diff --git a/cockroach/build.sh b/cockroach/build.sh index e77ed0e..f755042 100755 --- a/cockroach/build.sh +++ b/cockroach/build.sh @@ -23,15 +23,22 @@ WORKAROUND="$ROOT/cache/workaround" rm -rf "$WORKAROUND" mkdir -p "$WORKAROUND" -VER='21.2.9' -URL="https://binaries.cockroachdb.com/cockroach-v$VER.src.tgz" +VER='22.1.5' +COCKROACHDB_CLONE_REF="v$VER" + +NODEVER="v16.3.0" +SYSNODEVER=$( node -v 2>&1 ) +if [[ "$NODEVER" != "$SYSNODEVER" ]]; then + fatal "expected node $NODEVER, but found: $SYSNODEVER " \ + "(see node-16 package)" +fi -GOVER='1.16.10' -SYSGOVER=$( (pkg info go-116 || true) | awk '/Version:/ { print $NF }') +GOVER='1.17.13' +SYSGOVER=$( (pkg info go-117 || true) | awk '/Version:/ { print $NF }') if [[ "$SYSGOVER" != "$GOVER" ]]; then - fatal 'install or update go-116 package' + fatal 'install or update go-117 package' fi -export GOROOT='/opt/ooce/go-1.16' +export GOROOT='/opt/ooce/go-1.17' info "using $GOROOT/bin/go: $($GOROOT/bin/go version)" YARNVER='1.22.5' @@ -54,8 +61,21 @@ header 'downloading artefacts' yarnfile="$ARTEFACT/yarn-v$YARNVER.tar.gz" download_to yarn "$YARNURL" "$yarnfile" -file="$ARTEFACT/cockroach-v$VER.src.tgz" -download_to cockroach "$URL" "$file" +stamp="$ROOT/cache/cloned.stamp" +if [[ ! -f "$stamp" ]]; then + repo=https://github.com/cockroachdb/cockroach + info "cloning $repo branch $COCKROACHDB_CLONE_REF ..." + mkdir -p "$ROOT/cache/gopath/src/github.com/cockroachdb" + git clone \ + --recurse-submodules \ + --branch $COCKROACHDB_CLONE_REF \ + --depth 1 \ + $repo \ + cache/gopath/src/github.com/cockroachdb/cockroach + touch "$stamp" +else + info 'already cloned' +fi # # Extract artefacts: @@ -64,15 +84,6 @@ header 'extracting artefacts' extract_to yarn "$yarnfile" "$YARNROOT" --strip-components=1 -# -# The Cockroach DB source archive contains a wrapper Makefile at the top level -# which merely redirects one into the source that is set up, and sets GOPATH -# and BUILDCHANNEL='source-archive'. We'll just extract it into our expected -# GOPATH and ignore the rest. -# -#rm -rf "$GOPATH" # XXX -extract_to cockroach "$file" "$GOPATH" --strip-components=1 - # # Create workaround wrappers: # @@ -149,44 +160,14 @@ exit 1 EOF chmod 0755 "$WORKAROUND/ps" -# -# The build will try to detect information about the git repository, but finds -# garbage-compactor.git, because the source archive we use to build Cockroach -# is not, itself, a git repository. -# -cat >"$WORKAROUND/git" <<'EOF' -#!/usr/bin/bash -exit 1 -EOF -chmod 0755 "$WORKAROUND/git" - # # Build Cockroach: # header 'patching cockroach source' -function vendor_replace { - local targ="$GOPATH/src/github.com/cockroachdb/cockroach/vendor/$1" - info "vendor replace $1" - rm -rf "$targ/" - cp -r "$ROOT/patches/$1/" "$targ/" -} - stamp="$ROOT/cache/patched.stamp" if [[ ! -f "$stamp" ]]; then apply_patches "$ROOT/patches" "$GOPATH" - - info 'copying in extra files...' - cp $ROOT/patches/sysutil_illumos.go \ - "$GOPATH/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/" - cp $ROOT/patches/stderr_redirect_illumos.go \ - "$GOPATH/src/github.com/cockroachdb/cockroach/pkg/util/log/" - - vendor_replace "github.com/elastic/gosigar" - vendor_replace "github.com/knz/go-libedit" - vendor_replace "github.com/knz/strtime" - vendor_replace "github.com/cockroachdb/pebble/vfs" - touch "$stamp" else info 'already patched' diff --git a/cockroach/patches/03-sysutils.patch b/cockroach/patches/03-sysutils.patch deleted file mode 100644 index df7e628..0000000 --- a/cockroach/patches/03-sysutils.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -ur cockroach-v20.1.5-pristine/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix.go cockroach-v20.1.5/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix.go ---- cockroach-v20.1.5-pristine/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix.go Mon Aug 24 12:36:10 2020 -+++ cockroach-v20.1.5/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix.go Thu Sep 3 18:23:42 2020 -@@ -8,7 +8,7 @@ - // by the Apache License, Version 2.0, included in the file - // licenses/APL.txt. - --// +build !windows -+// +build !windows,!illumos - - //lint:file-ignore Unconvert (redundant conversions are necessary for cross-platform compatibility) - -diff -ur cockroach-v20.1.5-pristine/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix_test.go cockroach-v20.1.5/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix_test.go ---- cockroach-v20.1.5-pristine/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix_test.go Mon Aug 24 12:36:10 2020 -+++ cockroach-v20.1.5/src/github.com/cockroachdb/cockroach/pkg/util/sysutil/sysutil_unix_test.go Thu Sep 3 18:23:36 2020 -@@ -8,7 +8,7 @@ - // by the Apache License, Version 2.0, included in the file - // licenses/APL.txt. - --// +build !windows -+// +build !windows,!illumos - - package sysutil - diff --git a/cockroach/patches/04-stderr.patch b/cockroach/patches/04-stderr.patch deleted file mode 100644 index d10fb62..0000000 --- a/cockroach/patches/04-stderr.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/src/github.com/cockroachdb/cockroach/pkg/util/log/stderr_redirect_unix.go b/src/github.com/cockroachdb/cockroach/pkg/util/log/stderr_redirect_unix.go ---- a/src/github.com/cockroachdb/cockroach/pkg/util/log/stderr_redirect_unix.go -+++ b/src/github.com/cockroachdb/cockroach/pkg/util/log/stderr_redirect_unix.go -@@ -8,7 +8,7 @@ - // by the Apache License, Version 2.0, included in the file - // licenses/APL.txt. - --// +build !windows -+// +build !windows,!illumos - - package log - diff --git a/cockroach/patches/10-libpq.patch b/cockroach/patches/10-libpq.patch deleted file mode 100644 index c3df143..0000000 --- a/cockroach/patches/10-libpq.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/src/github.com/cockroachdb/cockroach/vendor/github.com/lib/pq/user_other.go Tue Apr 12 09:55:20 2022 -+++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/lib/pq/user_other.go Wed Apr 27 20:13:31 2022 -@@ -1,6 +1,6 @@ - // Package pq is a pure Go Postgres driver for the database/sql package. - --// +build js android hurd illumos zos -+// +build js android hurd zos - - package pq - diff --git a/cockroach/patches/11-makefile-tags.patch b/cockroach/patches/11-makefile-tags.patch new file mode 100644 index 0000000..f738a2b --- /dev/null +++ b/cockroach/patches/11-makefile-tags.patch @@ -0,0 +1,11 @@ +--- a/src/github.com/cockroachdb/cockroach/Makefile ++++ b/src/github.com/cockroachdb/cockroach/Makefile +@@ -163,7 +163,7 @@ DESTDIR := + + DUPLFLAGS := -t 100 + GOFLAGS := +-TAGS := ++TAGS := stdmalloc + ARCHIVE := cockroach.src.tgz + STARTFLAGS := -s type=mem,size=1GiB --logtostderr + BUILDTARGET := ./pkg/cmd/cockroach diff --git a/cockroach/patches/12-pebble-vfs.patch b/cockroach/patches/12-pebble-vfs.patch new file mode 100644 index 0000000..c3bd32b --- /dev/null +++ b/cockroach/patches/12-pebble-vfs.patch @@ -0,0 +1,41 @@ +--- a/src/github.com/cockroachdb/cockroach/vendor/github.com/cockroachdb/pebble/vfs/errors_unix.go Fri Aug 19 10:55:44 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/cockroachdb/pebble/vfs/errors_unix.go Fri Aug 19 10:55:44 2022 +@@ -2,8 +2,8 @@ + // of this source code is governed by a BSD-style license that can be found in + // the LICENSE file. + +-//go:build darwin || dragonfly || freebsd || linux || openbsd +-// +build darwin dragonfly freebsd linux openbsd ++//go:build darwin || dragonfly || freebsd || linux || openbsd || illumos ++// +build darwin dragonfly freebsd linux openbsd illumos + + package vfs + +--- /dev/null Fri Aug 19 10:52:18 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/cockroachdb/pebble/vfs/disk_usage_illumos.go Wed Aug 17 15:09:39 2022 +@@ -0,0 +1,25 @@ ++// Copyright 2020 The LevelDB-Go and Pebble 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 illumos ++ ++package vfs ++ ++import "golang.org/x/sys/unix" ++ ++func (defaultFS) GetDiskUsage(path string) (DiskUsage, error) { ++ stat := unix.Statvfs_t{} ++ if err := unix.Statvfs(path, &stat); err != nil { ++ return DiskUsage{}, err ++ } ++ ++ freeBytes := uint64(stat.Bsize) * uint64(stat.Bfree) ++ availBytes := uint64(stat.Bsize) * uint64(stat.Bavail) ++ totalBytes := uint64(stat.Bsize) * uint64(stat.Blocks) ++ return DiskUsage{ ++ AvailBytes: availBytes, ++ TotalBytes: totalBytes, ++ UsedBytes: totalBytes - freeBytes, ++ }, nil ++} diff --git a/cockroach/patches/13-strtime.patch b/cockroach/patches/13-strtime.patch new file mode 100644 index 0000000..a63ea63 --- /dev/null +++ b/cockroach/patches/13-strtime.patch @@ -0,0 +1,13 @@ +diff -ur cache/gopath/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/strtime/strptime.c patches/github.com/knz/strtime//strptime.c +--- a/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/strtime/strptime.c Fri Aug 19 09:57:34 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/strtime/strptime.c Fri Aug 19 09:57:34 2022 +@@ -59,6 +59,9 @@ + // #include "libc_private.h" + #include "timelocal.h" + // #include "tzfile.h" ++#ifdef __sun ++#include ++#endif + + static char * _strptime(const char *, const char *, struct mytm *, int *, locale_t); + diff --git a/cockroach/patches/14-go-libedit.patch b/cockroach/patches/14-go-libedit.patch new file mode 100644 index 0000000..0764f01 --- /dev/null +++ b/cockroach/patches/14-go-libedit.patch @@ -0,0 +1,36 @@ +--- a/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/go-libedit/editline_other.go Fri Aug 19 11:16:49 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/go-libedit/editline_other.go Fri Aug 19 11:16:49 2022 +@@ -12,7 +12,7 @@ + // implied. See the License for the specific language governing + // permissions and limitations under the License. + +-// +build !darwin,!freebsd,!linux,!openbsd,!netbsd,!dragonfly ++// +build !darwin,!freebsd,!illumos,!linux,!openbsd,!netbsd,!dragonfly + + package libedit + +--- a/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/go-libedit/editline_unix.go Fri Aug 19 11:16:49 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/go-libedit/editline_unix.go Fri Aug 19 11:16:49 2022 +@@ -12,7 +12,7 @@ + // implied. See the License for the specific language governing + // permissions and limitations under the License. + +-// +build darwin freebsd linux openbsd netbsd dragonfly ++// +build darwin freebsd illumos linux openbsd netbsd dragonfly + + package libedit + +--- a/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/go-libedit/unix/editline_unix.go Fri Aug 19 11:16:49 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/knz/go-libedit/unix/editline_unix.go Fri Aug 19 11:16:49 2022 +@@ -25,8 +25,8 @@ + common "github.com/knz/go-libedit/common" + ) + +-// #cgo openbsd netbsd freebsd dragonfly darwin LDFLAGS: -ledit +-// #cgo openbsd netbsd freebsd dragonfly darwin CPPFLAGS: -Ishim ++// #cgo openbsd netbsd illumos freebsd dragonfly darwin LDFLAGS: -ledit ++// #cgo openbsd netbsd illumos freebsd dragonfly darwin CPPFLAGS: -Ishim + // #cgo linux LDFLAGS: -lncurses + // #cgo linux CFLAGS: -Wno-unused-result -Wno-pointer-sign + // #cgo linux CPPFLAGS: -Isrc -Isrc/c-libedit -Isrc/c-libedit/editline -Isrc/c-libedit/linux-build -D_GNU_SOURCE + diff --git a/cockroach/patches/15-gosigar.patch b/cockroach/patches/15-gosigar.patch new file mode 100644 index 0000000..21ef2b8 --- /dev/null +++ b/cockroach/patches/15-gosigar.patch @@ -0,0 +1,165 @@ +--- a/src/github.com/cockroachdb/cockroach/vendor/github.com/elastic/gosigar/sigar_stub.go Fri Aug 19 11:34:48 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/elastic/gosigar/sigar_stub.go Fri Aug 19 11:34:48 2022 +@@ -1,4 +1,4 @@ +-// +build !aix,!darwin,!freebsd,!linux,!openbsd,!windows ++// +build !aix,!darwin,!freebsd,!linux,!openbsd,!windows,!illumos + + package gosigar + +--- /dev/null Fri Aug 19 11:34:48 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/elastic/gosigar/sigar_illumos.go Fri Aug 19 11:34:48 2022 +@@ -0,0 +1,118 @@ ++// Copyright 2020 Oxide Computer Company ++ ++package gosigar ++ ++import ( ++ "runtime" ++ "strings" ++ ++ "golang.org/x/sys/unix" ++) ++ ++func (c *Cpu) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (l *LoadAverage) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (m *Mem) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (s *Swap) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (s *HugeTLBPages) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (f *FDUsage) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcTime) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (self *CpuList) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcState) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcExe) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcMem) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcFDUsage) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcEnv) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcList) Get() error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (p *ProcArgs) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (self *Rusage) Get(int) error { ++ return ErrNotImplemented{runtime.GOOS} ++} ++ ++func (self *FileSystemList) Get() error { ++ capacity := len(self.List) ++ if capacity == 0 { ++ capacity = 10 ++ } ++ ++ fslist := make([]FileSystem, 0, capacity) ++ ++ err := readFile("/etc/mnttab", func(line string) bool { ++ fields := strings.Fields(line) ++ ++ fs := FileSystem{} ++ fs.DevName = fields[0] ++ fs.DirName = fields[1] ++ fs.SysTypeName = fields[2] ++ fs.Options = fields[3] ++ ++ fslist = append(fslist, fs) ++ ++ return true ++ }) ++ ++ if err == nil { ++ self.List = fslist ++ } ++ return err ++} ++ ++func (self *FileSystemUsage) Get(path string) error { ++ var fs unix.Statvfs_t ++ if err := unix.Statvfs(path, &fs); err != nil { ++ return err ++ } ++ ++ self.Total = uint64(fs.Blocks) * uint64(fs.Frsize) ++ self.Free = uint64(fs.Bfree) * uint64(fs.Frsize) ++ self.Avail = uint64(fs.Bavail) * uint64(fs.Frsize) ++ self.Used = self.Total - self.Free ++ self.Files = fs.Files ++ self.FreeFiles = fs.Ffree ++ ++ return nil ++} +--- /dev/null Fri Aug 19 12:22:03 2022 ++++ b/src/github.com/cockroachdb/cockroach/vendor/github.com/elastic/gosigar/sigar_unix_common.go Fri Aug 19 11:34:48 2022 +@@ -0,0 +1,33 @@ ++// Copyright (c) 2012 VMware, Inc. ++ ++// +build illumos ++ ++package gosigar ++ ++import ( ++ "bufio" ++ "bytes" ++ "io" ++ "io/ioutil" ++) ++ ++func readFile(file string, handler func(string) bool) error { ++ contents, err := ioutil.ReadFile(file) ++ if err != nil { ++ return err ++ } ++ ++ reader := bufio.NewReader(bytes.NewBuffer(contents)) ++ ++ for { ++ line, _, err := reader.ReadLine() ++ if err == io.EOF { ++ break ++ } ++ if !handler(string(line)) { ++ break ++ } ++ } ++ ++ return nil ++} diff --git a/cockroach/patches/16-issue-86403.patch b/cockroach/patches/16-issue-86403.patch new file mode 100644 index 0000000..8b94324 --- /dev/null +++ b/cockroach/patches/16-issue-86403.patch @@ -0,0 +1,11 @@ +--- a/src/github.com/cockroachdb/cockroach/pkg/ui/workspaces/db-console/webpack.vendor.js ++++ b/src/github.com/cockroachdb/cockroach/pkg/ui/workspaces/db-console/webpack.vendor.js +@@ -15,7 +15,7 @@ const webpack = require("webpack"); + + const pkg = require("./package.json"); + +-const prodDependencies = Object.keys(pkg.dependencies); ++const prodDependencies = Object.keys(pkg.dependencies).filter(name => !name.startsWith("@cockroachlabs")); + + // tslint:disable:object-literal-sort-keys + module.exports = (env, argv) => { diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/atomicfs/marker.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/atomicfs/marker.go deleted file mode 100644 index 6ac5e4e..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/atomicfs/marker.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2021 The LevelDB-Go and Pebble 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 atomicfs - -import ( - "fmt" - "strconv" - "strings" - - "github.com/cockroachdb/errors" - "github.com/cockroachdb/errors/oserror" - "github.com/cockroachdb/pebble/vfs" -) - -// ReadMarker looks up the current state of a marker returning just the -// current value of the marker. Callers that may need to move the marker -// should use LocateMarker. -func ReadMarker(fs vfs.FS, dir, markerName string) (string, error) { - state, err := scanForMarker(fs, dir, markerName) - if err != nil { - return "", err - } - return state.value, nil -} - -// LocateMarker loads the current state of a marker. It returns a handle -// to the Marker that may be used to move the marker and the -// current value of the marker. -func LocateMarker(fs vfs.FS, dir, markerName string) (*Marker, string, error) { - state, err := scanForMarker(fs, dir, markerName) - if err != nil { - return nil, "", err - } - dirFD, err := fs.OpenDir(dir) - if err != nil { - return nil, "", err - } - return &Marker{ - fs: fs, - dir: dir, - dirFD: dirFD, - name: markerName, - filename: state.filename, - iter: state.iter, - obsoleteFiles: state.obsolete, - }, state.value, nil -} - -type scannedState struct { - filename string - iter uint64 - value string - obsolete []string -} - -func scanForMarker(fs vfs.FS, dir, markerName string) (scannedState, error) { - ls, err := fs.List(dir) - if err != nil { - return scannedState{}, err - } - var state scannedState - for _, filename := range ls { - if !strings.HasPrefix(filename, `marker.`) { - continue - } - // Any filenames with the `marker.` prefix are required to be - // well-formed and parse as markers. - name, iter, value, err := parseMarkerFilename(filename) - if err != nil { - return scannedState{}, err - } - if name != markerName { - continue - } - - if state.filename == "" || state.iter < iter { - if state.filename != "" { - state.obsolete = append(state.obsolete, state.filename) - } - state.filename = filename - state.iter = iter - state.value = value - } else { - state.obsolete = append(state.obsolete, filename) - } - } - return state, nil -} - -// A Marker provides an interface for marking a single file on the -// filesystem. The marker may be atomically moved from name to name. -// Marker is not safe for concurrent use. Multiple processes may not -// read or move the same marker simulatenously. An Marker may only be -// constructed through LocateMarker. -// -// Marker names must be unique within the directory. -type Marker struct { - fs vfs.FS - dir string - dirFD vfs.File - // name identifies the marker. - name string - // filename contains the entire filename of the current marker. It - // has a format of `marker...`. It's not - // necessarily in sync with iter, since filename is only updated - // when the marker is successfully moved. - filename string - // iter holds the current iteration value. It matches the iteration - // value encoded within filename, if filename is non-empty. Iter is - // monotonically increasing over the lifetime of a marker. Actual - // marker files will always have a positive iter value. - iter uint64 - // obsoleteFiles holds a list of files discovered by LocateMarker - // that are old values for this marker. These files may exist if the - // filesystem doesn't guarantee atomic renames (eg, if it's - // implemented as a link(newpath), remove(oldpath), and a crash in - // between may leave an entry at the old path). - obsoleteFiles []string -} - -func markerFilename(name string, iter uint64, value string) string { - return fmt.Sprintf("marker.%s.%06d.%s", name, iter, value) -} - -func parseMarkerFilename(s string) (name string, iter uint64, value string, err error) { - // Check for and remove the `marker.` prefix. - if !strings.HasPrefix(s, `marker.`) { - return "", 0, "", errors.Newf("invalid marker filename: %q", s) - } - s = s[len(`marker.`):] - - // Extract the marker's name. - i := strings.IndexByte(s, '.') - if i == -1 { - return "", 0, "", errors.Newf("invalid marker filename: %q", s) - } - name = s[:i] - s = s[i+1:] - - // Extract the marker's iteration number. - i = strings.IndexByte(s, '.') - if i == -1 { - return "", 0, "", errors.Newf("invalid marker filename: %q", s) - } - iter, err = strconv.ParseUint(s[:i], 10, 64) - if err != nil { - return "", 0, "", errors.Newf("invalid marker filename: %q", s) - } - - // Everything after the iteration's `.` delimiter is the value. - s = s[i+1:] - - return name, iter, s, nil -} - -// Close releases all resources in use by the marker. -func (a *Marker) Close() error { - return a.dirFD.Close() -} - -// Move atomically moves the marker to mark the provided filename. -// If Move returns a nil error, the new marker value is guaranteed to be -// persisted to stable storage. If Move returns an error, the current -// value of the marker may be the old value or the new value. Callers -// may retry a Move error. -// -// If an error occurs while syncing the directory, Move panics. -// -// The provided filename does not need to exist on the filesystem. -func (a *Marker) Move(filename string) error { - a.iter++ - dstFilename := markerFilename(a.name, a.iter, filename) - dstPath := a.fs.PathJoin(a.dir, dstFilename) - oldFilename := a.filename - - // The marker has never been placed. Create a new file. - f, err := a.fs.Create(dstPath) - if err != nil { - // On a distributed filesystem, an error doesn't guarantee that - // the file wasn't created. A retry of the same Move call will - // use a new iteration value, and try to a create a new file. If - // the errored invocation was actually successful in creating - // the file, we'll leak a file. That's okay, because the next - // time the marker is located we'll add it to the obsolete files - // list. - // - // Note that the unconditional increment of `a.iter` means that - // `a.iter` and `a.filename` are not necessarily in sync, - // because `a.filename` is only updated on success. - return err - } - a.filename = dstFilename - if err := f.Close(); err != nil { - return err - } - - // Remove the now defunct file. If an error is surfaced, we record - // the file as an obsolete file. The file's presence does not - // affect correctness, and it will be cleaned up the next time - // RemoveObsolete is called, either by this process or the next. - if oldFilename != "" { - if err := a.fs.Remove(a.fs.PathJoin(a.dir, oldFilename)); err != nil && !oserror.IsNotExist(err) { - a.obsoleteFiles = append(a.obsoleteFiles, oldFilename) - } - } - - // Sync the directory to ensure marker movement is synced. - if err := a.dirFD.Sync(); err != nil { - // Fsync errors are unrecoverable. - // See https://wiki.postgresql.org/wiki/Fsync_Errors and - // https://danluu.com/fsyncgate. - panic(errors.WithStack(err)) - } - return nil -} - -// NextIter returns the next iteration number that the marker will use. -// Clients may use this number for formulating filenames that are -// unused. -func (a *Marker) NextIter() uint64 { - return a.iter + 1 -} - -// RemoveObsolete removes any obsolete files discovered while locating -// the marker or files unable to be removed during Move. -func (a *Marker) RemoveObsolete() error { - obsolete := a.obsoleteFiles - for _, filename := range obsolete { - if err := a.fs.Remove(a.fs.PathJoin(a.dir, filename)); err != nil && !oserror.IsNotExist(err) { - return err - } - a.obsoleteFiles = obsolete[1:] - } - a.obsoleteFiles = nil - return nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/clone.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/clone.go deleted file mode 100644 index 8604b71..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/clone.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019 The LevelDB-Go and Pebble 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 vfs - -import ( - "io/ioutil" - "sort" - - "github.com/cockroachdb/errors/oserror" -) - -// Clone recursively copies a directory structure from srcFS to dstFS. srcPath -// specifies the path in srcFS to copy from and must be compatible with the -// srcFS path format. dstDir is the target directory in dstFS and must be -// compatible with the dstFS path format. Returns (true,nil) on a successful -// copy, (false,nil) if srcPath does not exist, and (false,err) if an error -// occurred. -func Clone(srcFS, dstFS FS, srcPath, dstPath string) (bool, error) { - srcFile, err := srcFS.Open(srcPath) - if err != nil { - if oserror.IsNotExist(err) { - // Ignore non-existent errors. Those will translate into non-existent - // files in the destination filesystem. - return false, nil - } - return false, err - } - - stat, err := srcFile.Stat() - if err != nil { - return false, err - } - - if stat.IsDir() { - if err := srcFile.Close(); err != nil { - return false, err - } - if err := dstFS.MkdirAll(dstPath, 0755); err != nil { - return false, err - } - list, err := srcFS.List(srcPath) - if err != nil { - return false, err - } - // Sort the paths so we get deterministic test output. - sort.Strings(list) - for _, name := range list { - _, err := Clone(srcFS, dstFS, srcFS.PathJoin(srcPath, name), dstFS.PathJoin(dstPath, name)) - if err != nil { - return false, err - } - } - return true, nil - } - - data, err := ioutil.ReadAll(srcFile) - if err != nil { - return false, err - } - if err := srcFile.Close(); err != nil { - return false, err - } - dstFile, err := dstFS.Create(dstPath) - if err != nil { - return false, err - } - if _, err = dstFile.Write(data); err != nil { - return false, err - } - if err := dstFile.Close(); err != nil { - return false, err - } - return true, nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/dir_unix.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/dir_unix.go deleted file mode 100644 index 8f7be0f..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/dir_unix.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2014 The LevelDB-Go and Pebble 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 dragonfly freebsd linux netbsd openbsd solaris - -package vfs - -import ( - "os" - "syscall" - - "github.com/cockroachdb/errors" -) - -func (defaultFS) OpenDir(name string) (File, error) { - f, err := os.OpenFile(name, syscall.O_CLOEXEC, 0) - return f, errors.WithStack(err) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/dir_windows.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/dir_windows.go deleted file mode 100644 index dc5f447..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/dir_windows.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 The LevelDB-Go and Pebble 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 windows - -package vfs - -import ( - "os" - "syscall" - - "github.com/cockroachdb/errors" -) - -type windowsDir struct { - File -} - -func (windowsDir) Sync() error { - // Silently ignore Sync() on Windows. This is the same behavior as - // RocksDB. See port/win/io_win.cc:WinDirectory::Fsync(). - return nil -} - -func (defaultFS) OpenDir(name string) (File, error) { - f, err := os.OpenFile(name, syscall.O_CLOEXEC, 0) - if err != nil { - return nil, errors.WithStack(err) - } - return windowsDir{f}, nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_full.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_full.go deleted file mode 100644 index c7d12ea..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_full.go +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright 2021 The LevelDB-Go and Pebble 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 vfs - -import ( - "io" - "os" - "sync" - "sync/atomic" - "syscall" - - "github.com/cockroachdb/errors" -) - -// OnDiskFull wraps the provided FS with an FS that examines returned errors, -// looking for ENOSPC errors. It invokes the provided callback when the -// underlying filesystem returns an error signifying the storage is out of -// disk space. -// -// All new writes to the filesystem are blocked while the callback executes, -// so care must be taken to avoid expensive work from within the callback. -// -// Once the callback completes, any write-oriented operations that encountered -// ENOSPC are retried exactly once. Once the callback completes, it will not -// be invoked again until a new operation that began after the callback -// returned encounters an ENOSPC error. -// -// OnDiskFull may be used to automatically manage a ballast file, which is -// removed from the filesystem from within the callback. Note that if managing -// a ballast, the caller should maintain a reference to the inner FS and -// remove the ballast on the unwrapped FS. -func OnDiskFull(fs FS, fn func()) FS { - newFS := &enospcFS{inner: fs} - newFS.mu.Cond.L = &newFS.mu.Mutex - newFS.mu.onDiskFull = fn - return newFS -} - -type enospcFS struct { - inner FS - atomic struct { - // generation is a monotonically increasing number that encodes the - // current state of ENOSPC error handling. Incoming writes are - // organized into generations to provide strong guarantees on when the - // disk full callback is invoked. The callback is invoked once per - // write generation. - // - // Special significance is given to the parity of this generation - // field to optimize incoming writes in the normal state, which only - // need to perform a single atomic load. If generation is odd, an - // ENOSPC error is being actively handled. The generations associated - // with writes are always even. - // - // The lifecycle of a write is: - // - // 1. Atomically load the current generation. - // a. If it's even, this is the write's generation number. - // b. If it's odd, an ENOSPC was recently encountered and the - // corresponding invocation of the disk full callback has not - // yet completed. The write must wait until the callback has - // completed and generation is updated to an even number, which - // becomes the write's generation number. - // 2. Perform the write. If it encounters no error or an error other - // than ENOSPC, the write returns and proceeds no further in this - // lifecycle. - // 3. Handle ENOSPC. If the write encounters ENOSPC, the callback must - // be invoked for the write's generation. The write's goroutine - // acquires the FS's mutex. - // a. If the FS's current generation is still equal to the write's - // generation, the write is the first write of its generation to - // encounter ENOSPC. It increments the FS's current generation - // to an odd number, signifying that an ENOSPC is being handled - // and invokes the callback. - // b. If the FS's current generation has changed, some other write - // from the same generation encountered an ENOSPC first. This - // write waits on the condition variable until the FS's current - // generation is updated indicating that the generation's - // callback invocation has completed. - // 3. Retry the write once. The callback for the write's generation - // has completed, either by this write's goroutine or another's. - // The write may proceed with the expectation that the callback - // remedied the full disk by freeing up disk space and an ENOSPC - // should not be encountered again for at least a few minutes. If - // we do encounter another ENOSPC on the retry, the callback was - // unable to remedy the full disk and another retry won't be - // useful. Any error, including ENOSPC, during the retry is - // returned without further handling. None of the retries invoke - // the callback. - // - // This scheme has a few nice properties: - // * Once the disk-full callback completes, it won't be invoked - // again unless a write that started strictly later encounters an - // ENOSPC. This is convenient if the callback strives to 'fix' the - // full disk, for example, by removing a ballast file. A new - // invocation of the callback guarantees a new problem. - // * Incoming writes block if there's an unhandled ENOSPC. Some - // writes, like WAL or MANIFEST fsyncs, are fatal if they encounter - // an ENOSPC. - generation uint32 - } - mu struct { - sync.Mutex - sync.Cond - onDiskFull func() - } -} - -// Unwrap returns the underlying FS. This may be called by vfs.Root to access -// the underlying filesystem. -func (fs *enospcFS) Unwrap() FS { - return fs.inner -} - -// waitUntilReady is called before every FS or File operation that -// might return ENOSPC. If an ENOSPC was encountered and the corresponding -// invocation of the `onDiskFull` callback has not yet returned, -// waitUntilReady blocks until the callback returns. The returned generation -// is always even. -func (fs *enospcFS) waitUntilReady() uint32 { - gen := atomic.LoadUint32(&fs.atomic.generation) - if gen%2 == 0 { - // An even generation indicates that we're not currently handling an - // ENOSPC. Allow the write to proceed. - return gen - } - - // We're currently handling an ENOSPC error. Wait on the condition - // variable until we're not handling an ENOSPC. - fs.mu.Lock() - defer fs.mu.Unlock() - - // Load the generation again with fs.mu locked. - gen = atomic.LoadUint32(&fs.atomic.generation) - for gen%2 == 1 { - fs.mu.Wait() - gen = atomic.LoadUint32(&fs.atomic.generation) - } - return gen -} - -func (fs *enospcFS) handleENOSPC(gen uint32) { - fs.mu.Lock() - defer fs.mu.Unlock() - - currentGeneration := atomic.LoadUint32(&fs.atomic.generation) - - // If the current generation is still `gen`, this is the first goroutine - // to hit an ENOSPC within this write generation, so this goroutine is - // responsible for invoking the callback. - if currentGeneration == gen { - // Increment the generation to an odd number, indicating that the FS - // is out-of-disk space and incoming writes should pause and wait for - // the next generation before continuing. - atomic.StoreUint32(&fs.atomic.generation, gen+1) - - func() { - // Drop the mutex while we invoke the callback, re-acquiring - // afterwards. - fs.mu.Unlock() - defer fs.mu.Lock() - fs.mu.onDiskFull() - }() - - // Update the current generation again to an even number, indicating - // that the callback has completed for the write generation `gen`. - atomic.StoreUint32(&fs.atomic.generation, gen+2) - fs.mu.Broadcast() - return - } - - // The current generation has already been incremented, so either the - // callback is currently being run by another goroutine or it's already - // completed. Wait for it complete if it hasn't already. - // - // The current generation may be updated multiple times, including to an - // odd number signifying a later write generation has already encountered - // ENOSPC. In that case, the callback was not able to remedy the full disk - // and waiting is unlikely to be helpful. Continuing to wait risks - // blocking an unbounded number of generations. Retrying and bubbling the - // ENOSPC up might be helpful if we can abort a large compaction that - // started before we became more selective about compaction picking, so - // this loop only waits for this write generation's callback and no - // subsequent generations' callbacks. - for currentGeneration == gen+1 { - fs.mu.Wait() - currentGeneration = atomic.LoadUint32(&fs.atomic.generation) - } -} - -func (fs *enospcFS) Create(name string) (File, error) { - gen := fs.waitUntilReady() - - f, err := fs.inner.Create(name) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - f, err = fs.inner.Create(name) - } - if f != nil { - f = WithFd(f, enospcFile{ - fs: fs, - inner: f, - }) - } - return f, err -} - -func (fs *enospcFS) Link(oldname, newname string) error { - gen := fs.waitUntilReady() - - err := fs.inner.Link(oldname, newname) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - err = fs.inner.Link(oldname, newname) - } - return err -} - -func (fs *enospcFS) Open(name string, opts ...OpenOption) (File, error) { - f, err := fs.inner.Open(name, opts...) - if f != nil { - f = WithFd(f, enospcFile{ - fs: fs, - inner: f, - }) - } - return f, err -} - -func (fs *enospcFS) OpenDir(name string) (File, error) { - f, err := fs.inner.OpenDir(name) - if f != nil { - f = WithFd(f, enospcFile{ - fs: fs, - inner: f, - }) - } - return f, err -} - -func (fs *enospcFS) Remove(name string) error { - gen := fs.waitUntilReady() - - err := fs.inner.Remove(name) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - err = fs.inner.Remove(name) - } - return err -} - -func (fs *enospcFS) RemoveAll(name string) error { - gen := fs.waitUntilReady() - - err := fs.inner.RemoveAll(name) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - err = fs.inner.RemoveAll(name) - } - return err -} - -func (fs *enospcFS) Rename(oldname, newname string) error { - gen := fs.waitUntilReady() - - err := fs.inner.Rename(oldname, newname) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - err = fs.inner.Rename(oldname, newname) - } - return err -} - -func (fs *enospcFS) ReuseForWrite(oldname, newname string) (File, error) { - gen := fs.waitUntilReady() - - f, err := fs.inner.ReuseForWrite(oldname, newname) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - f, err = fs.inner.ReuseForWrite(oldname, newname) - } - - if f != nil { - f = WithFd(f, enospcFile{ - fs: fs, - inner: f, - }) - } - return f, err -} - -func (fs *enospcFS) MkdirAll(dir string, perm os.FileMode) error { - gen := fs.waitUntilReady() - - err := fs.inner.MkdirAll(dir, perm) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - err = fs.inner.MkdirAll(dir, perm) - } - return err -} - -func (fs *enospcFS) Lock(name string) (io.Closer, error) { - gen := fs.waitUntilReady() - - closer, err := fs.inner.Lock(name) - - if err != nil && isENOSPC(err) { - fs.handleENOSPC(gen) - closer, err = fs.inner.Lock(name) - } - return closer, err -} - -func (fs *enospcFS) List(dir string) ([]string, error) { - return fs.inner.List(dir) -} - -func (fs *enospcFS) Stat(name string) (os.FileInfo, error) { - return fs.inner.Stat(name) -} - -func (fs *enospcFS) PathBase(path string) string { - return fs.inner.PathBase(path) -} - -func (fs *enospcFS) PathJoin(elem ...string) string { - return fs.inner.PathJoin(elem...) -} - -func (fs *enospcFS) PathDir(path string) string { - return fs.inner.PathDir(path) -} - -func (fs *enospcFS) GetDiskUsage(path string) (DiskUsage, error) { - return fs.inner.GetDiskUsage(path) -} - -type enospcFile struct { - fs *enospcFS - inner File -} - -func (f enospcFile) Close() error { - return f.inner.Close() -} - -func (f enospcFile) Read(p []byte) (n int, err error) { - return f.inner.Read(p) -} - -func (f enospcFile) ReadAt(p []byte, off int64) (n int, err error) { - return f.inner.ReadAt(p, off) -} - -func (f enospcFile) Write(p []byte) (n int, err error) { - gen := f.fs.waitUntilReady() - - n, err = f.inner.Write(p) - - if err != nil && isENOSPC(err) { - f.fs.handleENOSPC(gen) - var n2 int - n2, err = f.inner.Write(p[n:]) - n += n2 - } - return n, err -} - -func (f enospcFile) Stat() (os.FileInfo, error) { - return f.inner.Stat() -} - -func (f enospcFile) Sync() error { - gen := f.fs.waitUntilReady() - - err := f.inner.Sync() - - if err != nil && isENOSPC(err) { - f.fs.handleENOSPC(gen) - - // NB: It is NOT safe to retry the Sync. See the PostgreSQL - // 'fsyncgate' discussion. A successful Sync after a failed one does - // not provide any guarantees and (always?) loses the unsynced writes. - // We need to bubble the error up and hope we weren't syncing a WAL or - // MANIFEST, because we'll have no choice but to crash. Errors while - // syncing an sstable will result in a failed flush/compaction, and - // the relevant sstable(s) will be marked as obsolete and deleted. - // See: https://lwn.net/Articles/752063/ - } - return err -} - -// Ensure that *enospcFS implements the FS interface. -var _ FS = (*enospcFS)(nil) - -func isENOSPC(err error) bool { - err = errors.UnwrapAll(err) - e, ok := err.(syscall.Errno) - return ok && e == syscall.ENOSPC -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_health.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_health.go deleted file mode 100644 index 19fdeb6..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_health.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 vfs - -import ( - "sync/atomic" - "time" -) - -const ( - // defaultTickInterval is the default interval between two ticks of each - // diskHealthCheckingFile loop iteration. - defaultTickInterval = 2 * time.Second -) - -// diskHealthCheckingFile is a File wrapper to detect slow disk operations, and -// call onSlowDisk if a disk operation is seen to exceed diskSlowThreshold. -// -// This struct creates a goroutine (in startTicker()) that, at every tick -// interval, sees if there's a disk operation taking longer than the specified -// duration. This setup is preferable to creating a new timer at every disk -// operation, as it reduces overhead per disk operation. -type diskHealthCheckingFile struct { - File - - onSlowDisk func(time.Duration) - diskSlowThreshold time.Duration - tickInterval time.Duration - - stopper chan struct{} - lastWriteNanos int64 -} - -// newDiskHealthCheckingFile instantiates a new diskHealthCheckingFile, with the -// specified time threshold and event listener. -func newDiskHealthCheckingFile( - file File, diskSlowThreshold time.Duration, onSlowDisk func(time.Duration), -) *diskHealthCheckingFile { - return &diskHealthCheckingFile{ - File: file, - onSlowDisk: onSlowDisk, - diskSlowThreshold: diskSlowThreshold, - tickInterval: defaultTickInterval, - - stopper: make(chan struct{}), - } -} - -// startTicker starts a new goroutine with a ticker to monitor disk operations. -// Can only be called if the ticker goroutine isn't running already. -func (d *diskHealthCheckingFile) startTicker() { - if d.diskSlowThreshold == 0 { - return - } - - go func() { - ticker := time.NewTicker(d.tickInterval) - defer ticker.Stop() - - for { - select { - case <-d.stopper: - return - - case <-ticker.C: - lastWriteNanos := atomic.LoadInt64(&d.lastWriteNanos) - if lastWriteNanos == 0 { - continue - } - lastWrite := time.Unix(0, lastWriteNanos) - now := time.Now() - if lastWrite.Add(d.diskSlowThreshold).Before(now) { - // diskSlowThreshold was exceeded. Call the passed-in - // listener. - d.onSlowDisk(now.Sub(lastWrite)) - } - } - } - }() -} - -// stopTicker stops the goroutine started in startTicker. -func (d *diskHealthCheckingFile) stopTicker() { - close(d.stopper) -} - -// Write implements the io.Writer interface. -func (d *diskHealthCheckingFile) Write(p []byte) (n int, err error) { - d.timeDiskOp(func() { - n, err = d.File.Write(p) - }) - return n, err -} - -// Close implements the io.Closer interface. -func (d *diskHealthCheckingFile) Close() error { - d.stopTicker() - return d.File.Close() -} - -// Sync implements the io.Syncer interface. -func (d *diskHealthCheckingFile) Sync() (err error) { - d.timeDiskOp(func() { - err = d.File.Sync() - }) - return err -} - -// timeDiskOp runs the specified closure and makes its timing visible to the -// monitoring goroutine, in case it exceeds one of the slow disk durations. -func (d *diskHealthCheckingFile) timeDiskOp(op func()) { - if d == nil { - op() - return - } - - atomic.StoreInt64(&d.lastWriteNanos, time.Now().UnixNano()) - defer func() { - atomic.StoreInt64(&d.lastWriteNanos, 0) - }() - op() -} - -type diskHealthCheckingFS struct { - FS - - diskSlowThreshold time.Duration - onSlowDisk func(string, time.Duration) -} - -// WithDiskHealthChecks wraps an FS and ensures that all -// write-oriented created with that FS are wrapped with disk health detection -// checks. Disk operations that are observed to take longer than -// diskSlowThreshold trigger an onSlowDisk call. -func WithDiskHealthChecks( - fs FS, diskSlowThreshold time.Duration, onSlowDisk func(string, time.Duration), -) FS { - return diskHealthCheckingFS{ - FS: fs, - diskSlowThreshold: diskSlowThreshold, - onSlowDisk: onSlowDisk, - } -} - -// Create implements the vfs.FS interface. -func (d diskHealthCheckingFS) Create(name string) (File, error) { - f, err := d.FS.Create(name) - if err != nil { - return f, err - } - if d.diskSlowThreshold == 0 { - return f, nil - } - checkingFile := newDiskHealthCheckingFile(f, d.diskSlowThreshold, func(duration time.Duration) { - d.onSlowDisk(name, duration) - }) - checkingFile.startTicker() - return WithFd(f, checkingFile), nil -} - -// ReuseForWrite implements the vfs.FS interface. -func (d diskHealthCheckingFS) ReuseForWrite(oldname, newname string) (File, error) { - f, err := d.FS.ReuseForWrite(oldname, newname) - if err != nil { - return f, err - } - if d.diskSlowThreshold == 0 { - return f, nil - } - checkingFile := newDiskHealthCheckingFile(f, d.diskSlowThreshold, func(duration time.Duration) { - d.onSlowDisk(newname, duration) - }) - checkingFile.startTicker() - return WithFd(f, checkingFile), nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_illumos.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_illumos.go deleted file mode 100644 index 29779d4..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_illumos.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 illumos - -package vfs - -import "golang.org/x/sys/unix" - -func (defaultFS) GetDiskUsage(path string) (DiskUsage, error) { - stat := unix.Statvfs_t{} - if err := unix.Statvfs(path, &stat); err != nil { - return DiskUsage{}, err - } - - freeBytes := uint64(stat.Bsize) * uint64(stat.Bfree) - availBytes := uint64(stat.Bsize) * uint64(stat.Bavail) - totalBytes := uint64(stat.Bsize) * uint64(stat.Blocks) - return DiskUsage{ - AvailBytes: availBytes, - TotalBytes: totalBytes, - UsedBytes: totalBytes - freeBytes, - }, nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_linux.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_linux.go deleted file mode 100644 index 9f28812..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_linux.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 - -package vfs - -import "golang.org/x/sys/unix" - -func (defaultFS) GetDiskUsage(path string) (DiskUsage, error) { - stat := unix.Statfs_t{} - if err := unix.Statfs(path, &stat); err != nil { - return DiskUsage{}, err - } - - // We use stat.Frsize here rather than stat.Bsize because on - // Linux Bavail and Bfree are in Frsize units. - // - // On most filesystems Frsize and Bsize will be set to the - // same value, but on some filesystems bsize returns the - // "optimal transfer block size"[1] which may be different - // (typically larger) than the actual block size. - // - // This confusion is cleared up in the statvfs[2] libc function, - // but the statfs system call used above varies across - // platforms. - // - // Frsize is used by GNU coreutils and other libraries, so - // this also helps ensure that we get the same results as one - // would get if they ran `df` on the given path. - // - // [1] https://man7.org/linux/man-pages/man2/statfs.2.html - // [2] https://man7.org/linux/man-pages/man3/statvfs.3.html - freeBytes := uint64(stat.Frsize) * uint64(stat.Bfree) - availBytes := uint64(stat.Frsize) * uint64(stat.Bavail) - totalBytes := uint64(stat.Bsize) * uint64(stat.Blocks) - return DiskUsage{ - AvailBytes: availBytes, - TotalBytes: totalBytes, - UsedBytes: totalBytes - freeBytes, - }, nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_unix.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_unix.go deleted file mode 100644 index 84c8555..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_unix.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 openbsd dragonfly freebsd - -package vfs - -import "golang.org/x/sys/unix" - -func (defaultFS) GetDiskUsage(path string) (DiskUsage, error) { - stat := unix.Statfs_t{} - if err := unix.Statfs(path, &stat); err != nil { - return DiskUsage{}, err - } - - freeBytes := uint64(stat.Bsize) * uint64(stat.Bfree) - availBytes := uint64(stat.Bsize) * uint64(stat.Bavail) - totalBytes := uint64(stat.Bsize) * uint64(stat.Blocks) - return DiskUsage{ - AvailBytes: availBytes, - TotalBytes: totalBytes, - UsedBytes: totalBytes - freeBytes, - }, nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_windows.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_windows.go deleted file mode 100644 index db3ee73..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/disk_usage_windows.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 windows - -package vfs - -import "golang.org/x/sys/windows" - -func (defaultFS) GetDiskUsage(path string) (DiskUsage, error) { - p, err := windows.UTF16PtrFromString(path) - if err != nil { - return DiskUsage{}, err - } - var freeBytes uint64 - du := DiskUsage{} - err = windows.GetDiskFreeSpaceEx(p, &du.AvailBytes, &du.TotalBytes, &freeBytes) - du.UsedBytes = du.TotalBytes - freeBytes - return du, err -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_illumos.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_illumos.go deleted file mode 100644 index 72e68ab..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_illumos.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 illumos - -package vfs - -import ( - "syscall" - - "github.com/cockroachdb/errors" - "golang.org/x/sys/unix" -) - -var errNotEmpty = syscall.EEXIST - -// IsNoSpaceError returns true if the given error indicates that the disk is -// out of space. -func IsNoSpaceError(err error) bool { - return errors.Is(err, unix.ENOSPC) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_unix.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_unix.go deleted file mode 100644 index 31b4dc7..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_unix.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 dragonfly freebsd linux openbsd - -package vfs - -import ( - "syscall" - - "github.com/cockroachdb/errors" - "golang.org/x/sys/unix" -) - -var errNotEmpty = syscall.ENOTEMPTY - -// IsNoSpaceError returns true if the given error indicates that the disk is -// out of space. -func IsNoSpaceError(err error) bool { - return errors.Is(err, unix.ENOSPC) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_windows.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_windows.go deleted file mode 100644 index 06ce204..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/errors_windows.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 windows - -package vfs - -import ( - "github.com/cockroachdb/errors" - "golang.org/x/sys/windows" -) - -var errNotEmpty = windows.ERROR_DIR_NOT_EMPTY - -// IsNoSpaceError returns true if the given error indicates that the disk is -// out of space. -func IsNoSpaceError(err error) bool { - return errors.Is(err, windows.ERROR_DISK_FULL) || - errors.Is(err, windows.ERROR_HANDLE_DISK_FULL) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/fadvise_generic.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/fadvise_generic.go deleted file mode 100644 index 22b3de8..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/fadvise_generic.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2019 The LevelDB-Go and Pebble 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 - -package vfs - -func fadviseRandom(f uintptr) error { - return nil -} - -func fadviseSequential(f uintptr) error { - return nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/fadvise_linux.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/fadvise_linux.go deleted file mode 100644 index 50c6547..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/fadvise_linux.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2019 The LevelDB-Go and Pebble 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 - -package vfs - -import "golang.org/x/sys/unix" - -// Calls Fadvise with FADV_RANDOM to disable readahead on a file descriptor. -func fadviseRandom(f uintptr) error { - return unix.Fadvise(int(f), 0, 0, unix.FADV_RANDOM) -} - -// Calls Fadvise with FADV_SEQUENTIAL to enable readahead on a file descriptor. -func fadviseSequential(f uintptr) error { - return unix.Fadvise(int(f), 0, 0, unix.FADV_SEQUENTIAL) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/fd.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/fd.go deleted file mode 100644 index 199d304..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/fd.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2021 The LevelDB-Go and Pebble 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 vfs - -// fdGetter is an interface for a file with an Fd() method. A lot of -// File related optimizations (eg. Prefetch(), WAL recycling) rely on the -// existence of the Fd method to return a raw file descriptor. -type fdGetter interface { - Fd() uintptr -} - -// fdFileWrapper is a File wrapper that also exposes an Fd() method. Used to -// wrap outer (wrapped) Files that could unintentionally hide the Fd() method -// exposed by the inner (unwrapped) File. It effectively lets the Fd() method -// bypass the outer File and go to the inner File. -type fdFileWrapper struct { - File - - // All methods usually pass through to File above, except for Fd(), which - // bypasses it and gets called directly on the inner file. - inner fdGetter -} - -func (f *fdFileWrapper) Fd() uintptr { - return f.inner.Fd() -} - -// WithFd takes an inner (unwrapped) and an outer (wrapped) vfs.File, -// and returns an fdFileWrapper if the inner file has an Fd() method. Use this -// method to fix the hiding of the Fd() method and the subsequent unintentional -// disabling of Fd-related file optimizations. -func WithFd(inner, outer File) File { - if f, ok := inner.(fdGetter); ok { - return &fdFileWrapper{ - File: outer, - inner: f, - } - } - return outer -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_generic.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_generic.go deleted file mode 100644 index 5c141c1..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_generic.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2012 The LevelDB-Go and Pebble 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,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows - -package vfs - -import ( - "io" - "runtime" - - "github.com/cockroachdb/errors" -) - -func (defFS) Lock(name string) (io.Closer, error) { - return nil, errors.Errorf("pebble: file locking is not implemented on %s/%s", - errors.Safe(runtime.GOOS), errors.Safe(runtime.GOARCH)) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_unix.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_unix.go deleted file mode 100644 index 5974810..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_unix.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2014 The LevelDB-Go and Pebble 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 dragonfly freebsd linux netbsd openbsd solaris - -package vfs - -import ( - "io" - "os" - "sync" - "syscall" - - "github.com/cockroachdb/errors" -) - -var lockedFiles struct { - mu struct { - sync.Mutex - files map[string]bool - } -} - -// lockCloser hides all of an os.File's methods, except for Close. -type lockCloser struct { - name string - f *os.File -} - -func (l lockCloser) Close() error { - lockedFiles.mu.Lock() - defer lockedFiles.mu.Unlock() - if !lockedFiles.mu.files[l.name] { - panic(errors.Errorf("lock file %q is not locked", l.name)) - } - delete(lockedFiles.mu.files, l.name) - - return l.f.Close() -} - -func (defaultFS) Lock(name string) (io.Closer, error) { - lockedFiles.mu.Lock() - defer lockedFiles.mu.Unlock() - if lockedFiles.mu.files == nil { - lockedFiles.mu.files = map[string]bool{} - } - if lockedFiles.mu.files[name] { - return nil, errors.New("lock held by current process") - } - - f, err := os.Create(name) - if err != nil { - return nil, err - } - spec := syscall.Flock_t{ - Type: syscall.F_WRLCK, - Whence: io.SeekStart, - Start: 0, - Len: 0, // 0 means to lock the entire file. - Pid: int32(os.Getpid()), - } - if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &spec); err != nil { - f.Close() - return nil, err - } - lockedFiles.mu.files[name] = true - return lockCloser{name, f}, nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_windows.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_windows.go deleted file mode 100644 index f9072b8..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/file_lock_windows.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2013 The LevelDB-Go and Pebble 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 windows - -package vfs - -import ( - "io" - "syscall" -) - -// lockCloser hides all of an syscall.Handle's methods, except for Close. -type lockCloser struct { - fd syscall.Handle -} - -func (l lockCloser) Close() error { - return syscall.Close(l.fd) -} - -// Lock locks the given file. On Windows, Locking will fail if the file is -// already open by the current process. -func (defaultFS) Lock(name string) (io.Closer, error) { - p, err := syscall.UTF16PtrFromString(name) - if err != nil { - return nil, err - } - fd, err := syscall.CreateFile(p, - syscall.GENERIC_READ|syscall.GENERIC_WRITE, - 0, nil, syscall.CREATE_ALWAYS, - syscall.FILE_ATTRIBUTE_NORMAL, - 0, - ) - if err != nil { - return nil, err - } - return lockCloser{fd: fd}, nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/mem_fs.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/mem_fs.go deleted file mode 100644 index 424539c..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/mem_fs.go +++ /dev/null @@ -1,709 +0,0 @@ -// Copyright 2012 The LevelDB-Go and Pebble 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 vfs // import "github.com/cockroachdb/pebble/vfs" - -import ( - "bytes" - "fmt" - "io" - "os" - "path" - "sort" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/cockroachdb/errors" - "github.com/cockroachdb/errors/oserror" - "github.com/cockroachdb/pebble/internal/invariants" -) - -const sep = "/" - -// NewMem returns a new memory-backed FS implementation. -func NewMem() *MemFS { - return &MemFS{ - root: &memNode{ - children: make(map[string]*memNode), - isDir: true, - }, - } -} - -// NewStrictMem returns a "strict" memory-backed FS implementation. The behaviour is strict wrt -// needing a Sync() call on files or directories for the state changes to be finalized. Any -// changes that are not finalized are visible to reads until MemFS.ResetToSyncedState() is called, -// at which point they are discarded and no longer visible. -// -// Expected usage: -// strictFS := NewStrictMem() -// db := Open(..., &Options{FS: strictFS}) -// // Do and commit various operations. -// ... -// // Prevent any more changes to finalized state. -// strictFS.SetIgnoreSyncs(true) -// // This will finish any ongoing background flushes, compactions but none of these writes will -// // be finalized since syncs are being ignored. -// db.Close() -// // Discard unsynced state. -// strictFS.ResetToSyncedState() -// // Allow changes to finalized state. -// strictFS.SetIgnoreSyncs(false) -// // Open the DB. This DB should have the same state as if the earlier strictFS operations and -// // db.Close() were not called. -// db := Open(..., &Options{FS: strictFS}) -func NewStrictMem() *MemFS { - return &MemFS{ - root: &memNode{ - children: make(map[string]*memNode), - isDir: true, - }, - strict: true, - } -} - -// NewMemFile returns a memory-backed File implementation. The memory-backed -// file takes ownership of data. -func NewMemFile(data []byte) File { - n := &memNode{refs: 1} - n.mu.data = data - n.mu.modTime = time.Now() - return &memFile{ - n: n, - read: true, - } -} - -// MemFS implements FS. -type MemFS struct { - mu sync.Mutex - root *memNode - - strict bool - ignoreSyncs bool -} - -var _ FS = &MemFS{} - -// String dumps the contents of the MemFS. -func (y *MemFS) String() string { - y.mu.Lock() - defer y.mu.Unlock() - - s := new(bytes.Buffer) - y.root.dump(s, 0) - return s.String() -} - -// SetIgnoreSyncs sets the MemFS.ignoreSyncs field. See the usage comment with NewStrictMem() for -// details. -func (y *MemFS) SetIgnoreSyncs(ignoreSyncs bool) { - y.mu.Lock() - if !y.strict { - // noop - return - } - y.ignoreSyncs = ignoreSyncs - y.mu.Unlock() -} - -// ResetToSyncedState discards state in the FS that is not synced. See the usage comment with -// NewStrictMem() for details. -func (y *MemFS) ResetToSyncedState() { - if !y.strict { - // noop - return - } - y.mu.Lock() - y.root.resetToSyncedState() - y.mu.Unlock() -} - -// walk walks the directory tree for the fullname, calling f at each step. If -// f returns an error, the walk will be aborted and return that same error. -// -// Each walk is atomic: y's mutex is held for the entire operation, including -// all calls to f. -// -// dir is the directory at that step, frag is the name fragment, and final is -// whether it is the final step. For example, walking "/foo/bar/x" will result -// in 3 calls to f: -// - "/", "foo", false -// - "/foo/", "bar", false -// - "/foo/bar/", "x", true -// Similarly, walking "/y/z/", with a trailing slash, will result in 3 calls to f: -// - "/", "y", false -// - "/y/", "z", false -// - "/y/z/", "", true -func (y *MemFS) walk(fullname string, f func(dir *memNode, frag string, final bool) error) error { - y.mu.Lock() - defer y.mu.Unlock() - - // For memfs, the current working directory is the same as the root directory, - // so we strip off any leading "/"s to make fullname a relative path, and - // the walk starts at y.root. - for len(fullname) > 0 && fullname[0] == sep[0] { - fullname = fullname[1:] - } - dir := y.root - - for { - frag, remaining := fullname, "" - i := strings.IndexRune(fullname, rune(sep[0])) - final := i < 0 - if !final { - frag, remaining = fullname[:i], fullname[i+1:] - for len(remaining) > 0 && remaining[0] == sep[0] { - remaining = remaining[1:] - } - } - if err := f(dir, frag, final); err != nil { - return err - } - if final { - break - } - child := dir.children[frag] - if child == nil { - return &os.PathError{ - Op: "open", - Path: fullname, - Err: oserror.ErrNotExist, - } - } - if !child.isDir { - return &os.PathError{ - Op: "open", - Path: fullname, - Err: errors.New("not a directory"), - } - } - dir, fullname = child, remaining - } - return nil -} - -// Create implements FS.Create. -func (y *MemFS) Create(fullname string) (File, error) { - var ret *memFile - err := y.walk(fullname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - return errors.New("pebble/vfs: empty file name") - } - n := &memNode{name: frag} - dir.children[frag] = n - ret = &memFile{ - n: n, - fs: y, - write: true, - } - } - return nil - }) - if err != nil { - return nil, err - } - atomic.AddInt32(&ret.n.refs, 1) - return ret, nil -} - -// Link implements FS.Link. -func (y *MemFS) Link(oldname, newname string) error { - var n *memNode - err := y.walk(oldname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - return errors.New("pebble/vfs: empty file name") - } - n = dir.children[frag] - } - return nil - }) - if err != nil { - return err - } - if n == nil { - return &os.LinkError{ - Op: "link", - Old: oldname, - New: newname, - Err: oserror.ErrNotExist, - } - } - return y.walk(newname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - return errors.New("pebble/vfs: empty file name") - } - if _, ok := dir.children[frag]; ok { - return &os.LinkError{ - Op: "link", - Old: oldname, - New: newname, - Err: oserror.ErrExist, - } - } - dir.children[frag] = n - } - return nil - }) -} - -func (y *MemFS) open(fullname string, allowEmptyName bool) (File, error) { - var ret *memFile - err := y.walk(fullname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - if !allowEmptyName { - return errors.New("pebble/vfs: empty file name") - } - ret = &memFile{ - n: dir, - fs: y, - } - return nil - } - if n := dir.children[frag]; n != nil { - ret = &memFile{ - n: n, - fs: y, - read: true, - } - } - } - return nil - }) - if err != nil { - return nil, err - } - if ret == nil { - return nil, &os.PathError{ - Op: "open", - Path: fullname, - Err: oserror.ErrNotExist, - } - } - atomic.AddInt32(&ret.n.refs, 1) - return ret, nil -} - -// Open implements FS.Open. -func (y *MemFS) Open(fullname string, opts ...OpenOption) (File, error) { - return y.open(fullname, false /* allowEmptyName */) -} - -// OpenDir implements FS.OpenDir. -func (y *MemFS) OpenDir(fullname string) (File, error) { - return y.open(fullname, true /* allowEmptyName */) -} - -// Remove implements FS.Remove. -func (y *MemFS) Remove(fullname string) error { - return y.walk(fullname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - return errors.New("pebble/vfs: empty file name") - } - child, ok := dir.children[frag] - if !ok { - return oserror.ErrNotExist - } - // Disallow removal of open files/directories which implements Windows - // semantics. This ensures that we don't regress in the ordering of - // operations and try to remove a file while it is still open. - if n := atomic.LoadInt32(&child.refs); n > 0 { - return oserror.ErrInvalid - } - if len(child.children) > 0 { - return errNotEmpty - } - delete(dir.children, frag) - } - return nil - }) -} - -// RemoveAll implements FS.RemoveAll. -func (y *MemFS) RemoveAll(fullname string) error { - err := y.walk(fullname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - return errors.New("pebble/vfs: empty file name") - } - _, ok := dir.children[frag] - if !ok { - return nil - } - delete(dir.children, frag) - } - return nil - }) - // Match os.RemoveAll which returns a nil error even if the parent - // directories don't exist. - if oserror.IsNotExist(err) { - err = nil - } - return err -} - -// Rename implements FS.Rename. -func (y *MemFS) Rename(oldname, newname string) error { - var n *memNode - err := y.walk(oldname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - return errors.New("pebble/vfs: empty file name") - } - n = dir.children[frag] - delete(dir.children, frag) - } - return nil - }) - if err != nil { - return err - } - if n == nil { - return &os.PathError{ - Op: "open", - Path: oldname, - Err: oserror.ErrNotExist, - } - } - return y.walk(newname, func(dir *memNode, frag string, final bool) error { - if final { - if frag == "" { - return errors.New("pebble/vfs: empty file name") - } - dir.children[frag] = n - n.name = frag - } - return nil - }) -} - -// ReuseForWrite implements FS.ReuseForWrite. -func (y *MemFS) ReuseForWrite(oldname, newname string) (File, error) { - if err := y.Rename(oldname, newname); err != nil { - return nil, err - } - f, err := y.Open(newname) - if err != nil { - return nil, err - } - y.mu.Lock() - defer y.mu.Unlock() - - mf := f.(*memFile) - mf.read = false - mf.write = true - return f, nil -} - -// MkdirAll implements FS.MkdirAll. -func (y *MemFS) MkdirAll(dirname string, perm os.FileMode) error { - return y.walk(dirname, func(dir *memNode, frag string, final bool) error { - if frag == "" { - if final { - return nil - } - return errors.New("pebble/vfs: empty file name") - } - child := dir.children[frag] - if child == nil { - dir.children[frag] = &memNode{ - name: frag, - children: make(map[string]*memNode), - isDir: true, - } - return nil - } - if !child.isDir { - return &os.PathError{ - Op: "open", - Path: dirname, - Err: errors.New("not a directory"), - } - } - return nil - }) -} - -// Lock implements FS.Lock. -func (y *MemFS) Lock(fullname string) (io.Closer, error) { - // FS.Lock excludes other processes, but other processes cannot see this - // process' memory. We translate Lock into Create so that have the normal - // detection of non-existent directory paths. - return y.Create(fullname) -} - -// List implements FS.List. -func (y *MemFS) List(dirname string) ([]string, error) { - if !strings.HasSuffix(dirname, sep) { - dirname += sep - } - var ret []string - err := y.walk(dirname, func(dir *memNode, frag string, final bool) error { - if final { - if frag != "" { - panic("unreachable") - } - ret = make([]string, 0, len(dir.children)) - for s := range dir.children { - ret = append(ret, s) - } - } - return nil - }) - return ret, err -} - -// Stat implements FS.Stat. -func (y *MemFS) Stat(name string) (os.FileInfo, error) { - f, err := y.Open(name) - if err != nil { - if pe, ok := err.(*os.PathError); ok { - pe.Op = "stat" - } - return nil, err - } - defer f.Close() - return f.Stat() -} - -// PathBase implements FS.PathBase. -func (*MemFS) PathBase(p string) string { - // Note that MemFS uses forward slashes for its separator, hence the use of - // path.Base, not filepath.Base. - return path.Base(p) -} - -// PathJoin implements FS.PathJoin. -func (*MemFS) PathJoin(elem ...string) string { - // Note that MemFS uses forward slashes for its separator, hence the use of - // path.Join, not filepath.Join. - return path.Join(elem...) -} - -// PathDir implements FS.PathDir. -func (*MemFS) PathDir(p string) string { - // Note that MemFS uses forward slashes for its separator, hence the use of - // path.Dir, not filepath.Dir. - return path.Dir(p) -} - -// GetDiskUsage implements FS.GetDiskUsage. -func (*MemFS) GetDiskUsage(string) (DiskUsage, error) { - return DiskUsage{}, ErrUnsupported -} - -// memNode holds a file's data or a directory's children, and implements os.FileInfo. -type memNode struct { - name string - isDir bool - refs int32 - - // Mutable state. - // - For a file: data, syncedDate, modTime: A file is only being mutated by a single goroutine, - // but there can be concurrent readers e.g. DB.Checkpoint() which can read WAL or MANIFEST - // files that are being written to. Additionally Sync() calls can be concurrent with writing. - // - For a directory: children and syncedChildren. Concurrent writes are possible, and - // these are protected using MemFS.mu. - mu struct { - sync.Mutex - data []byte - syncedData []byte - modTime time.Time - } - - children map[string]*memNode - syncedChildren map[string]*memNode -} - -func (f *memNode) IsDir() bool { - return f.isDir -} - -func (f *memNode) ModTime() time.Time { - f.mu.Lock() - defer f.mu.Unlock() - return f.mu.modTime -} - -func (f *memNode) Mode() os.FileMode { - if f.isDir { - return os.ModeDir | 0755 - } - return 0755 -} - -func (f *memNode) Name() string { - return f.name -} - -func (f *memNode) Size() int64 { - f.mu.Lock() - defer f.mu.Unlock() - return int64(len(f.mu.data)) -} - -func (f *memNode) Sys() interface{} { - return nil -} - -func (f *memNode) dump(w *bytes.Buffer, level int) { - if f.isDir { - w.WriteString(" ") - } else { - f.mu.Lock() - fmt.Fprintf(w, "%8d ", len(f.mu.data)) - f.mu.Unlock() - } - for i := 0; i < level; i++ { - w.WriteString(" ") - } - w.WriteString(f.name) - if !f.isDir { - w.WriteByte('\n') - return - } - w.WriteByte(sep[0]) - w.WriteByte('\n') - names := make([]string, 0, len(f.children)) - for name := range f.children { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { - f.children[name].dump(w, level+1) - } -} - -func (f *memNode) resetToSyncedState() { - if f.isDir { - f.children = make(map[string]*memNode) - for k, v := range f.syncedChildren { - f.children[k] = v - } - for _, v := range f.children { - v.resetToSyncedState() - } - } else { - f.mu.Lock() - f.mu.data = append([]byte(nil), f.mu.syncedData...) - f.mu.Unlock() - } -} - -// memFile is a reader or writer of a node's data, and implements File. -type memFile struct { - n *memNode - fs *MemFS // nil for a standalone memFile - rpos int - wpos int - read, write bool -} - -func (f *memFile) Close() error { - if n := atomic.AddInt32(&f.n.refs, -1); n < 0 { - panic(fmt.Sprintf("pebble: close of unopened file: %d", n)) - } - f.n = nil - return nil -} - -func (f *memFile) Read(p []byte) (int, error) { - if !f.read { - return 0, errors.New("pebble/vfs: file was not opened for reading") - } - if f.n.isDir { - return 0, errors.New("pebble/vfs: cannot read a directory") - } - f.n.mu.Lock() - defer f.n.mu.Unlock() - if f.rpos >= len(f.n.mu.data) { - return 0, io.EOF - } - n := copy(p, f.n.mu.data[f.rpos:]) - f.rpos += n - return n, nil -} - -func (f *memFile) ReadAt(p []byte, off int64) (int, error) { - if !f.read { - return 0, errors.New("pebble/vfs: file was not opened for reading") - } - if f.n.isDir { - return 0, errors.New("pebble/vfs: cannot read a directory") - } - f.n.mu.Lock() - defer f.n.mu.Unlock() - if off >= int64(len(f.n.mu.data)) { - return 0, io.EOF - } - return copy(p, f.n.mu.data[off:]), nil -} - -func (f *memFile) Write(p []byte) (int, error) { - if !f.write { - return 0, errors.New("pebble/vfs: file was not created for writing") - } - if f.n.isDir { - return 0, errors.New("pebble/vfs: cannot write a directory") - } - f.n.mu.Lock() - defer f.n.mu.Unlock() - f.n.mu.modTime = time.Now() - if f.wpos+len(p) <= len(f.n.mu.data) { - n := copy(f.n.mu.data[f.wpos:f.wpos+len(p)], p) - if n != len(p) { - panic("stuff") - } - } else { - f.n.mu.data = append(f.n.mu.data[:f.wpos], p...) - } - f.wpos += len(p) - - if invariants.Enabled { - // Mutate the input buffer to flush out bugs in Pebble which expect the - // input buffer to be unmodified. - for i := range p { - p[i] ^= 0xff - } - } - return len(p), nil -} - -func (f *memFile) Stat() (os.FileInfo, error) { - return f.n, nil -} - -func (f *memFile) Sync() error { - if f.fs != nil && f.fs.strict { - f.fs.mu.Lock() - defer f.fs.mu.Unlock() - if f.fs.ignoreSyncs { - return nil - } - if f.n.isDir { - f.n.syncedChildren = make(map[string]*memNode) - for k, v := range f.n.children { - f.n.syncedChildren[k] = v - } - } else { - f.n.mu.Lock() - f.n.mu.syncedData = append([]byte(nil), f.n.mu.data...) - f.n.mu.Unlock() - } - } - return nil -} - -// Flush is a no-op and present only to prevent buffering at higher levels -// (e.g. it prevents sstable.Writer from using a bufio.Writer). -func (f *memFile) Flush() error { - return nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/preallocate_generic.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/preallocate_generic.go deleted file mode 100644 index a707392..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/preallocate_generic.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build !linux - -package vfs - -func preallocExtend(fd uintptr, offset, length int64) error { - // It is ok for correctness to no-op file preallocation. WAL recycling is the - // more important mechanism for WAL sync performance and it doesn't rely on - // fallocate or posix_fallocate in order to be effective. - return nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/preallocate_linux.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/preallocate_linux.go deleted file mode 100644 index d7484d4..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/preallocate_linux.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2016 The etcd Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build linux - -package vfs - -import ( - "syscall" - - "golang.org/x/sys/unix" -) - -func preallocExtend(fd uintptr, offset, length int64) error { - return syscall.Fallocate(int(fd), unix.FALLOC_FL_KEEP_SIZE, offset, length) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/prefetch_generic.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/prefetch_generic.go deleted file mode 100644 index 7d30d3b..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/prefetch_generic.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 - -package vfs - -// Prefetch signals the OS (on supported platforms) to fetch the next size -// bytes in file (as returned by os.File.Fd()) after offset into cache. Any -// subsequent reads in that range will not issue disk IO. -func Prefetch(file uintptr, offset uint64, size uint64) error { - // No-op. - return nil -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/prefetch_linux.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/prefetch_linux.go deleted file mode 100644 index 103fb4e..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/prefetch_linux.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2020 The LevelDB-Go and Pebble 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 - -package vfs - -import "syscall" - -// Prefetch signals the OS (on supported platforms) to fetch the next size -// bytes in file (as returned by os.File.Fd()) after offset into cache. Any -// subsequent reads in that range will not issue disk IO. -func Prefetch(file uintptr, offset uint64, size uint64) error { - _, _, err := syscall.Syscall(syscall.SYS_READAHEAD, uintptr(file), uintptr(offset), uintptr(size)) - return err -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file.go deleted file mode 100644 index dd2201f..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2019 The LevelDB-Go and Pebble 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 vfs - -import ( - "sync/atomic" - - "github.com/cockroachdb/errors" -) - -// SyncingFileOptions holds the options for a syncingFile. -type SyncingFileOptions struct { - BytesPerSync int - PreallocateSize int -} - -type syncingFile struct { - File - fd uintptr - useSyncRange bool - bytesPerSync int64 - preallocateSize int64 - atomic struct { - // The offset at which dirty data has been written. - offset int64 - // The offset at which data has been synced. Note that if SyncFileRange is - // being used, the periodic syncing of data during writing will only ever - // sync up to offset-1MB. This is done to avoid rewriting the tail of the - // file multiple times, but has the side effect of ensuring that Close will - // sync the file's metadata. - syncOffset int64 - } - preallocatedBlocks int64 - syncData func() error - syncTo func(offset int64) error - timeDiskOp func(op func()) -} - -// NewSyncingFile wraps a writable file and ensures that data is synced -// periodically as it is written. The syncing does not provide persistency -// guarantees for these periodic syncs, but is used to avoid latency spikes if -// the OS automatically decides to write out a large chunk of dirty filesystem -// buffers. The underlying file is fully synced upon close. -func NewSyncingFile(f File, opts SyncingFileOptions) File { - s := &syncingFile{ - File: f, - bytesPerSync: int64(opts.BytesPerSync), - preallocateSize: int64(opts.PreallocateSize), - } - // Ensure a file that is opened and then closed will be synced, even if no - // data has been written to it. - s.atomic.syncOffset = -1 - - type fd interface { - Fd() uintptr - } - if d, ok := f.(fd); ok { - s.fd = d.Fd() - } - type dhChecker interface { - timeDiskOp(op func()) - } - if d, ok := f.(dhChecker); ok { - s.timeDiskOp = d.timeDiskOp - } else { - s.timeDiskOp = func(op func()) { - op() - } - } - - s.init() - - if s.syncData == nil { - s.syncData = s.File.Sync - } - return WithFd(f, s) -} - -// NB: syncingFile.Write is unsafe for concurrent use! -func (f *syncingFile) Write(p []byte) (n int, err error) { - _ = f.preallocate(atomic.LoadInt64(&f.atomic.offset)) - - n, err = f.File.Write(p) - if err != nil { - return n, errors.WithStack(err) - } - // The offset is updated atomically so that it can be accessed safely from - // Sync. - atomic.AddInt64(&f.atomic.offset, int64(n)) - if err := f.maybeSync(); err != nil { - return 0, err - } - return n, nil -} - -func (f *syncingFile) preallocate(offset int64) error { - if f.fd == 0 || f.preallocateSize == 0 { - return nil - } - - newPreallocatedBlocks := (offset + f.preallocateSize - 1) / f.preallocateSize - if newPreallocatedBlocks <= f.preallocatedBlocks { - return nil - } - - length := f.preallocateSize * (newPreallocatedBlocks - f.preallocatedBlocks) - offset = f.preallocateSize * f.preallocatedBlocks - f.preallocatedBlocks = newPreallocatedBlocks - return preallocExtend(f.fd, offset, length) -} - -func (f *syncingFile) ratchetSyncOffset(offset int64) { - for { - syncOffset := atomic.LoadInt64(&f.atomic.syncOffset) - if syncOffset >= offset { - return - } - if atomic.CompareAndSwapInt64(&f.atomic.syncOffset, syncOffset, offset) { - return - } - } -} - -func (f *syncingFile) Sync() error { - // We update syncOffset (atomically) in order to avoid spurious syncs in - // maybeSync. Note that even if syncOffset is larger than the current file - // offset, we still need to call the underlying file's sync for persistence - // guarantees (which are not provided by sync_file_range). - f.ratchetSyncOffset(atomic.LoadInt64(&f.atomic.offset)) - return f.syncData() -} - -func (f *syncingFile) maybeSync() error { - if f.bytesPerSync <= 0 { - return nil - } - - // From the RocksDB source: - // - // We try to avoid sync to the last 1MB of data. For two reasons: - // (1) avoid rewrite the same page that is modified later. - // (2) for older version of OS, write can block while writing out - // the page. - // Xfs does neighbor page flushing outside of the specified ranges. We - // need to make sure sync range is far from the write offset. - const syncRangeBuffer = 1 << 20 // 1 MB - offset := atomic.LoadInt64(&f.atomic.offset) - if offset <= syncRangeBuffer { - return nil - } - - const syncRangeAlignment = 4 << 10 // 4 KB - syncToOffset := offset - syncRangeBuffer - syncToOffset -= syncToOffset % syncRangeAlignment - syncOffset := atomic.LoadInt64(&f.atomic.syncOffset) - if syncToOffset < 0 || (syncToOffset-syncOffset) < f.bytesPerSync { - return nil - } - - if f.fd == 0 { - return errors.WithStack(f.Sync()) - } - - // Note that syncTo will always be called with an offset < atomic.offset. The - // syncTo implementation may choose to sync the entire file (i.e. on OSes - // which do not support syncing a portion of the file). The syncTo - // implementation must call ratchetSyncOffset with as much of the file as it - // has synced. - return errors.WithStack(f.syncTo(syncToOffset)) -} - -func (f *syncingFile) Close() error { - // Sync any data that has been written but not yet synced. Note that if - // SyncFileRange was used, atomic.syncOffset will be less than - // atomic.offset. See syncingFile.syncToRange. - if atomic.LoadInt64(&f.atomic.offset) > atomic.LoadInt64(&f.atomic.syncOffset) { - if err := f.Sync(); err != nil { - return errors.WithStack(err) - } - } - return errors.WithStack(f.File.Close()) -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file_generic.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file_generic.go deleted file mode 100644 index 4c6b3e4..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file_generic.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2019 The LevelDB-Go and Pebble 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 arm - -package vfs - -func (f *syncingFile) init() { - f.syncTo = f.syncToGeneric -} - -func (f *syncingFile) syncToGeneric(_ int64) error { - return f.Sync() -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file_linux.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file_linux.go deleted file mode 100644 index 5393349..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/syncing_file_linux.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2019 The LevelDB-Go and Pebble 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,!arm - -package vfs - -import "syscall" - -type syncFileRange func(fd int, off int64, n int64, flags int) (err error) - -// sync_file_range depends on both the filesystem, and the broader kernel -// support. In particular, Windows Subsystem for Linux does not support -// sync_file_range, even when used with ext{2,3,4}. syncRangeSmokeTest performs -// a test of of sync_file_range, returning false on ENOSYS, and true otherwise. -func syncRangeSmokeTest(fd uintptr, fn syncFileRange) bool { - err := fn(int(fd), 0 /* offset */, 0 /* nbytes */, 0 /* flags */) - return err != syscall.ENOSYS -} - -func isSyncRangeSupported(fd uintptr) bool { - var stat syscall.Statfs_t - if err := syscall.Fstatfs(int(fd), &stat); err != nil { - return false - } - - // Allowlist which filesystems we allow using sync_file_range with as some - // filesystems treat that syscall as a noop (notably ZFS). A allowlist is - // used instead of a denylist in order to have a more graceful failure mode - // in case a filesystem we haven't tested is encountered. Currently only - // ext2/3/4 are known to work properly. - const extMagic = 0xef53 - switch stat.Type { - case extMagic: - return syncRangeSmokeTest(fd, syscall.SyncFileRange) - } - return false -} - -func (f *syncingFile) init() { - if f.fd == 0 { - return - } - f.timeDiskOp(func() { - f.useSyncRange = isSyncRangeSupported(f.fd) - }) - if f.useSyncRange { - f.syncTo = f.syncToRange - } else { - f.syncTo = f.syncToFdatasync - } - f.syncData = f.syncFdatasync -} - -func (f *syncingFile) syncFdatasync() error { - if f.fd == 0 { - return f.File.Sync() - } - var err error - f.timeDiskOp(func() { - err = syscall.Fdatasync(int(f.fd)) - }) - return err -} - -func (f *syncingFile) syncToFdatasync(_ int64) error { - return f.Sync() -} - -func (f *syncingFile) syncToRange(offset int64) error { - const ( - waitBefore = 0x1 - write = 0x2 - // waitAfter = 0x4 - ) - - // Note that syncToRange is only called with an offset that is guaranteed to - // be less than atomic.offset (i.e. the write offset). This implies the - // syncingFile.Close will Sync the rest of the data, as well as the file's - // metadata. - f.ratchetSyncOffset(offset) - - // By specifying write|waitBefore for the flags, we're instructing - // SyncFileRange to a) wait for any outstanding data being written to finish, - // and b) to queue any other dirty data blocks in the range [0,offset] for - // writing. The actual writing of this data will occur asynchronously. The - // use of `waitBefore` is to limit how much dirty data is allowed to - // accumulate. Linux sometimes behaves poorly when a large amount of dirty - // data accumulates, impacting other I/O operations. - var err error - f.timeDiskOp(func() { - err = syscall.SyncFileRange(int(f.fd), 0, offset, write|waitBefore) - }) - return err -} diff --git a/cockroach/patches/github.com/cockroachdb/pebble/vfs/vfs.go b/cockroach/patches/github.com/cockroachdb/pebble/vfs/vfs.go deleted file mode 100644 index 965bf37..0000000 --- a/cockroach/patches/github.com/cockroachdb/pebble/vfs/vfs.go +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright 2012 The LevelDB-Go and Pebble 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 vfs - -import ( - "io" - "os" - "path/filepath" - "syscall" - - "github.com/cockroachdb/errors" - "github.com/cockroachdb/errors/oserror" -) - -// File is a readable, writable sequence of bytes. -// -// Typically, it will be an *os.File, but test code may choose to substitute -// memory-backed implementations. -type File interface { - io.Closer - io.Reader - io.ReaderAt - // Unlike the specification for io.Writer.Write(), the vfs.File.Write() - // method *is* allowed to modify the slice passed in, whether temporarily - // or permanently. Callers of Write() need to take this into account. - io.Writer - Stat() (os.FileInfo, error) - Sync() error -} - -// OpenOption provide an interface to do work on file handles in the Open() -// call. -type OpenOption interface { - // Apply is called on the file handle after it's opened. - Apply(File) -} - -// FS is a namespace for files. -// -// The names are filepath names: they may be / separated or \ separated, -// depending on the underlying operating system. -type FS interface { - // Create creates the named file for reading and writing. If a file - // already exists at the provided name, it's removed first ensuring the - // resulting file descriptor points to a new inode. - Create(name string) (File, error) - - // Link creates newname as a hard link to the oldname file. - Link(oldname, newname string) error - - // Open opens the named file for reading. openOptions provides - Open(name string, opts ...OpenOption) (File, error) - - // OpenDir opens the named directory for syncing. - OpenDir(name string) (File, error) - - // Remove removes the named file or directory. - Remove(name string) error - - // Remove removes the named file or directory and any children it - // contains. It removes everything it can but returns the first error it - // encounters. - RemoveAll(name string) error - - // Rename renames a file. It overwrites the file at newname if one exists, - // the same as os.Rename. - Rename(oldname, newname string) error - - // ReuseForWrite attempts to reuse the file with oldname by renaming it to newname and opening - // it for writing without truncation. It is acceptable for the implementation to choose not - // to reuse oldname, and simply create the file with newname -- in this case the implementation - // should delete oldname. If the caller calls this function with an oldname that does not exist, - // the implementation may return an error. - ReuseForWrite(oldname, newname string) (File, error) - - // MkdirAll creates a directory and all necessary parents. The permission - // bits perm have the same semantics as in os.MkdirAll. If the directory - // already exists, MkdirAll does nothing and returns nil. - MkdirAll(dir string, perm os.FileMode) error - - // Lock locks the given file, creating the file if necessary, and - // truncating the file if it already exists. The lock is an exclusive lock - // (a write lock), but locked files should neither be read from nor written - // to. Such files should have zero size and only exist to co-ordinate - // ownership across processes. - // - // A nil Closer is returned if an error occurred. Otherwise, close that - // Closer to release the lock. - // - // On Linux and OSX, a lock has the same semantics as fcntl(2)'s advisory - // locks. In particular, closing any other file descriptor for the same - // file will release the lock prematurely. - // - // Attempting to lock a file that is already locked by the current process - // returns an error and leaves the existing lock untouched. - // - // Lock is not yet implemented on other operating systems, and calling it - // will return an error. - Lock(name string) (io.Closer, error) - - // List returns a listing of the given directory. The names returned are - // relative to dir. - List(dir string) ([]string, error) - - // Stat returns an os.FileInfo describing the named file. - Stat(name string) (os.FileInfo, error) - - // PathBase returns the last element of path. Trailing path separators are - // removed before extracting the last element. If the path is empty, PathBase - // returns ".". If the path consists entirely of separators, PathBase returns a - // single separator. - PathBase(path string) string - - // PathJoin joins any number of path elements into a single path, adding a - // separator if necessary. - PathJoin(elem ...string) string - - // PathDir returns all but the last element of path, typically the path's directory. - PathDir(path string) string - - // GetDiskUsage returns disk space statistics for the filesystem where - // path is any file or directory within that filesystem. - GetDiskUsage(path string) (DiskUsage, error) -} - -// DiskUsage summarizes disk space usage on a filesystem. -type DiskUsage struct { - // Total disk space available to the current process in bytes. - AvailBytes uint64 - // Total disk space in bytes. - TotalBytes uint64 - // Used disk space in bytes. - UsedBytes uint64 -} - -// Default is a FS implementation backed by the underlying operating system's -// file system. -var Default FS = defaultFS{} - -type defaultFS struct{} - -func (defaultFS) Create(name string) (File, error) { - const openFlags = os.O_RDWR | os.O_CREATE | os.O_EXCL | syscall.O_CLOEXEC - - f, err := os.OpenFile(name, openFlags, 0666) - // If the file already exists, remove it and try again. - // - // NB: We choose to remove the file instead of truncating it, despite the - // fact that we can't do so atomically, because it's more resistant to - // misuse when using hard links. - - // We must loop in case another goroutine/thread/process is also - // attempting to create the a file at the same path. - for oserror.IsExist(err) { - if removeErr := os.Remove(name); removeErr != nil && !oserror.IsNotExist(removeErr) { - return f, errors.WithStack(removeErr) - } - f, err = os.OpenFile(name, openFlags, 0666) - } - return f, errors.WithStack(err) -} - -func (defaultFS) Link(oldname, newname string) error { - return errors.WithStack(os.Link(oldname, newname)) -} - -func (defaultFS) Open(name string, opts ...OpenOption) (File, error) { - file, err := os.OpenFile(name, os.O_RDONLY|syscall.O_CLOEXEC, 0) - if err != nil { - return nil, errors.WithStack(err) - } - for _, opt := range opts { - opt.Apply(file) - } - return file, nil -} - -func (defaultFS) Remove(name string) error { - return errors.WithStack(os.Remove(name)) -} - -func (defaultFS) RemoveAll(name string) error { - return errors.WithStack(os.RemoveAll(name)) -} - -func (defaultFS) Rename(oldname, newname string) error { - return errors.WithStack(os.Rename(oldname, newname)) -} - -func (fs defaultFS) ReuseForWrite(oldname, newname string) (File, error) { - if err := fs.Rename(oldname, newname); err != nil { - return nil, errors.WithStack(err) - } - f, err := os.OpenFile(newname, os.O_RDWR|os.O_CREATE|syscall.O_CLOEXEC, 0666) - return f, errors.WithStack(err) -} - -func (defaultFS) MkdirAll(dir string, perm os.FileMode) error { - return errors.WithStack(os.MkdirAll(dir, perm)) -} - -func (defaultFS) List(dir string) ([]string, error) { - f, err := os.Open(dir) - if err != nil { - return nil, err - } - defer f.Close() - dirnames, err := f.Readdirnames(-1) - return dirnames, errors.WithStack(err) -} - -func (defaultFS) Stat(name string) (os.FileInfo, error) { - finfo, err := os.Stat(name) - return finfo, errors.WithStack(err) -} - -func (defaultFS) PathBase(path string) string { - return filepath.Base(path) -} - -func (defaultFS) PathJoin(elem ...string) string { - return filepath.Join(elem...) -} - -func (defaultFS) PathDir(path string) string { - return filepath.Dir(path) -} - -type randomReadsOption struct{} - -// RandomReadsOption is an OpenOption that optimizes opened file handle for -// random reads, by calling fadvise() with POSIX_FADV_RANDOM on Linux systems -// to disable readahead. -var RandomReadsOption OpenOption = &randomReadsOption{} - -// Apply implements the OpenOption interface. -func (randomReadsOption) Apply(f File) { - type fd interface { - Fd() uintptr - } - if fdFile, ok := f.(fd); ok { - _ = fadviseRandom(fdFile.Fd()) - } -} - -type sequentialReadsOption struct{} - -// SequentialReadsOption is an OpenOption that optimizes opened file handle for -// sequential reads, by calling fadvise() with POSIX_FADV_SEQUENTIAL on Linux -// systems to enable readahead. -var SequentialReadsOption OpenOption = &sequentialReadsOption{} - -// Apply implements the OpenOption interface. -func (sequentialReadsOption) Apply(f File) { - type fd interface { - Fd() uintptr - } - if fdFile, ok := f.(fd); ok { - _ = fadviseSequential(fdFile.Fd()) - } -} - -// Copy copies the contents of oldname to newname. If newname exists, it will -// be overwritten. -func Copy(fs FS, oldname, newname string) error { - src, err := fs.Open(oldname) - if err != nil { - return err - } - defer src.Close() - - dst, err := fs.Create(newname) - if err != nil { - return err - } - defer dst.Close() - - if _, err := io.Copy(dst, src); err != nil { - return err - } - return dst.Sync() -} - -// LimitedCopy copies up to maxBytes from oldname to newname. If newname -// exists, it will be overwritten. -func LimitedCopy(fs FS, oldname, newname string, maxBytes int64) error { - src, err := fs.Open(oldname) - if err != nil { - return err - } - defer src.Close() - - dst, err := fs.Create(newname) - if err != nil { - return err - } - defer dst.Close() - - if _, err := io.Copy(dst, &io.LimitedReader{R: src, N: maxBytes}); err != nil { - return err - } - return dst.Sync() -} - -// LinkOrCopy creates newname as a hard link to the oldname file. If creating -// the hard link fails, LinkOrCopy falls back to copying the file (which may -// also fail if newname doesn't exist or oldname already exists). -func LinkOrCopy(fs FS, oldname, newname string) error { - err := fs.Link(oldname, newname) - if err == nil { - return nil - } - // Permit a handful of errors which we know won't be fixed by copying the - // file. Note that we don't check for the specifics of the error code as it - // isn't easy to do so in a portable manner. On Unix we'd have to check for - // LinkError.Err == syscall.EXDEV. On Windows we'd have to check for - // ERROR_NOT_SAME_DEVICE, ERROR_INVALID_FUNCTION, and - // ERROR_INVALID_PARAMETER. Rather that such OS specific checks, we fall back - // to always trying to copy if hard-linking failed. - if oserror.IsExist(err) || oserror.IsNotExist(err) || oserror.IsPermission(err) { - return err - } - return Copy(fs, oldname, newname) -} - -// Root returns the base FS implementation, unwrapping all nested FSs that -// expose an Unwrap method. -func Root(fs FS) FS { - type unwrapper interface { - Unwrap() FS - } - - for { - u, ok := fs.(unwrapper) - if !ok { - break - } - fs = u.Unwrap() - } - return fs -} - -// ErrUnsupported may be returned a FS when it does not support an operation. -var ErrUnsupported = errors.New("pebble: not supported") diff --git a/cockroach/patches/github.com/elastic/gosigar/.appveyor.yml b/cockroach/patches/github.com/elastic/gosigar/.appveyor.yml deleted file mode 100644 index 4684127..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/.appveyor.yml +++ /dev/null @@ -1,73 +0,0 @@ -# Version format -version: "{build}" - -# Operating system (build VM template) -os: Windows Server 2012 R2 - -# Environment variables -environment: - GOPATH: c:\gopath - GVM_GO_VERSION: 1.10.8 - GVM_DL: https://github.com/andrewkroh/gvm/releases/download/v0.2.2/gvm-windows-amd64.exe - -# Custom clone folder (variables are not expanded here). -clone_folder: c:\gopath\src\github.com\elastic\gosigar - -# Cache mingw install until appveyor.yml is modified. -cache: -- C:\ProgramData\chocolatey\bin -> .appveyor.yml -- C:\ProgramData\chocolatey\lib -> .appveyor.yml -- C:\Users\appveyor\.gvm -> .appveyor.yml -- C:\Windows\System32\gvm.exe -> .appveyor.yml -- C:\tools\mingw64 -> .appveyor.yml - -# Scripts that run after cloning repository -install: - - ps: >- - if(!(Test-Path "C:\Windows\System32\gvm.exe")) { - wget "$env:GVM_DL" -Outfile C:\Windows\System32\gvm.exe - } - - ps: gvm --format=powershell "$env:GVM_GO_VERSION" | Invoke-Expression - # AppVeyor installed mingw is 32-bit only so install 64-bit version. - - ps: >- - if(!(Test-Path "C:\tools\mingw64\bin\gcc.exe")) { - cinst mingw > mingw-install.txt - Push-AppveyorArtifact mingw-install.txt - } - - set PATH=C:\tools\mingw64\bin;%GOROOT%\bin;%PATH% - - set PATH=%GOPATH%\bin;%PATH% - - go version - - go env - - python --version - -# To run your custom scripts instead of automatic MSBuild -build_script: - # Compile - - appveyor AddCompilationMessage "Starting Compile" - - cd c:\gopath\src\github.com\elastic\gosigar - - go get -v -t -d ./... - - go build - - go build -o examples/df/df.exe ./examples/df - - go build -o examples/free/free.exe ./examples/free - - go build -o examples/ps/ps.exe ./examples/ps - - go build -o examples/uptime/uptime.exe ./examples/uptime - - appveyor AddCompilationMessage "Compile Success" - -# To run your custom scripts instead of automatic tests -test_script: - # Unit tests - - ps: Add-AppveyorTest "Unit Tests" -Outcome Running - - go test -v ./... - - ps: Update-AppveyorTest "Unit Tests" -Outcome Passed - - ps: Add-AppveyorTest "Running Examples" -Outcome Running - - .\examples\df\df.exe - - .\examples\free\free.exe - - .\examples\ps\ps.exe - - .\examples\uptime\uptime.exe - - ps: Update-AppveyorTest "Running Examples" -Outcome Passed - -# To disable deployment -deploy: off - -# Notifications should only be setup using the AppVeyor UI so that -# forks can be created without inheriting the settings. diff --git a/cockroach/patches/github.com/elastic/gosigar/.gitignore b/cockroach/patches/github.com/elastic/gosigar/.gitignore deleted file mode 100644 index 6f14505..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# Directories -/.vagrant -/.idea -/build - -# Files -.DS_Store -/*.iml -*.h - -# Editor swap files -*.swp -*.swo -*.swn - -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so -*.exe -*.test -*.prof -*.pyc -*.swp - -# Example binaries -examples/df/df -examples/df/df.exe -examples/free/free -examples/free/free.exe -examples/ps/ps -examples/ps/ps.exe -examples/ss/ss -examples/ss/ss.exe -examples/uptime/uptime -examples/uptime/uptime.exe - -# Test Data -cgroup/testdata/* -!cgroup/testdata/*.zip - diff --git a/cockroach/patches/github.com/elastic/gosigar/.travis.yml b/cockroach/patches/github.com/elastic/gosigar/.travis.yml deleted file mode 100644 index 408f9a5..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -language: go - -os: - - linux - - osx - -go: - - 1.10.x - - 1.14.x - -env: - global: - - PROJ="github.com/elastic/gosigar" - -sudo: false - -before_install: - # Put project into proper GOPATH location (important for forks). - - mkdir -p $HOME/gopath/src/${PROJ} - - rsync -az ${TRAVIS_BUILD_DIR}/ $HOME/gopath/src/${PROJ}/ - - export TRAVIS_BUILD_DIR=$HOME/gopath/src/${PROJ} - - cd $HOME/gopath/src/${PROJ} - -install: - - go get -v -t -d ./... - -script: - - gofmt -l . | read && echo "Code differs from gofmt's style. Run 'gofmt -w .'" 1>&2 && exit 1 || true - - go vet - - go build - - go test -v ./... - - for i in $(ls examples); do go build -o examples/$i/$i ./examples/$i; ./examples/$i/$i; done \ No newline at end of file diff --git a/cockroach/patches/github.com/elastic/gosigar/CHANGELOG.md b/cockroach/patches/github.com/elastic/gosigar/CHANGELOG.md deleted file mode 100644 index 8e0e6f9..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/CHANGELOG.md +++ /dev/null @@ -1,186 +0,0 @@ -# elastic/gosigar Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added - -- Add AIX support. #133 - -### Fixed - -### Changed - -### Deprecated - -## [0.11.0] - -### Added - -- Added support for AIX. [#133](https://github.com/elastic/gosigar/pull/133) - -### Fixed - -- Fixed the `ss` example by replacing the Logrus package with the stdlib `log` package. [#123](https://github.com/elastic/gosigar/issues/123) [#136](https://github.com/elastic/gosigar/pull/136) -- Replaced `bytePtrToString` and cleaned up darwin code. [#138](https://github.com/elastic/gosigar/issues/138) [#141](https://github.com/elastic/gosigar/pull/141) - -## [0.10.5] - -### Fixed - -- Fixed uptime calculation under Windows. [#126](https://github.com/elastic/gosigar/pull/126) -- Fixed compilation issue for darwin/386. [#128](https://github.com/elastic/gosigar/pull/128) - -### Changed - -- Load DLLs only from Windows system directory. [#132](https://github.com/elastic/gosigar/pull/132) - -## [0.10.4] - -### Fixed - -- Fixed a crash when splitting command-line arguments under Windows. [#124](https://github.com/elastic/gosigar/pull/124) - -## [0.10.3] - -### Fixed -- ProcState.Get() doesn't fail under Windows when it cannot obtain process ownership information. [#121](https://github.com/elastic/gosigar/pull/121) - -## [0.10.2] - -### Fixed -- Fix memory leak when getting process arguments. [#119](https://github.com/elastic/gosigar/pull/119) - -## [0.10.1] - -### Fixed -- Replaced the WMI queries with win32 apis due to high CPU usage. [#116](https://github.com/elastic/gosigar/pull/116) - -## [0.10.0] - -### Added -- List filesystems on Windows that have an access path but not an assigned letter. [#112](https://github.com/elastic/gosigar/pull/112) - -### Fixed -- Added missing runtime import for FreeBSD. [#104](https://github.com/elastic/gosigar/pull/104) -- Handle nil command line in Windows processes. [#110](https://github.com/elastic/gosigar/pull/110) - -## [0.9.0] - -### Added -- Added support for huge TLB pages on Linux [#97](https://github.com/elastic/gosigar/pull/97) -- Added support for big endian platform [#100](https://github.com/elastic/gosigar/pull/100) - -### Fixed -- Add missing method for OpenBSD [#99](https://github.com/elastic/gosigar/pull/99) - -## [0.8.0] - -### Added -- Added partial `getrusage` support for Windows to retrieve system CPU time and user CPU time. [#95](https://github.com/elastic/gosigar/pull/95) -- Added full `getrusage` support for Unix. [#95](https://github.com/elastic/gosigar/pull/95) - -## [0.7.0] - -### Added -- Added method stubs for process handling for operating system that are not supported - by gosigar. All methods return `ErrNotImplemented` on such systems. [#88](https://github.com/elastic/gosigar/pull/88) - -### Fixed -- Fix freebsd build by using the common version of Get(pid). [#91](https://github.com/elastic/gosigar/pull/91) - -### Changed -- Fixed issues in cgroup package by adding missing error checks and closing - file handles. [#92](https://github.com/elastic/gosigar/pull/92) - -## [0.6.0] - -### Added -- Added method stubs to enable compilation for operating systems that are not - supported by gosigar. All methods return `ErrNotImplemented` on these unsupported - operating systems. [#83](https://github.com/elastic/gosigar/pull/83) -- FreeBSD returns `ErrNotImplemented` for `ProcTime.Get`. [#83](https://github.com/elastic/gosigar/pull/83) - -### Changed -- OpenBSD returns `ErrNotImplemented` for `ProcTime.Get` instead of `nil`. [#83](https://github.com/elastic/gosigar/pull/83) -- Fixed incorrect `Mem.Used` calculation under linux. [#82](https://github.com/elastic/gosigar/pull/82) -- Fixed `ProcState` on Linux and FreeBSD when process names contain parentheses. [#81](https://github.com/elastic/gosigar/pull/81) - -### Removed -- Remove NetBSD build from sigar_unix.go as it is not supported by gosigar. [#83](https://github.com/elastic/gosigar/pull/83) - -## [0.5.0] - -### Changed -- Fixed Trim environment variables when comparing values in the test suite. [#79](https://github.com/elastic/gosigar/pull/79) -- Make `kern_procargs` more robust under darwin when we cannot retrieve - all the information about a process. [#78](https://github.com/elastic/gosigar/pull/78) - -## [0.4.0] - -### Changed -- Fixed Windows issue that caused a hang during `init()` if WMI wasn't ready. [#74](https://github.com/elastic/gosigar/pull/74) - -## [0.3.0] - -### Added -- Read `MemAvailable` value for kernel 3.14+ [#71](https://github.com/elastic/gosigar/pull/71) - -## [0.2.0] - -### Added -- Added `ErrCgroupsMissing` to indicate that /proc/cgroups is missing which is - an indicator that cgroups were disabled at compile time. [#64](https://github.com/elastic/gosigar/pull/64) - -### Changed -- Changed `cgroup.SupportedSubsystems()` to honor the "enabled" column in the - /proc/cgroups file. [#64](https://github.com/elastic/gosigar/pull/64) - -## [0.1.0] - -### Added -- Added `CpuList` implementation for Windows that returns CPU timing information - on a per CPU basis. [#55](https://github.com/elastic/gosigar/pull/55) -- Added `Uptime` implementation for Windows. [#55](https://github.com/elastic/gosigar/pull/55) -- Added `Swap` implementation for Windows based on page file metrics. [#55](https://github.com/elastic/gosigar/pull/55) -- Added support to `github.com/gosigar/sys/windows` for querying and enabling - privileges in a process token. -- Added utility code for interfacing with linux NETLINK_INET_DIAG. [#60](https://github.com/elastic/gosigar/pull/60) -- Added `ProcEnv` for getting a process's environment variables. [#61](https://github.com/elastic/gosigar/pull/61) - -### Changed -- Changed several `OpenProcess` calls on Windows to request the lowest possible - access privileges. [#50](https://github.com/elastic/gosigar/pull/50) -- Removed cgo usage from Windows code. -- Added OS version checks to `ProcArgs.Get` on Windows because the - `Win32_Process` WMI query is not available prior to Windows vista. On XP and - Windows 2003, this method returns `ErrNotImplemented`. [#55](https://github.com/elastic/gosigar/pull/55) - -### Fixed -- Fixed value of `Mem.ActualFree` and `Mem.ActualUsed` on Windows. [#49](https://github.com/elastic/gosigar/pull/49) -- Fixed `ProcTime.StartTime` on Windows to report value in milliseconds since - Unix epoch. [#51](https://github.com/elastic/gosigar/pull/51) -- Fixed `ProcStatus.PPID` value is wrong on Windows. [#55](https://github.com/elastic/gosigar/pull/55) -- Fixed `ProcStatus.Username` error on Windows XP [#56](https://github.com/elastic/gosigar/pull/56) - -[Unreleased]: https://github.com/elastic/gosigar/compare/v0.11.0...HEAD -[0.11.0]: https://github.com/elastic/gosigar/releases/tag/v0.11.0 -[0.10.5]: https://github.com/elastic/gosigar/releases/tag/v0.10.5 -[0.10.4]: https://github.com/elastic/gosigar/releases/tag/v0.10.4 -[0.10.3]: https://github.com/elastic/gosigar/releases/tag/v0.10.3 -[0.10.2]: https://github.com/elastic/gosigar/releases/tag/v0.10.2 -[0.10.1]: https://github.com/elastic/gosigar/releases/tag/v0.10.1 -[0.10.0]: https://github.com/elastic/gosigar/releases/tag/v0.10.0 -[0.9.0]: https://github.com/elastic/gosigar/releases/tag/v0.9.0 -[0.8.0]: https://github.com/elastic/gosigar/releases/tag/v0.8.0 -[0.7.0]: https://github.com/elastic/gosigar/releases/tag/v0.7.0 -[0.6.0]: https://github.com/elastic/gosigar/releases/tag/v0.6.0 -[0.5.0]: https://github.com/elastic/gosigar/releases/tag/v0.5.0 -[0.4.0]: https://github.com/elastic/gosigar/releases/tag/v0.4.0 -[0.3.0]: https://github.com/elastic/gosigar/releases/tag/v0.3.0 -[0.2.0]: https://github.com/elastic/gosigar/releases/tag/v0.2.0 -[0.1.0]: https://github.com/elastic/gosigar/releases/tag/v0.1.0 \ No newline at end of file diff --git a/cockroach/patches/github.com/elastic/gosigar/LICENSE b/cockroach/patches/github.com/elastic/gosigar/LICENSE deleted file mode 100644 index 11069ed..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor 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, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/cockroach/patches/github.com/elastic/gosigar/NOTICE b/cockroach/patches/github.com/elastic/gosigar/NOTICE deleted file mode 100644 index fda553b..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/NOTICE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) [2009-2011] VMware, Inc. All Rights Reserved. - -This product is licensed to you under the Apache License, Version 2.0 (the "License"). -You may not use this product except in compliance with the License. - -This product includes a number of subcomponents with -separate copyright notices and license terms. Your use of these -subcomponents is subject to the terms and conditions of the -subcomponent's license, as noted in the LICENSE file. \ No newline at end of file diff --git a/cockroach/patches/github.com/elastic/gosigar/README.md b/cockroach/patches/github.com/elastic/gosigar/README.md deleted file mode 100644 index 07b479d..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Go sigar [![Build Status](https://travis-ci.org/elastic/gosigar.svg?branch=master)](https://travis-ci.org/elastic/gosigar) [![Build status](https://ci.appveyor.com/api/projects/status/4yh6sa7u97ek5uib/branch/master?svg=true)](https://ci.appveyor.com/project/elastic-beats/gosigar/branch/master) - - -## Overview - -Go sigar is a golang implementation of the -[sigar API](https://github.com/hyperic/sigar). The Go version of -sigar has a very similar interface, but is being written from scratch -in pure go/cgo, rather than cgo bindings for libsigar. - -## Test drive - - $ go get github.com/elastic/gosigar - $ cd $GOPATH/src/github.com/elastic/gosigar/examples/ps - $ go build - $ ./ps - -## Supported platforms - -The features vary by operating system. - -| Feature | Linux | Darwin | Windows | OpenBSD | FreeBSD | AIX | -|-----------------|:-----:|:------:|:-------:|:-------:|:-------:|:-------:| -| Cpu | X | X | X | X | X | X | -| CpuList | X | X | | X | X | X | -| FDUsage | X | | | | X | | -| FileSystemList | X | X | X | X | X | X | -| FileSystemUsage | X | X | X | X | X | X | -| HugeTLBPages | X | | | | | | -| LoadAverage | X | X | | X | X | X | -| Mem | X | X | X | X | X | X | -| ProcArgs | X | X | X | | X | X | -| ProcEnv | X | X | | | X | X | -| ProcExe | X | X | | | X | X | -| ProcFDUsage | X | | | | X | | -| ProcList | X | X | X | | X | X | -| ProcMem | X | X | X | | X | X | -| ProcState | X | X | X | | X | X | -| ProcTime | X | X | X | | X | X | -| Rusage | X | | X | | | X | -| Swap | X | X | | X | X | X | -| Uptime | X | X | | X | X | X | - -## OS Specific Notes - -### FreeBSD - -Mount both `linprocfs` and `procfs` for compatability. Consider adding these -mounts to your `/etc/fstab` file so they are mounted automatically at boot. - -``` -sudo mount -t procfs proc /proc -sudo mkdir -p /compat/linux/proc -sudo mount -t linprocfs /dev/null /compat/linux/proc -``` - -## License - -Apache 2.0 diff --git a/cockroach/patches/github.com/elastic/gosigar/Vagrantfile b/cockroach/patches/github.com/elastic/gosigar/Vagrantfile deleted file mode 100644 index 6fd990c..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/Vagrantfile +++ /dev/null @@ -1,25 +0,0 @@ -# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! -VAGRANTFILE_API_VERSION = "2" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - config.vm.box = "hashicorp/precise64" - config.vm.provision "shell", inline: "mkdir -p /home/vagrant/go" - config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/cloudfoundry/gosigar" - config.vm.provision "shell", inline: "chown -R vagrant:vagrant /home/vagrant/go" - install_go = <<-BASH - set -e - -if [ ! -d "/usr/local/go" ]; then - cd /tmp && wget https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz - cd /usr/local - tar xvzf /tmp/go1.3.3.linux-amd64.tar.gz - echo 'export GOPATH=/home/vagrant/go; export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin' >> /home/vagrant/.bashrc -fi -export GOPATH=/home/vagrant/go -export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin -/usr/local/go/bin/go get -u github.com/onsi/ginkgo/ginkgo -/usr/local/go/bin/go get -u github.com/onsi/gomega; -BASH - config.vm.provision "shell", inline: 'apt-get install -y git-core' - config.vm.provision "shell", inline: install_go -end diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/blkio.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/blkio.go deleted file mode 100644 index 7d13dbd..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/blkio.go +++ /dev/null @@ -1,293 +0,0 @@ -package cgroup - -import ( - "bufio" - "os" - "path/filepath" - "strconv" - "strings" - "unicode" -) - -// BlockIOSubsystem contains limits and metrics from the "blkio" subsystem. The -// blkio subsystem controls and monitors access to I/O on block devices by tasks -// in a cgroup. -// -// https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt -type BlockIOSubsystem struct { - Metadata - Throttle ThrottlePolicy `json:"throttle,omitempty"` // Throttle limits for upper IO rates and metrics. - //CFQ CFQScheduler `json:"cfq,omitempty"` // Completely fair queue scheduler limits and metrics. -} - -// CFQScheduler contains limits and metrics for the proportional weight time -// based division of disk policy. It is implemented in CFQ. Hence this policy -// takes effect only on leaf nodes when CFQ is being used. -// -// https://www.kernel.org/doc/Documentation/block/cfq-iosched.txt -type CFQScheduler struct { - Weight uint64 `json:"weight"` // Default weight for all devices unless overridden. Allowed range of weights is from 10 to 1000. - Devices []CFQDevice `json:"devices,omitempty"` -} - -// CFQDevice contains CFQ limits and metrics associated with a single device. -type CFQDevice struct { - DeviceID DeviceID `json:"device_id"` // ID of the device. - - // Proportional weight for the device. 0 means a per device weight is not set and - // that the blkio.weight value is used. - Weight uint64 `json:"weight"` - - TimeMs uint64 `json:"time_ms"` // Disk time allocated to cgroup per device in milliseconds. - Sectors uint64 `json:"sectors"` // Number of sectors transferred to/from disk by the cgroup. - Bytes OperationValues `json:"io_service_bytes"` // Number of bytes transferred to/from the disk by the cgroup. - IOs OperationValues `json:"io_serviced"` // Number of IO operations issued to the disk by the cgroup. - ServiceTimeNanos OperationValues `json:"io_service_time"` // Amount of time between request dispatch and request completion for the IOs done by this cgroup. - WaitTimeNanos OperationValues `json:"io_wait_time"` // Amount of time the IOs for this cgroup spent waiting in the scheduler queues for service. - Merges OperationValues `json:"io_merged"` // Total number of bios/requests merged into requests belonging to this cgroup. -} - -// ThrottlePolicy contains the upper IO limits and metrics for devices used -// by the cgroup. -type ThrottlePolicy struct { - Devices []ThrottleDevice `json:"devices,omitempty"` // Device centric view of limits and metrics. - TotalBytes uint64 `json:"total_io_service_bytes"` // Total number of bytes serviced by all devices. - TotalIOs uint64 `json:"total_io_serviced"` // Total number of IO operations serviced by all devices. -} - -// ThrottleDevice contains throttle limits and metrics associated with a single device. -type ThrottleDevice struct { - DeviceID DeviceID `json:"device_id"` // ID of the device. - - ReadLimitBPS uint64 `json:"read_bps_device"` // Read limit in bytes per second (BPS). Zero means no limit. - WriteLimitBPS uint64 `json:"write_bps_device"` // Write limit in bytes per second (BPS). Zero mean no limit. - ReadLimitIOPS uint64 `json:"read_iops_device"` // Read limit in IOPS. Zero means no limit. - WriteLimitIOPS uint64 `json:"write_iops_device"` // Write limit in IOPS. Zero means no limit. - - Bytes OperationValues `json:"io_service_bytes"` // Number of bytes transferred to/from the disk by the cgroup. - IOs OperationValues `json:"io_serviced"` // Number of IO operations issued to the disk by the cgroup. -} - -// OperationValues contains the I/O limits or metrics associated with read, -// write, sync, and async operations. -type OperationValues struct { - Read uint64 `json:"read"` - Write uint64 `json:"write"` - Async uint64 `json:"async"` - Sync uint64 `json:"sync"` -} - -// DeviceID identifies a Linux block device. -type DeviceID struct { - Major uint64 - Minor uint64 -} - -// blkioValue holds a single blkio value associated with a device. -type blkioValue struct { - DeviceID - Operation string - Value uint64 -} - -// get reads metrics from the "blkio" subsystem. path is the filepath to the -// cgroup hierarchy to read. -func (blkio *BlockIOSubsystem) get(path string) error { - if err := blkioThrottle(path, blkio); err != nil { - return err - } - - // TODO(akroh): Implement reading for the CFQ values. - - return nil -} - -// blkioThrottle reads all of the limits and metrics associated with blkio -// throttling policy. -func blkioThrottle(path string, blkio *BlockIOSubsystem) error { - devices := map[DeviceID]*ThrottleDevice{} - - getDevice := func(id DeviceID) *ThrottleDevice { - td := devices[id] - if td == nil { - td = &ThrottleDevice{DeviceID: id} - devices[id] = td - } - return td - } - - values, err := readBlkioValues(path, "blkio.throttle.io_service_bytes") - if err != nil { - return err - } - if values != nil { - for id, opValues := range collectOpValues(values) { - getDevice(id).Bytes = *opValues - } - } - - values, err = readBlkioValues(path, "blkio.throttle.io_serviced") - if err != nil { - return err - } - if values != nil { - for id, opValues := range collectOpValues(values) { - getDevice(id).IOs = *opValues - } - } - - values, err = readBlkioValues(path, "blkio.throttle.read_bps_device") - if err != nil { - return err - } - if values != nil { - for _, bv := range values { - getDevice(bv.DeviceID).ReadLimitBPS = bv.Value - } - } - - values, err = readBlkioValues(path, "blkio.throttle.write_bps_device") - if err != nil { - return err - } - if values != nil { - for _, bv := range values { - getDevice(bv.DeviceID).WriteLimitBPS = bv.Value - } - } - - values, err = readBlkioValues(path, "blkio.throttle.read_iops_device") - if err != nil { - return err - } - if values != nil { - for _, bv := range values { - getDevice(bv.DeviceID).ReadLimitIOPS = bv.Value - } - } - - values, err = readBlkioValues(path, "blkio.throttle.write_iops_device") - if err != nil { - return err - } - if values != nil { - for _, bv := range values { - getDevice(bv.DeviceID).WriteLimitIOPS = bv.Value - } - } - - blkio.Throttle.Devices = make([]ThrottleDevice, 0, len(devices)) - for _, dev := range devices { - blkio.Throttle.Devices = append(blkio.Throttle.Devices, *dev) - blkio.Throttle.TotalBytes += dev.Bytes.Read + dev.Bytes.Write - blkio.Throttle.TotalIOs += dev.IOs.Read + dev.IOs.Write - } - - return nil -} - -// collectOpValues collects the discreet I/O values (e.g. read, write, sync, -// async) for a given device into a single OperationValues object. It returns a -// mapping of device ID to OperationValues. -func collectOpValues(values []blkioValue) map[DeviceID]*OperationValues { - opValues := map[DeviceID]*OperationValues{} - for _, bv := range values { - opValue := opValues[bv.DeviceID] - if opValue == nil { - opValue = &OperationValues{} - opValues[bv.DeviceID] = opValue - } - - switch bv.Operation { - case "read": - opValue.Read = bv.Value - case "write": - opValue.Write = bv.Value - case "async": - opValue.Async = bv.Value - case "sync": - opValue.Sync = bv.Value - } - } - - return opValues -} - -// readDeviceValues reads values from a single blkio file. -// It expects to read values like "245:1 read 18880" or "254:1 1909". It returns -// an array containing an entry for each valid line read. -func readBlkioValues(path ...string) ([]blkioValue, error) { - f, err := os.Open(filepath.Join(path...)) - if err != nil { - if os.IsNotExist(err) { - return nil, nil - } - return nil, err - } - defer f.Close() - - var values []blkioValue - sc := bufio.NewScanner(f) - for sc.Scan() { - line := strings.TrimSpace(sc.Text()) - if len(line) == 0 { - continue - } - // Valid lines start with a device ID. - if !unicode.IsNumber(rune(line[0])) { - continue - } - - v, err := parseBlkioValue(sc.Text()) - if err != nil { - return nil, err - } - - values = append(values, v) - } - - return values, sc.Err() -} - -func isColonOrSpace(r rune) bool { - return unicode.IsSpace(r) || r == ':' -} - -func parseBlkioValue(line string) (blkioValue, error) { - fields := strings.FieldsFunc(line, isColonOrSpace) - if len(fields) != 3 && len(fields) != 4 { - return blkioValue{}, ErrInvalidFormat - } - - major, err := strconv.ParseUint(fields[0], 10, 64) - if err != nil { - return blkioValue{}, err - } - - minor, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - return blkioValue{}, err - } - - var value uint64 - var operation string - if len(fields) == 3 { - value, err = parseUint([]byte(fields[2])) - if err != nil { - return blkioValue{}, err - } - } else { - operation = strings.ToLower(fields[2]) - - value, err = parseUint([]byte(fields[3])) - if err != nil { - return blkioValue{}, err - } - } - - return blkioValue{ - DeviceID: DeviceID{major, minor}, - Operation: operation, - Value: value, - }, nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/blkio_test.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/blkio_test.go deleted file mode 100644 index 8306001..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/blkio_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package cgroup - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/assert" -) - -const blkioPath = "testdata/docker/sys/fs/cgroup/blkio/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242" - -func TestParseBlkioValueWithOp(t *testing.T) { - line := `253:1 Async 1638912` - opValue, err := parseBlkioValue(line) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(253), opValue.Major) - assert.Equal(t, uint64(1), opValue.Minor) - assert.Equal(t, "async", opValue.Operation) - assert.Equal(t, uint64(1638912), opValue.Value) -} - -func TestParseBlkioValueWithoutOp(t *testing.T) { - line := `1:2 10088` - opValue, err := parseBlkioValue(line) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(1), opValue.Major) - assert.Equal(t, uint64(2), opValue.Minor) - assert.Equal(t, "", opValue.Operation) - assert.Equal(t, uint64(10088), opValue.Value) -} - -func TestBlkioThrottle(t *testing.T) { - blkio := BlockIOSubsystem{} - err := blkioThrottle(blkioPath, &blkio) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(46), blkio.Throttle.TotalIOs) - assert.Equal(t, uint64(1648128), blkio.Throttle.TotalBytes) - assert.Len(t, blkio.Throttle.Devices, 3) - - for _, device := range blkio.Throttle.Devices { - if device.DeviceID.Major == 7 && device.DeviceID.Minor == 0 { - assert.Equal(t, uint64(1000), device.ReadLimitBPS) - assert.Equal(t, uint64(2000), device.ReadLimitIOPS) - assert.Equal(t, uint64(3000), device.WriteLimitBPS) - assert.Equal(t, uint64(4000), device.WriteLimitIOPS) - - assert.Equal(t, uint64(4608), device.Bytes.Read) - assert.Equal(t, uint64(0), device.Bytes.Write) - assert.Equal(t, uint64(4608), device.Bytes.Async) - assert.Equal(t, uint64(0), device.Bytes.Sync) - - assert.Equal(t, uint64(2), device.IOs.Read) - assert.Equal(t, uint64(0), device.IOs.Write) - assert.Equal(t, uint64(2), device.IOs.Async) - assert.Equal(t, uint64(0), device.IOs.Sync) - } - } -} - -func TestBlockIOSubsystemGet(t *testing.T) { - blkio := BlockIOSubsystem{} - if err := blkio.get(blkioPath); err != nil { - t.Fatal(err) - } - - assert.True(t, len(blkio.Throttle.Devices) > 0) -} - -func TestBlockIOSubsystemJSON(t *testing.T) { - blkio := BlockIOSubsystem{} - if err := blkio.get(blkioPath); err != nil { - t.Fatal(err) - } - - json, err := json.MarshalIndent(blkio, "", " ") - if err != nil { - t.Fatal(err) - } - - t.Log(string(json)) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpu.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/cpu.go deleted file mode 100644 index d2c5acc..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpu.go +++ /dev/null @@ -1,139 +0,0 @@ -package cgroup - -import ( - "bufio" - "os" - "path/filepath" -) - -// CPUSubsystem contains metrics and limits from the "cpu" subsystem. This -// subsystem is used to guarantee a minimum number of cpu shares to the cgroup -// when the system is busy. This subsystem does not track CPU usage, for that -// information see the "cpuacct" subsystem. -type CPUSubsystem struct { - Metadata - // Completely Fair Scheduler (CFS) settings. - CFS CFS `json:"cfs,omitempty"` - // Real-time (RT) Scheduler settings. - RT RT `json:"rt,omitempty"` - // CPU time statistics for tasks in this cgroup. - Stats ThrottleStats `json:"stats,omitempty"` -} - -// RT contains the tunable parameters for the real-time scheduler. -type RT struct { - // Period of time in microseconds for how regularly the cgroup's access to - // CPU resources should be reallocated. - PeriodMicros uint64 `json:"period_us"` - // Period of time in microseconds for the longest continuous period in which - // the tasks in the cgroup have access to CPU resources. - RuntimeMicros uint64 `json:"quota_us"` -} - -// CFS contains the tunable parameters for the completely fair scheduler. -type CFS struct { - // Period of time in microseconds for how regularly the cgroup's access to - // CPU resources should be reallocated. - PeriodMicros uint64 `json:"period_us"` - // Total amount of time in microseconds for which all tasks in the cgroup - // can run during one period. - QuotaMicros uint64 `json:"quota_us"` - // Relative share of CPU time available to tasks the cgroup. The value is - // an integer greater than or equal to 2. - Shares uint64 `json:"shares"` -} - -// ThrottleStats contains stats that indicate the extent to which this cgroup's -// CPU usage was throttled. -type ThrottleStats struct { - // Number of periods with throttling active. - Periods uint64 `json:"periods,omitempty"` - // Number of periods when the cgroup hit its throttling limit. - ThrottledPeriods uint64 `json:"throttled_periods,omitempty"` - // Aggregate time the cgroup was throttled for in nanoseconds. - ThrottledTimeNanos uint64 `json:"throttled_nanos,omitempty"` -} - -// get reads metrics from the "cpu" subsystem. path is the filepath to the -// cgroup hierarchy to read. -func (cpu *CPUSubsystem) get(path string) error { - if err := cpuCFS(path, cpu); err != nil { - return err - } - - if err := cpuRT(path, cpu); err != nil { - return err - } - - if err := cpuStat(path, cpu); err != nil { - return err - } - - return nil -} - -func cpuStat(path string, cpu *CPUSubsystem) error { - f, err := os.Open(filepath.Join(path, "cpu.stat")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - - sc := bufio.NewScanner(f) - for sc.Scan() { - t, v, err := parseCgroupParamKeyValue(sc.Text()) - if err != nil { - return err - } - switch t { - case "nr_periods": - cpu.Stats.Periods = v - - case "nr_throttled": - cpu.Stats.ThrottledPeriods = v - - case "throttled_time": - cpu.Stats.ThrottledTimeNanos = v - } - } - - return sc.Err() -} - -func cpuCFS(path string, cpu *CPUSubsystem) error { - var err error - cpu.CFS.PeriodMicros, err = parseUintFromFile(path, "cpu.cfs_period_us") - if err != nil { - return err - } - - cpu.CFS.QuotaMicros, err = parseUintFromFile(path, "cpu.cfs_quota_us") - if err != nil { - return err - } - - cpu.CFS.Shares, err = parseUintFromFile(path, "cpu.shares") - if err != nil { - return err - } - - return nil -} - -func cpuRT(path string, cpu *CPUSubsystem) error { - var err error - cpu.RT.PeriodMicros, err = parseUintFromFile(path, "cpu.rt_period_us") - if err != nil { - return err - } - - cpu.RT.RuntimeMicros, err = parseUintFromFile(path, "cpu.rt_runtime_us") - if err != nil { - return err - } - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpu_test.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/cpu_test.go deleted file mode 100644 index 3c8b22b..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpu_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package cgroup - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/assert" -) - -const cpuPath = "testdata/docker/sys/fs/cgroup/cpu/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242" - -func TestCpuStats(t *testing.T) { - cpu := CPUSubsystem{} - if err := cpuStat(cpuPath, &cpu); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(769021), cpu.Stats.Periods) - assert.Equal(t, uint64(1046), cpu.Stats.ThrottledPeriods) - assert.Equal(t, uint64(352597023453), cpu.Stats.ThrottledTimeNanos) -} - -func TestCpuCFS(t *testing.T) { - cpu := CPUSubsystem{} - if err := cpuCFS(cpuPath, &cpu); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(100000), cpu.CFS.PeriodMicros) - assert.Equal(t, uint64(0), cpu.CFS.QuotaMicros) // -1 is changed to 0. - assert.Equal(t, uint64(1024), cpu.CFS.Shares) -} - -func TestCpuRT(t *testing.T) { - cpu := CPUSubsystem{} - if err := cpuRT(cpuPath, &cpu); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(1000000), cpu.RT.PeriodMicros) - assert.Equal(t, uint64(0), cpu.RT.RuntimeMicros) -} - -func TestCpuSubsystemGet(t *testing.T) { - cpu := CPUSubsystem{} - if err := cpu.get(cpuPath); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(769021), cpu.Stats.Periods) - assert.Equal(t, uint64(100000), cpu.CFS.PeriodMicros) - assert.Equal(t, uint64(1000000), cpu.RT.PeriodMicros) -} - -func TestCpuSubsystemJSON(t *testing.T) { - cpu := CPUSubsystem{} - if err := cpu.get(cpuPath); err != nil { - t.Fatal(err) - } - - json, err := json.MarshalIndent(cpu, "", " ") - if err != nil { - t.Fatal(err) - } - - t.Log(string(json)) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpuacct.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/cpuacct.go deleted file mode 100644 index 31beae1..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpuacct.go +++ /dev/null @@ -1,112 +0,0 @@ -package cgroup - -import ( - "bufio" - "bytes" - "io/ioutil" - "os" - "path/filepath" - "time" - - "github.com/elastic/gosigar/sys/linux" -) - -var clockTicks = uint64(linux.GetClockTicks()) - -// CPUAccountingSubsystem contains metrics from the "cpuacct" subsystem. -type CPUAccountingSubsystem struct { - Metadata - TotalNanos uint64 `json:"total_nanos"` - UsagePerCPU []uint64 `json:"usage_percpu_nanos"` - // CPU time statistics for tasks in this cgroup. - Stats CPUAccountingStats `json:"stats,omitempty"` -} - -// CPUAccountingStats contains the stats reported from the cpuacct subsystem. -type CPUAccountingStats struct { - UserNanos uint64 `json:"user_nanos"` - SystemNanos uint64 `json:"system_nanos"` -} - -// get reads metrics from the "cpuacct" subsystem. path is the filepath to the -// cgroup hierarchy to read. -func (cpuacct *CPUAccountingSubsystem) get(path string) error { - if err := cpuacctStat(path, cpuacct); err != nil { - return err - } - - if err := cpuacctUsage(path, cpuacct); err != nil { - return err - } - - if err := cpuacctUsagePerCPU(path, cpuacct); err != nil { - return err - } - - return nil -} - -func cpuacctStat(path string, cpuacct *CPUAccountingSubsystem) error { - f, err := os.Open(filepath.Join(path, "cpuacct.stat")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - - sc := bufio.NewScanner(f) - for sc.Scan() { - t, v, err := parseCgroupParamKeyValue(sc.Text()) - if err != nil { - return err - } - switch t { - case "user": - cpuacct.Stats.UserNanos = convertJiffiesToNanos(v) - case "system": - cpuacct.Stats.SystemNanos = convertJiffiesToNanos(v) - } - } - - return sc.Err() -} - -func cpuacctUsage(path string, cpuacct *CPUAccountingSubsystem) error { - var err error - cpuacct.TotalNanos, err = parseUintFromFile(path, "cpuacct.usage") - if err != nil { - return err - } - - return nil -} - -func cpuacctUsagePerCPU(path string, cpuacct *CPUAccountingSubsystem) error { - contents, err := ioutil.ReadFile(filepath.Join(path, "cpuacct.usage_percpu")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - - var values []uint64 - usages := bytes.Fields(contents) - for _, usage := range usages { - value, err := parseUint(usage) - if err != nil { - return err - } - - values = append(values, value) - } - cpuacct.UsagePerCPU = values - - return nil -} - -func convertJiffiesToNanos(j uint64) uint64 { - return (j * uint64(time.Second)) / clockTicks -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpuacct_test.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/cpuacct_test.go deleted file mode 100644 index 05711db..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/cpuacct_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package cgroup - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/assert" -) - -const cpuacctPath = "testdata/docker/sys/fs/cgroup/cpuacct/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242" - -func TestCPUAccountingStats(t *testing.T) { - cpuacct := CPUAccountingSubsystem{} - if err := cpuacctStat(cpuacctPath, &cpuacct); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(61950000000), cpuacct.Stats.UserNanos) - assert.Equal(t, uint64(7730000000), cpuacct.Stats.SystemNanos) -} - -func TestCpuacctUsage(t *testing.T) { - cpuacct := CPUAccountingSubsystem{} - if err := cpuacctUsage(cpuacctPath, &cpuacct); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(95996653175), cpuacct.TotalNanos) -} - -func TestCpuacctUsagePerCPU(t *testing.T) { - cpuacct := CPUAccountingSubsystem{} - if err := cpuacctUsagePerCPU(cpuacctPath, &cpuacct); err != nil { - t.Fatal(err) - } - - assert.Equal(t, []uint64{26571825468, 23185259690, 24300973729, 21937433730}, cpuacct.UsagePerCPU) -} - -func TestCPUAccountingSubsystem_Get(t *testing.T) { - cpuacct := CPUAccountingSubsystem{} - if err := cpuacct.get(cpuacctPath); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(61950000000), cpuacct.Stats.UserNanos) - assert.Equal(t, uint64(95996653175), cpuacct.TotalNanos) - assert.Len(t, cpuacct.UsagePerCPU, 4) -} - -func TestCPUAccountingSubsystemJSON(t *testing.T) { - cpuacct := CPUAccountingSubsystem{} - if err := cpuacct.get(cpuacctPath); err != nil { - t.Fatal(err) - } - - json, err := json.MarshalIndent(cpuacct, "", " ") - if err != nil { - t.Fatal(err) - } - - t.Log(string(json)) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/doc.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/doc.go deleted file mode 100644 index 25a81a8..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package cgroup reads metrics and other tunable parameters associated with -// control groups, a Linux kernel feature for grouping tasks to track and limit -// resource usage. -// -// Terminology -// -// A cgroup is a collection of processes that are bound to a set of limits. -// -// A subsystem is a kernel component the modifies the behavior of processes -// in a cgroup. -package cgroup diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/memory.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/memory.go deleted file mode 100644 index 320bd89..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/memory.go +++ /dev/null @@ -1,168 +0,0 @@ -package cgroup - -import ( - "bufio" - "os" - "path/filepath" -) - -// MemorySubsystem contains the metrics and limits from the "memory" subsystem. -type MemorySubsystem struct { - Metadata - Mem MemoryData `json:"mem"` // Memory usage by tasks in this cgroup. - MemSwap MemoryData `json:"memsw"` // Memory plus swap usage by tasks in this cgroup. - Kernel MemoryData `json:"kmem"` // Kernel memory used by tasks in this cgroup. - KernelTCP MemoryData `json:"kmem_tcp"` // Kernel TCP buffer memory used by tasks in this cgroup. - Stats MemoryStat `json:"stats"` // A wide range of memory statistics. -} - -// MemoryData groups related memory usage metrics and limits. -type MemoryData struct { - Usage uint64 `json:"usage"` // Usage in bytes. - MaxUsage uint64 `json:"max_usage"` // Max usage in bytes. - Limit uint64 `json:"limit"` // Limit in bytes. - FailCount uint64 `json:"failure_count"` // Number of times the memory limit has been reached. -} - -// MemoryStat contains various memory statistics and accounting information -// associated with a cgroup. -type MemoryStat struct { - // Page cache, including tmpfs (shmem), in bytes. - Cache uint64 `json:"cache"` - // Anonymous and swap cache, not including tmpfs (shmem), in bytes. - RSS uint64 `json:"rss"` - // Anonymous transparent hugepages in bytes. - RSSHuge uint64 `json:"rss_huge"` - // Size of memory-mapped mapped files, including tmpfs (shmem), in bytes. - MappedFile uint64 `json:"mapped_file"` - // Number of pages paged into memory. - PagesIn uint64 `json:"pgpgin"` - // Number of pages paged out of memory. - PagesOut uint64 `json:"pgpgout"` - // Number of times a task in the cgroup triggered a page fault. - PageFaults uint64 `json:"pgfault"` - // Number of times a task in the cgroup triggered a major page fault. - MajorPageFaults uint64 `json:"pgmajfault"` - // Swap usage in bytes. - Swap uint64 `json:"swap"` - // Anonymous and swap cache on active least-recently-used (LRU) list, including tmpfs (shmem), in bytes. - ActiveAnon uint64 `json:"active_anon"` - // Anonymous and swap cache on inactive LRU list, including tmpfs (shmem), in bytes. - InactiveAnon uint64 `json:"inactive_anon"` - // File-backed memory on active LRU list, in bytes. - ActiveFile uint64 `json:"active_file"` - // File-backed memory on inactive LRU list, in bytes. - InactiveFile uint64 `json:"inactive_file"` - // Memory that cannot be reclaimed, in bytes. - Unevictable uint64 `json:"unevictable"` - // Memory limit for the hierarchy that contains the memory cgroup, in bytes. - HierarchicalMemoryLimit uint64 `json:"hierarchical_memory_limit"` - // Memory plus swap limit for the hierarchy that contains the memory cgroup, in bytes. - HierarchicalMemswLimit uint64 `json:"hierarchical_memsw_limit"` -} - -// get reads metrics from the "memory" subsystem. path is the filepath to the -// cgroup hierarchy to read. -func (mem *MemorySubsystem) get(path string) error { - if err := memoryData(path, "memory", &mem.Mem); err != nil { - return err - } - - if err := memoryData(path, "memory.memsw", &mem.MemSwap); err != nil { - return err - } - - if err := memoryData(path, "memory.kmem", &mem.Kernel); err != nil { - return err - } - - if err := memoryData(path, "memory.kmem.tcp", &mem.KernelTCP); err != nil { - return err - } - - if err := memoryStats(path, mem); err != nil { - return err - } - - return nil -} - -func memoryData(path, prefix string, data *MemoryData) error { - var err error - data.Usage, err = parseUintFromFile(path, prefix+".usage_in_bytes") - if err != nil { - return err - } - - data.MaxUsage, err = parseUintFromFile(path, prefix+".max_usage_in_bytes") - if err != nil { - return err - } - - data.Limit, err = parseUintFromFile(path, prefix+".limit_in_bytes") - if err != nil { - return err - } - - data.FailCount, err = parseUintFromFile(path, prefix+".failcnt") - if err != nil { - return err - } - - return nil -} - -func memoryStats(path string, mem *MemorySubsystem) error { - f, err := os.Open(filepath.Join(path, "memory.stat")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - - sc := bufio.NewScanner(f) - for sc.Scan() { - t, v, err := parseCgroupParamKeyValue(sc.Text()) - if err != nil { - return err - } - switch t { - case "cache": - mem.Stats.Cache = v - case "rss": - mem.Stats.RSS = v - case "rss_huge": - mem.Stats.RSSHuge = v - case "mapped_file": - mem.Stats.MappedFile = v - case "pgpgin": - mem.Stats.PagesIn = v - case "pgpgout": - mem.Stats.PagesOut = v - case "pgfault": - mem.Stats.PageFaults = v - case "pgmajfault": - mem.Stats.MajorPageFaults = v - case "swap": - mem.Stats.Swap = v - case "active_anon": - mem.Stats.ActiveAnon = v - case "inactive_anon": - mem.Stats.InactiveAnon = v - case "active_file": - mem.Stats.ActiveFile = v - case "inactive_file": - mem.Stats.InactiveFile = v - case "unevictable": - mem.Stats.Unevictable = v - case "hierarchical_memory_limit": - mem.Stats.HierarchicalMemoryLimit = v - case "hierarchical_memsw_limit": - mem.Stats.HierarchicalMemswLimit = v - } - } - - return sc.Err() -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/memory_test.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/memory_test.go deleted file mode 100644 index 4e9e375..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/memory_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package cgroup - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/assert" -) - -const memoryPath = "testdata/docker/sys/fs/cgroup/memory/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242" - -func TestMemoryStat(t *testing.T) { - mem := MemorySubsystem{} - if err := memoryStats(memoryPath, &mem); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(65101824), mem.Stats.Cache) - assert.Equal(t, uint64(230662144), mem.Stats.RSS) - assert.Equal(t, uint64(174063616), mem.Stats.RSSHuge) - assert.Equal(t, uint64(17633280), mem.Stats.MappedFile) - assert.Equal(t, uint64(0), mem.Stats.Swap) - assert.Equal(t, uint64(103258), mem.Stats.PagesIn) - assert.Equal(t, uint64(77551), mem.Stats.PagesOut) - assert.Equal(t, uint64(91651), mem.Stats.PageFaults) - assert.Equal(t, uint64(166), mem.Stats.MajorPageFaults) - assert.Equal(t, uint64(28672), mem.Stats.InactiveAnon) - assert.Equal(t, uint64(230780928), mem.Stats.ActiveAnon) - assert.Equal(t, uint64(40108032), mem.Stats.InactiveFile) - assert.Equal(t, uint64(24813568), mem.Stats.ActiveFile) - assert.Equal(t, uint64(0), mem.Stats.Unevictable) - assert.Equal(t, uint64(9223372036854771712), mem.Stats.HierarchicalMemoryLimit) - assert.Equal(t, uint64(9223372036854771712), mem.Stats.HierarchicalMemswLimit) -} - -func TestMemoryData(t *testing.T) { - usage := MemoryData{} - if err := memoryData(memoryPath, "memory", &usage); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(295997440), usage.Usage) - assert.Equal(t, uint64(298532864), usage.MaxUsage) - assert.Equal(t, uint64(9223372036854771712), usage.Limit) - assert.Equal(t, uint64(0), usage.FailCount) -} - -func TestMemoryDataSwap(t *testing.T) { - usage := MemoryData{} - if err := memoryData(memoryPath, "memory.memsw", &usage); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(295997440), usage.Usage) - assert.Equal(t, uint64(298532864), usage.MaxUsage) - assert.Equal(t, uint64(9223372036854771712), usage.Limit) - assert.Equal(t, uint64(0), usage.FailCount) -} - -func TestMemoryDataKernel(t *testing.T) { - usage := MemoryData{} - if err := memoryData(memoryPath, "memory.kmem", &usage); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(40), usage.Usage) - assert.Equal(t, uint64(50), usage.MaxUsage) - assert.Equal(t, uint64(9223372036854771712), usage.Limit) - assert.Equal(t, uint64(0), usage.FailCount) -} - -func TestMemoryDataKernelTCP(t *testing.T) { - usage := MemoryData{} - if err := memoryData(memoryPath, "memory.kmem.tcp", &usage); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(10), usage.Usage) - assert.Equal(t, uint64(70), usage.MaxUsage) - assert.Equal(t, uint64(9223372036854771712), usage.Limit) - assert.Equal(t, uint64(0), usage.FailCount) -} - -func TestMemorySubsystemGet(t *testing.T) { - mem := MemorySubsystem{} - if err := mem.get(memoryPath); err != nil { - t.Fatal(err) - } - - assert.Equal(t, uint64(65101824), mem.Stats.Cache) - assert.Equal(t, uint64(295997440), mem.Mem.Usage) - assert.Equal(t, uint64(295997440), mem.MemSwap.Usage) - assert.Equal(t, uint64(40), mem.Kernel.Usage) - assert.Equal(t, uint64(10), mem.KernelTCP.Usage) -} - -func TestMemorySubsystemJSON(t *testing.T) { - mem := MemorySubsystem{} - if err := mem.get(memoryPath); err != nil { - t.Fatal(err) - } - - json, err := json.MarshalIndent(mem, "", " ") - if err != nil { - t.Fatal(err) - } - - t.Log(string(json)) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/reader.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/reader.go deleted file mode 100644 index 894061d..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/reader.go +++ /dev/null @@ -1,162 +0,0 @@ -package cgroup - -import ( - "path/filepath" -) - -// Stats contains metrics and limits from each of the cgroup subsystems. -type Stats struct { - Metadata - CPU *CPUSubsystem `json:"cpu"` - CPUAccounting *CPUAccountingSubsystem `json:"cpuacct"` - Memory *MemorySubsystem `json:"memory"` - BlockIO *BlockIOSubsystem `json:"blkio"` -} - -// Metadata contains metadata associated with cgroup stats. -type Metadata struct { - ID string `json:"id,omitempty"` // ID of the cgroup. - Path string `json:"path,omitempty"` // Path to the cgroup relative to the cgroup subsystem's mountpoint. -} - -type mount struct { - subsystem string // Subsystem name (e.g. cpuacct). - mountpoint string // Mountpoint of the subsystem (e.g. /cgroup/cpuacct). - path string // Relative path to the cgroup (e.g. /docker/). - id string // ID of the cgroup. - fullPath string // Absolute path to the cgroup. It's the mountpoint joined with the path. -} - -// Reader reads cgroup metrics and limits. -type Reader struct { - // Mountpoint of the root filesystem. Defaults to / if not set. This can be - // useful for example if you mount / as /rootfs inside of a container. - rootfsMountpoint string - ignoreRootCgroups bool // Ignore a cgroup when its path is "/". - cgroupMountpoints map[string]string // Mountpoints for each subsystem (e.g. cpu, cpuacct, memory, blkio). -} - -// NewReader creates and returns a new Reader. -func NewReader(rootfsMountpoint string, ignoreRootCgroups bool) (*Reader, error) { - if rootfsMountpoint == "" { - rootfsMountpoint = "/" - } - - // Determine what subsystems are supported by the kernel. - subsystems, err := SupportedSubsystems(rootfsMountpoint) - if err != nil { - return nil, err - } - - // Locate the mountpoints of those subsystems. - mountpoints, err := SubsystemMountpoints(rootfsMountpoint, subsystems) - if err != nil { - return nil, err - } - - return &Reader{ - rootfsMountpoint: rootfsMountpoint, - ignoreRootCgroups: ignoreRootCgroups, - cgroupMountpoints: mountpoints, - }, nil -} - -// GetStatsForProcess returns cgroup metrics and limits associated with a process. -func (r *Reader) GetStatsForProcess(pid int) (*Stats, error) { - // Read /proc/[pid]/cgroup to get the paths to the cgroup metrics. - paths, err := ProcessCgroupPaths(r.rootfsMountpoint, pid) - if err != nil { - return nil, err - } - - // Build the full path for the subsystems we are interested in. - mounts := map[string]mount{} - for _, interestedSubsystem := range []string{"blkio", "cpu", "cpuacct", "memory"} { - path, found := paths[interestedSubsystem] - if !found { - continue - } - - if path == "/" && r.ignoreRootCgroups { - continue - } - - subsystemMount, found := r.cgroupMountpoints[interestedSubsystem] - if !found { - continue - } - - mounts[interestedSubsystem] = mount{ - subsystem: interestedSubsystem, - mountpoint: subsystemMount, - path: path, - id: filepath.Base(path), - fullPath: filepath.Join(subsystemMount, path), - } - } - - stats := Stats{Metadata: getCommonCgroupMetadata(mounts)} - - // Collect stats from each cgroup subsystem associated with the task. - if mount, found := mounts["blkio"]; found { - stats.BlockIO = &BlockIOSubsystem{} - err := stats.BlockIO.get(mount.fullPath) - if err != nil { - return nil, err - } - stats.BlockIO.Metadata.ID = mount.id - stats.BlockIO.Metadata.Path = mount.path - } - if mount, found := mounts["cpu"]; found { - stats.CPU = &CPUSubsystem{} - err := stats.CPU.get(mount.fullPath) - if err != nil { - return nil, err - } - stats.CPU.Metadata.ID = mount.id - stats.CPU.Metadata.Path = mount.path - } - if mount, found := mounts["cpuacct"]; found { - stats.CPUAccounting = &CPUAccountingSubsystem{} - err := stats.CPUAccounting.get(mount.fullPath) - if err != nil { - return nil, err - } - stats.CPUAccounting.Metadata.ID = mount.id - stats.CPUAccounting.Metadata.Path = mount.path - } - if mount, found := mounts["memory"]; found { - stats.Memory = &MemorySubsystem{} - err := stats.Memory.get(mount.fullPath) - if err != nil { - return nil, err - } - stats.Memory.Metadata.ID = mount.id - stats.Memory.Metadata.Path = mount.path - } - - // Return nil if no metrics were collected. - if stats.BlockIO == nil && stats.CPU == nil && stats.CPUAccounting == nil && stats.Memory == nil { - return nil, nil - } - - return &stats, nil -} - -// getCommonCgroupMetadata returns Metadata containing the cgroup path and ID -// iff all subsystems share a common path and ID. This is common for -// containerized processes. If there is no common path and ID then the returned -// values are empty strings. -func getCommonCgroupMetadata(mounts map[string]mount) Metadata { - var path string - for _, m := range mounts { - if path == "" { - path = m.path - } else if path != m.path { - // All paths are not the same. - return Metadata{} - } - } - - return Metadata{Path: path, ID: filepath.Base(path)} -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/reader_test.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/reader_test.go deleted file mode 100644 index c8e7025..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/reader_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package cgroup - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/assert" -) - -const ( - path = "/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242" - id = "b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242" -) - -func TestReaderGetStats(t *testing.T) { - reader, err := NewReader("testdata/docker", true) - if err != nil { - t.Fatal(err) - } - - stats, err := reader.GetStatsForProcess(985) - if err != nil { - t.Fatal(err) - } - if stats == nil { - t.Fatal("no cgroup stats found") - } - - assert.Equal(t, id, stats.ID) - assert.Equal(t, id, stats.BlockIO.ID) - assert.Equal(t, id, stats.CPU.ID) - assert.Equal(t, id, stats.CPUAccounting.ID) - assert.Equal(t, id, stats.Memory.ID) - - assert.Equal(t, path, stats.Path) - assert.Equal(t, path, stats.BlockIO.Path) - assert.Equal(t, path, stats.CPU.Path) - assert.Equal(t, path, stats.CPUAccounting.Path) - assert.Equal(t, path, stats.Memory.Path) - - json, err := json.MarshalIndent(stats, "", " ") - if err != nil { - t.Fatal(err) - } - - t.Log(string(json)) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/testdata/docker.zip b/cockroach/patches/github.com/elastic/gosigar/cgroup/testdata/docker.zip deleted file mode 100644 index 66ca734..0000000 Binary files a/cockroach/patches/github.com/elastic/gosigar/cgroup/testdata/docker.zip and /dev/null differ diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/util.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/util.go deleted file mode 100644 index eceb506..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/util.go +++ /dev/null @@ -1,263 +0,0 @@ -package cgroup - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" -) - -var ( - // ErrCgroupsMissing indicates the /proc/cgroups was not found. This means - // that cgroups were disabled at compile time (CONFIG_CGROUPS=n) or that - // an invalid rootfs path was given. - ErrCgroupsMissing = errors.New("cgroups not found or unsupported by OS") - - // ErrInvalidFormat indicates a malformed key/value pair on a line. - ErrInvalidFormat = errors.New("error invalid key/value format") -) - -// mountinfo represents a subset of the fields containing /proc/[pid]/mountinfo. -type mountinfo struct { - mountpoint string - filesystemType string - superOptions []string -} - -// Parses a cgroup param and returns the key name and value. -func parseCgroupParamKeyValue(t string) (string, uint64, error) { - parts := strings.Fields(t) - if len(parts) != 2 { - return "", 0, ErrInvalidFormat - } - - value, err := parseUint([]byte(parts[1])) - if err != nil { - return "", 0, fmt.Errorf("unable to convert param value (%q) to uint64: %v", parts[1], err) - } - - return parts[0], value, nil -} - -// parseUintFromFile reads a single uint value from a file. -func parseUintFromFile(path ...string) (uint64, error) { - value, err := ioutil.ReadFile(filepath.Join(path...)) - if err != nil { - // Not all features are implemented/enabled by each OS. - if os.IsNotExist(err) { - return 0, nil - } - return 0, err - } - - return parseUint(value) -} - -// parseUint reads a single uint value. It will trip any whitespace before -// attempting to parse string. If the value is negative it will return 0. -func parseUint(value []byte) (uint64, error) { - strValue := string(bytes.TrimSpace(value)) - uintValue, err := strconv.ParseUint(strValue, 10, 64) - if err != nil { - // Munge negative values to 0. - intValue, intErr := strconv.ParseInt(strValue, 10, 64) - if intErr == nil && intValue < 0 { - return 0, nil - } else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 { - return 0, nil - } - - return 0, err - } - - return uintValue, nil -} - -// parseMountinfoLine parses a line from the /proc/[pid]/mountinfo file on -// Linux. The format of the line is specified in section 3.5 of -// https://www.kernel.org/doc/Documentation/filesystems/proc.txt. -func parseMountinfoLine(line string) (mountinfo, error) { - mount := mountinfo{} - - fields := strings.Fields(line) - if len(fields) < 10 { - return mount, fmt.Errorf("invalid mountinfo line, expected at least "+ - "10 fields but got %d from line='%s'", len(fields), line) - } - - mount.mountpoint = fields[4] - - var seperatorIndex int - for i, value := range fields { - if value == "-" { - seperatorIndex = i - break - } - } - if fields[seperatorIndex] != "-" { - return mount, fmt.Errorf("invalid mountinfo line, separator ('-') not "+ - "found in line='%s'", line) - } - - if len(fields)-seperatorIndex-1 < 3 { - return mount, fmt.Errorf("invalid mountinfo line, expected at least "+ - "3 fields after seperator but got %d from line='%s'", - len(fields)-seperatorIndex-1, line) - } - - fields = fields[seperatorIndex+1:] - mount.filesystemType = fields[0] - mount.superOptions = strings.Split(fields[2], ",") - return mount, nil -} - -// SupportedSubsystems returns the subsystems that are supported by the -// kernel. The returned map contains a entry for each subsystem. -func SupportedSubsystems(rootfsMountpoint string) (map[string]struct{}, error) { - if rootfsMountpoint == "" { - rootfsMountpoint = "/" - } - - cgroups, err := os.Open(filepath.Join(rootfsMountpoint, "proc", "cgroups")) - if err != nil { - if os.IsNotExist(err) { - return nil, ErrCgroupsMissing - } - return nil, err - } - defer cgroups.Close() - - subsystemSet := map[string]struct{}{} - sc := bufio.NewScanner(cgroups) - for sc.Scan() { - line := sc.Text() - - // Ignore the header. - if len(line) > 0 && line[0] == '#' { - continue - } - - // Parse the cgroup subsystems. - // Format: subsys_name hierarchy num_cgroups enabled - // Example: cpuset 4 1 1 - fields := strings.Fields(line) - if len(fields) == 0 { - continue - } - - // Check the enabled flag. - if len(fields) > 3 { - enabled := fields[3] - if enabled == "0" { - // Ignore cgroup subsystems that are disabled (via the - // cgroup_disable kernel command-line boot parameter). - continue - } - } - - subsystem := fields[0] - subsystemSet[subsystem] = struct{}{} - } - - return subsystemSet, sc.Err() -} - -// SubsystemMountpoints returns the mountpoints for each of the given subsystems. -// The returned map contains the subsystem name as a key and the value is the -// mountpoint. -func SubsystemMountpoints(rootfsMountpoint string, subsystems map[string]struct{}) (map[string]string, error) { - if rootfsMountpoint == "" { - rootfsMountpoint = "/" - } - - mountinfo, err := os.Open(filepath.Join(rootfsMountpoint, "proc", "self", "mountinfo")) - if err != nil { - return nil, err - } - defer mountinfo.Close() - - mounts := map[string]string{} - sc := bufio.NewScanner(mountinfo) - for sc.Scan() { - // https://www.kernel.org/doc/Documentation/filesystems/proc.txt - // Example: - // 25 21 0:20 / /cgroup/cpu rw,relatime - cgroup cgroup rw,cpu - line := strings.TrimSpace(sc.Text()) - if line == "" { - continue - } - - mount, err := parseMountinfoLine(line) - if err != nil { - return nil, err - } - - if mount.filesystemType != "cgroup" { - continue - } - - if !strings.HasPrefix(mount.mountpoint, rootfsMountpoint) { - continue - } - - for _, opt := range mount.superOptions { - // Sometimes the subsystem name is written like "name=blkio". - fields := strings.SplitN(opt, "=", 2) - if len(fields) > 1 { - opt = fields[1] - } - - // Test if option is a subsystem name. - if _, found := subsystems[opt]; found { - // Add the subsystem mount if it does not already exist. - if _, exists := mounts[opt]; !exists { - mounts[opt] = mount.mountpoint - } - } - } - } - - return mounts, sc.Err() -} - -// ProcessCgroupPaths returns the cgroups to which a process belongs and the -// pathname of the cgroup relative to the mountpoint of the subsystem. -func ProcessCgroupPaths(rootfsMountpoint string, pid int) (map[string]string, error) { - if rootfsMountpoint == "" { - rootfsMountpoint = "/" - } - - cgroup, err := os.Open(filepath.Join(rootfsMountpoint, "proc", strconv.Itoa(pid), "cgroup")) - if err != nil { - return nil, err - } - defer cgroup.Close() - - paths := map[string]string{} - sc := bufio.NewScanner(cgroup) - for sc.Scan() { - // http://man7.org/linux/man-pages/man7/cgroups.7.html - // Format: hierarchy-ID:subsystem-list:cgroup-path - // Example: - // 2:cpu:/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242 - line := sc.Text() - - fields := strings.Split(line, ":") - if len(fields) != 3 { - continue - } - - path := fields[2] - subsystems := strings.Split(fields[1], ",") - for _, subsystem := range subsystems { - paths[subsystem] = path - } - } - - return paths, sc.Err() -} diff --git a/cockroach/patches/github.com/elastic/gosigar/cgroup/util_test.go b/cockroach/patches/github.com/elastic/gosigar/cgroup/util_test.go deleted file mode 100644 index 6a3809b..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/cgroup/util_test.go +++ /dev/null @@ -1,191 +0,0 @@ -package cgroup - -import ( - "archive/zip" - "fmt" - "io" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" -) - -const dockerTestData = "testdata/docker.zip" - -func TestMain(m *testing.M) { - err := extractTestData(dockerTestData) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - os.Exit(m.Run()) -} - -// extractTestData from zip file and write it in the same dir as the zip file. -func extractTestData(path string) error { - r, err := zip.OpenReader(path) - if err != nil { - return err - } - defer r.Close() - - dest := filepath.Dir(path) - - extractAndWriteFile := func(f *zip.File) error { - rc, err := f.Open() - if err != nil { - return err - } - defer rc.Close() - - path := filepath.Join(dest, f.Name) - if found, err := exists(path); err != nil || found { - return err - } - - if f.FileInfo().IsDir() { - os.MkdirAll(path, f.Mode()) - } else { - destFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0700)) - if err != nil { - return err - } - defer destFile.Close() - - _, err = io.Copy(destFile, rc) - if err != nil { - return err - } - - os.Chmod(path, f.Mode()) - } - return nil - } - - for _, f := range r.File { - err := extractAndWriteFile(f) - if err != nil { - return err - } - } - - return nil -} - -// exists returns whether the given file or directory exists or not -func exists(path string) (bool, error) { - _, err := os.Stat(path) - if err == nil { - return true, nil - } - if os.IsNotExist(err) { - return false, nil - } - return true, err -} - -func TestSupportedSubsystems(t *testing.T) { - subsystems, err := SupportedSubsystems("testdata/docker") - if err != nil { - t.Fatal(err) - } - - assert.Len(t, subsystems, 11) - assertContains(t, subsystems, "cpuset") - assertContains(t, subsystems, "cpu") - assertContains(t, subsystems, "cpuacct") - assertContains(t, subsystems, "blkio") - assertContains(t, subsystems, "memory") - assertContains(t, subsystems, "devices") - assertContains(t, subsystems, "freezer") - assertContains(t, subsystems, "net_cls") - assertContains(t, subsystems, "perf_event") - assertContains(t, subsystems, "net_prio") - assertContains(t, subsystems, "pids") - - _, found := subsystems["hugetlb"] - assert.False(t, found, "hugetlb should be missing because it's disabled") -} - -func TestSupportedSubsystemsErrCgroupsMissing(t *testing.T) { - _, err := SupportedSubsystems("testdata/doesnotexist") - if err != ErrCgroupsMissing { - t.Fatalf("expected ErrCgroupsMissing, but got %v", err) - } -} - -func TestSubsystemMountpoints(t *testing.T) { - subsystems := map[string]struct{}{} - subsystems["blkio"] = struct{}{} - subsystems["cpu"] = struct{}{} - subsystems["cpuacct"] = struct{}{} - subsystems["cpuset"] = struct{}{} - subsystems["devices"] = struct{}{} - subsystems["freezer"] = struct{}{} - subsystems["hugetlb"] = struct{}{} - subsystems["memory"] = struct{}{} - subsystems["perf_event"] = struct{}{} - - mountpoints, err := SubsystemMountpoints("testdata/docker", subsystems) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, "testdata/docker/sys/fs/cgroup/blkio", mountpoints["blkio"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/cpu", mountpoints["cpu"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/cpuacct", mountpoints["cpuacct"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/cpuset", mountpoints["cpuset"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/devices", mountpoints["devices"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/freezer", mountpoints["freezer"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/hugetlb", mountpoints["hugetlb"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/memory", mountpoints["memory"]) - assert.Equal(t, "testdata/docker/sys/fs/cgroup/perf_event", mountpoints["perf_event"]) -} - -func TestProcessCgroupPaths(t *testing.T) { - paths, err := ProcessCgroupPaths("testdata/docker", 985) - if err != nil { - t.Fatal(err) - } - - path := "/docker/b29faf21b7eff959f64b4192c34d5d67a707fe8561e9eaa608cb27693fba4242" - assert.Equal(t, path, paths["blkio"]) - assert.Equal(t, path, paths["cpu"]) - assert.Equal(t, path, paths["cpuacct"]) - assert.Equal(t, path, paths["cpuset"]) - assert.Equal(t, path, paths["devices"]) - assert.Equal(t, path, paths["freezer"]) - assert.Equal(t, path, paths["memory"]) - assert.Equal(t, path, paths["net_cls"]) - assert.Equal(t, path, paths["net_prio"]) - assert.Equal(t, path, paths["perf_event"]) - assert.Len(t, paths, 10) -} - -func assertContains(t testing.TB, m map[string]struct{}, key string) { - _, contains := m[key] - if !contains { - t.Errorf("map is missing key %v, map=%+v", key, m) - } -} - -func TestParseMountinfoLine(t *testing.T) { - lines := []string{ - "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio", - "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,blkio", - "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:13 master:1 - cgroup cgroup rw,blkio", - "30 24 0:25 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,name=blkio", - } - - for _, line := range lines { - mount, err := parseMountinfoLine(line) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, "/sys/fs/cgroup/blkio", mount.mountpoint) - assert.Equal(t, "cgroup", mount.filesystemType) - assert.Len(t, mount.superOptions, 2) - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/codecov.yml b/cockroach/patches/github.com/elastic/gosigar/codecov.yml deleted file mode 100644 index 76ade0f..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/codecov.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Enable coverage report message for diff on commit -coverage: - status: - project: off - patch: - default: - # basic - target: auto - threshold: null - base: auto - # advanced - branches: null - if_no_uploads: error - if_not_found: success - if_ci_failed: error - only_pulls: false - flags: null - paths: null - -# Disable comments on Pull Requests -comment: false diff --git a/cockroach/patches/github.com/elastic/gosigar/concrete_sigar.go b/cockroach/patches/github.com/elastic/gosigar/concrete_sigar.go deleted file mode 100644 index e3ee80a..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/concrete_sigar.go +++ /dev/null @@ -1,89 +0,0 @@ -package gosigar - -import ( - "time" -) - -type ConcreteSigar struct{} - -func (c *ConcreteSigar) CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{}) { - // samplesCh is buffered to 1 value to immediately return first CPU sample - samplesCh := make(chan Cpu, 1) - - stopCh := make(chan struct{}) - - go func() { - var cpuUsage Cpu - - // Immediately provide non-delta value. - // samplesCh is buffered to 1 value, so it will not block. - cpuUsage.Get() - samplesCh <- cpuUsage - - ticker := time.NewTicker(collectionInterval) - - for { - select { - case <-ticker.C: - previousCpuUsage := cpuUsage - - cpuUsage.Get() - - select { - case samplesCh <- cpuUsage.Delta(previousCpuUsage): - default: - // Include default to avoid channel blocking - } - - case <-stopCh: - return - } - } - }() - - return samplesCh, stopCh -} - -func (c *ConcreteSigar) GetLoadAverage() (LoadAverage, error) { - l := LoadAverage{} - err := l.Get() - return l, err -} - -func (c *ConcreteSigar) GetMem() (Mem, error) { - m := Mem{} - err := m.Get() - return m, err -} - -func (c *ConcreteSigar) GetSwap() (Swap, error) { - s := Swap{} - err := s.Get() - return s, err -} - -func (c *ConcreteSigar) GetHugeTLBPages() (HugeTLBPages, error) { - p := HugeTLBPages{} - err := p.Get() - return p, err -} - -func (c *ConcreteSigar) GetFileSystemUsage(path string) (FileSystemUsage, error) { - f := FileSystemUsage{} - err := f.Get(path) - return f, err -} - -func (c *ConcreteSigar) GetFDUsage() (FDUsage, error) { - fd := FDUsage{} - err := fd.Get() - return fd, err -} - -// GetRusage return the resource usage of the process -// Possible params: 0 = RUSAGE_SELF, 1 = RUSAGE_CHILDREN, 2 = RUSAGE_THREAD -func (c *ConcreteSigar) GetRusage(who int) (Rusage, error) { - r := Rusage{} - err := r.Get(who) - return r, err -} diff --git a/cockroach/patches/github.com/elastic/gosigar/concrete_sigar_test.go b/cockroach/patches/github.com/elastic/gosigar/concrete_sigar_test.go deleted file mode 100644 index 99e3a36..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/concrete_sigar_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package gosigar_test - -import ( - "runtime" - "testing" - "time" - - sigar "github.com/elastic/gosigar" - "github.com/stretchr/testify/assert" -) - -func TestConcreteCollectCpuStats(t *testing.T) { - concreteSigar := &sigar.ConcreteSigar{} - - // Immediately makes first CPU usage available even though it's not very accurate. - samplesCh, stop := concreteSigar.CollectCpuStats(500 * time.Millisecond) - firstValue := <-samplesCh - assert.True(t, firstValue.User > 0) - stop <- struct{}{} - - // Makes CPU usage delta values available - samplesCh, stop = concreteSigar.CollectCpuStats(500 * time.Millisecond) - firstValue = <-samplesCh - secondValue := <-samplesCh - assert.True(t, secondValue.User < firstValue.User) - stop <- struct{}{} - - // Does not block. - _, stop = concreteSigar.CollectCpuStats(10 * time.Millisecond) - // Sleep long enough for samplesCh to fill at least 2 values - time.Sleep(20 * time.Millisecond) - stop <- struct{}{} -} - -func TestConcreteGetLoadAverage(t *testing.T) { - concreteSigar := &sigar.ConcreteSigar{} - avg, err := concreteSigar.GetLoadAverage() - skipNotImplemented(t, err, "windows") - if assert.NoError(t, err) { - assert.NotNil(t, avg.One) - assert.NotNil(t, avg.Five) - assert.NotNil(t, avg.Fifteen) - } -} - -func TestConcreteGetMem(t *testing.T) { - concreteSigar := &sigar.ConcreteSigar{} - mem, err := concreteSigar.GetMem() - if assert.NoError(t, err) { - assert.True(t, mem.Total > 0) - assert.True(t, mem.Used+mem.Free <= mem.Total) - } -} - -func TestConcreteGetSwap(t *testing.T) { - concreteSigar := &sigar.ConcreteSigar{} - swap, err := concreteSigar.GetSwap() - if assert.NoError(t, err) { - assert.True(t, swap.Used+swap.Free <= swap.Total) - } -} - -func TestConcreteFileSystemUsage(t *testing.T) { - root := "/" - if runtime.GOOS == "windows" { - root = "C:\\" - } - - concreteSigar := &sigar.ConcreteSigar{} - fsusage, err := concreteSigar.GetFileSystemUsage(root) - if assert.NoError(t, err, "Error is %v", err) { - assert.True(t, fsusage.Total > 0) - } - - fsusage, err = concreteSigar.GetFileSystemUsage("T O T A L L Y B O G U S") - assert.Error(t, err) -} - -func TestConcreteGetFDUsage(t *testing.T) { - concreteSigar := &sigar.ConcreteSigar{} - fdUsage, err := concreteSigar.GetFDUsage() - skipNotImplemented(t, err, "windows", "darwin", "aix") - if assert.NoError(t, err) { - assert.True(t, fdUsage.Open > 0) - assert.True(t, fdUsage.Open <= fdUsage.Max) - } -} - -func TestConcreteGetRusage(t *testing.T) { - concreteSigar := &sigar.ConcreteSigar{} - resourceUsage, err := concreteSigar.GetRusage(0) - skipNotImplemented(t, err, "netbsd", "solaris") - if assert.NoError(t, err) { - assert.True(t, resourceUsage.Utime >= 0) - assert.True(t, resourceUsage.Stime >= 0) - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/examples/df/df.go b/cockroach/patches/github.com/elastic/gosigar/examples/df/df.go deleted file mode 100644 index 8256575..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/examples/df/df.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package main - -import ( - "fmt" - "os" - - "github.com/elastic/gosigar" -) - -const output_format = "%-15s %4s %4s %5s %4s %-15s\n" - -func main() { - fslist := gosigar.FileSystemList{} - err := fslist.Get() - if err != nil { - fmt.Printf("Failed to get list of filesystems: %v\n", err) - os.Exit(-1) - } - - fmt.Fprintf(os.Stdout, output_format, - "Filesystem", "Size", "Used", "Avail", "Use%", "Mounted on") - - for _, fs := range fslist.List { - dir_name := fs.DirName - - usage := gosigar.FileSystemUsage{} - - usage.Get(dir_name) - - fmt.Fprintf(os.Stdout, output_format, - fs.DevName, - gosigar.FormatSize(usage.Total), - gosigar.FormatSize(usage.Used), - gosigar.FormatSize(usage.Avail), - gosigar.FormatPercent(usage.UsePercent()), - dir_name) - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/examples/free/free.go b/cockroach/patches/github.com/elastic/gosigar/examples/free/free.go deleted file mode 100644 index 57c3e4a..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/examples/free/free.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package main - -import ( - "fmt" - "os" - - "github.com/elastic/gosigar" -) - -func format(val uint64) uint64 { - return val / 1024 -} - -func main() { - mem := gosigar.Mem{} - swap := gosigar.Swap{} - - mem.Get() - swap.Get() - - fmt.Fprintf(os.Stdout, "%18s %10s %10s\n", - "total", "used", "free") - - fmt.Fprintf(os.Stdout, "Mem: %10d %10d %10d\n", - format(mem.Total), format(mem.Used), format(mem.Free)) - - fmt.Fprintf(os.Stdout, "-/+ buffers/cache: %10d %10d\n", - format(mem.ActualUsed), format(mem.ActualFree)) - - fmt.Fprintf(os.Stdout, "Swap: %10d %10d %10d\n", - format(swap.Total), format(swap.Used), format(swap.Free)) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/examples/ps/ps.go b/cockroach/patches/github.com/elastic/gosigar/examples/ps/ps.go deleted file mode 100644 index 8a2947e..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/examples/ps/ps.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package main - -import ( - "fmt" - "strings" - - "github.com/elastic/gosigar" -) - -func main() { - pids := gosigar.ProcList{} - err := pids.Get() - - if err != nil { - fmt.Printf("proclist get: %v\n", err) - } - - // ps -eo pid,ppid,stime,time,rss,user,state,command - fmt.Print(" PID PPID STIME TIME RSS USER S COMMAND\n") - - for _, pid := range pids.List { - state := gosigar.ProcState{} - mem := gosigar.ProcMem{} - time := gosigar.ProcTime{} - args := gosigar.ProcArgs{} - - if err := state.Get(pid); err != nil { - fmt.Printf("state get: %v\n", err) - continue - } - if err := mem.Get(pid); err != nil { - fmt.Printf("mem get: %v\n", err) - continue - } - if err := time.Get(pid); err != nil { - fmt.Printf("time get: %v\n", err) - continue - } - if err := args.Get(pid); err != nil { - fmt.Printf("args get: %v\n", err) - continue - } - - fmt.Printf("%5d %5d %s %s %6d %-15s %c %s\n", - pid, state.Ppid, - time.FormatStartTime(), time.FormatTotal(), - mem.Resident/1024, state.Username, state.State, - strings.Join(args.List, " ")) - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/examples/ss/ss.go b/cockroach/patches/github.com/elastic/gosigar/examples/ss/ss.go deleted file mode 100644 index eac09af..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/examples/ss/ss.go +++ /dev/null @@ -1,102 +0,0 @@ -// +build linux - -package main - -import ( - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "strings" - "syscall" - "text/tabwriter" - - "github.com/elastic/gosigar/sys/linux" -) - -var ( - fs = flag.NewFlagSet("ss", flag.ExitOnError) - debug = fs.Bool("d", false, "enable debug output to stderr") - ipv6 = fs.Bool("6", false, "display only IP version 6 sockets") - v1 = fs.Bool("v1", false, "send inet_diag_msg v1 instead of v2") - diag = fs.String("diag", "", "dump raw information about TCP sockets to FILE") -) - -func main() { - log.SetFlags(0) - fs.Parse(os.Args[1:]) - - if !*debug { - log.SetOutput(ioutil.Discard) - } - - if err := sockets(); err != nil { - fmt.Fprintf(os.Stderr, "error: %v\n", err) - os.Exit(1) - } -} - -func sockets() error { - // Set address family based on flags. The requested address family only - // works with inet_diag_req_v2. v1 returns all tcp sockets. - af := linux.AF_INET - if *ipv6 { - af = linux.AF_INET6 - } - - // For debug purposes allow for sending either inet_diag_req and inet_diag_req_v2. - var req syscall.NetlinkMessage - if *v1 { - req = linux.NewInetDiagReq() - } else { - req = linux.NewInetDiagReqV2(af) - } - - // Write netlink response to a file for further analysis or for writing - // tests cases. - var diagWriter io.Writer - if *diag != "" { - f, err := os.OpenFile(*diag, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0600) - if err != nil { - return err - } - defer f.Close() - diagWriter = f - } - - log.Println("sending netlink request") - msgs, err := linux.NetlinkInetDiagWithBuf(req, nil, diagWriter) - if err != nil { - return err - } - log.Printf("received %d inet_diag_msg responses", len(msgs)) - - w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) - fmt.Fprintln(w, strings.Join([]string{ - "State", - "Recv-Q", - "Send-Q", - "Local Address:Port", - "Remote Address:Port", - "UID", - "Inode", - "PID/Program", - }, "\t")) - defer w.Flush() - - for _, diag := range msgs { - // XXX: A real implementation of ss would find the process holding - // inode of the socket. It would read /proc//fd and find all sockets. - pidProgram := "not implemented" - - fmt.Fprintf(w, "%v\t%v\t%v\t%v:%v\t%v:%v\t%v\t%v\t%v\n", - linux.TCPState(diag.State), diag.RQueue, diag.WQueue, - diag.SrcIP().String(), diag.SrcPort(), - diag.DstIP().String(), diag.DstPort(), - diag.UID, diag.Inode, pidProgram) - } - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/examples/ss/ss_other.go b/cockroach/patches/github.com/elastic/gosigar/examples/ss/ss_other.go deleted file mode 100644 index 7b1e068..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/examples/ss/ss_other.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !linux - -package main - -import ( - "fmt" -) - -func main() { - fmt.Println("This command is only available on Linux") -} diff --git a/cockroach/patches/github.com/elastic/gosigar/examples/uptime/uptime.go b/cockroach/patches/github.com/elastic/gosigar/examples/uptime/uptime.go deleted file mode 100644 index 49d895f..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/examples/uptime/uptime.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package main - -import ( - "fmt" - "os" - "time" - - "github.com/elastic/gosigar" -) - -func main() { - concreteSigar := gosigar.ConcreteSigar{} - - uptime := gosigar.Uptime{} - uptime.Get() - avg, err := concreteSigar.GetLoadAverage() - if err != nil { - fmt.Printf("Failed to get load average") - return - } - - fmt.Fprintf(os.Stdout, " %s up %s load average: %.2f, %.2f, %.2f\n", - time.Now().Format("15:04:05"), - uptime.Format(), - avg.One, avg.Five, avg.Fifteen) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/fakes/fake_sigar.go b/cockroach/patches/github.com/elastic/gosigar/fakes/fake_sigar.go deleted file mode 100644 index 7d2414a..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/fakes/fake_sigar.go +++ /dev/null @@ -1,72 +0,0 @@ -package fakes - -import ( - "time" - - sigar "github.com/elastic/gosigar" -) - -type FakeSigar struct { - LoadAverage sigar.LoadAverage - LoadAverageErr error - - Mem sigar.Mem - MemErr error - - Swap sigar.Swap - SwapErr error - - FileSystemUsage sigar.FileSystemUsage - FileSystemUsageErr error - FileSystemUsagePath string - - CollectCpuStatsCpuCh chan sigar.Cpu - CollectCpuStatsStopCh chan struct{} -} - -func NewFakeSigar() *FakeSigar { - return &FakeSigar{ - CollectCpuStatsCpuCh: make(chan sigar.Cpu, 1), - CollectCpuStatsStopCh: make(chan struct{}), - } -} - -func (f *FakeSigar) CollectCpuStats(collectionInterval time.Duration) (<-chan sigar.Cpu, chan<- struct{}) { - samplesCh := make(chan sigar.Cpu, 1) - stopCh := make(chan struct{}) - - go func() { - for { - select { - case cpuStat := <-f.CollectCpuStatsCpuCh: - select { - case samplesCh <- cpuStat: - default: - // Include default to avoid channel blocking - } - - case <-f.CollectCpuStatsStopCh: - return - } - } - }() - - return samplesCh, stopCh -} - -func (f *FakeSigar) GetLoadAverage() (sigar.LoadAverage, error) { - return f.LoadAverage, f.LoadAverageErr -} - -func (f *FakeSigar) GetMem() (sigar.Mem, error) { - return f.Mem, f.MemErr -} - -func (f *FakeSigar) GetSwap() (sigar.Swap, error) { - return f.Swap, f.SwapErr -} - -func (f *FakeSigar) GetFileSystemUsage(path string) (sigar.FileSystemUsage, error) { - f.FileSystemUsagePath = path - return f.FileSystemUsage, f.FileSystemUsageErr -} diff --git a/cockroach/patches/github.com/elastic/gosigar/psnotify/README.md b/cockroach/patches/github.com/elastic/gosigar/psnotify/README.md deleted file mode 100644 index dd34ebc..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/psnotify/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Process notifications for Go - -## Overview - -The psnotify package captures process events from the kernel via -kqueue on Darwin/BSD and the netlink connector on Linux. - -The psnotify API is similar to the -[fsnotify](https://github.com/howeyc/fsnotify) package. - -Example: -```go - watcher, err := psnotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - - // Process events - go func() { - for { - select { - case ev := <-watcher.Fork: - log.Println("fork event:", ev) - case ev := <-watcher.Exec: - log.Println("exec event:", ev) - case ev := <-watcher.Exit: - log.Println("exit event:", ev) - case err := <-watcher.Error: - log.Println("error:", err) - } - } - }() - - err = watcher.Watch(os.Getpid(), psnotify.PROC_EVENT_ALL) - if err != nil { - log.Fatal(err) - } - - /* ... do stuff ... */ - watcher.Close() -``` - -## Supported platforms - -Currently targeting modern flavors of Darwin and Linux. -Should work on BSD, but untested. - -## License - -Apache 2.0 diff --git a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify.go b/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify.go deleted file mode 100644 index 5fb6f8c..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -// +build darwin freebsd netbsd openbsd linux - -package psnotify - -import ( - "errors" - "fmt" -) - -type ProcEventFork struct { - ParentPid int // Pid of the process that called fork() - ChildPid int // Child process pid created by fork() -} - -type ProcEventExec struct { - Pid int // Pid of the process that called exec() -} - -type ProcEventExit struct { - Pid int // Pid of the process that called exit() -} - -type watch struct { - flags uint32 // Saved value of Watch() flags param -} - -type eventListener interface { - close() error // Watch.Close() closes the OS specific listener -} - -type Watcher struct { - listener eventListener // OS specifics (kqueue or netlink) - watches map[int]*watch // Map of watched process ids - Error chan error // Errors are sent on this channel - Fork chan *ProcEventFork // Fork events are sent on this channel - Exec chan *ProcEventExec // Exec events are sent on this channel - Exit chan *ProcEventExit // Exit events are sent on this channel - done chan bool // Used to stop the readEvents() goroutine - isClosed bool // Set to true when Close() is first called -} - -// Initialize event listener and channels -func NewWatcher() (*Watcher, error) { - listener, err := createListener() - - if err != nil { - return nil, err - } - - w := &Watcher{ - listener: listener, - watches: make(map[int]*watch), - Fork: make(chan *ProcEventFork), - Exec: make(chan *ProcEventExec), - Exit: make(chan *ProcEventExit), - Error: make(chan error), - done: make(chan bool, 1), - } - - go w.readEvents() - return w, nil -} - -// Close event channels when done message is received -func (w *Watcher) finish() { - close(w.Fork) - close(w.Exec) - close(w.Exit) - close(w.Error) -} - -// Closes the OS specific event listener, -// removes all watches and closes all event channels. -func (w *Watcher) Close() error { - if w.isClosed { - return nil - } - w.isClosed = true - - for pid := range w.watches { - w.RemoveWatch(pid) - } - - w.done <- true - - w.listener.close() - - return nil -} - -// Add pid to the watched process set. -// The flags param is a bitmask of process events to capture, -// must be one or more of: PROC_EVENT_FORK, PROC_EVENT_EXEC, PROC_EVENT_EXIT -func (w *Watcher) Watch(pid int, flags uint32) error { - if w.isClosed { - return errors.New("psnotify watcher is closed") - } - - watchEntry, found := w.watches[pid] - - if found { - watchEntry.flags |= flags - } else { - if err := w.register(pid, flags); err != nil { - return err - } - w.watches[pid] = &watch{flags: flags} - } - - return nil -} - -// Remove pid from the watched process set. -func (w *Watcher) RemoveWatch(pid int) error { - _, ok := w.watches[pid] - if !ok { - msg := fmt.Sprintf("watch for pid=%d does not exist", pid) - return errors.New(msg) - } - delete(w.watches, pid) - return w.unregister(pid) -} - -// Internal helper to check if there is a message on the "done" channel. -// The "done" message is sent by the Close() method; when received here, -// the Watcher.finish method is called to close all channels and return -// true - in which case the caller should break from the readEvents loop. -func (w *Watcher) isDone() bool { - var done bool - select { - case done = <-w.done: - w.finish() - default: - } - return done -} diff --git a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_bsd.go b/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_bsd.go deleted file mode 100644 index e147d76..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_bsd.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -// +build darwin freebsd netbsd openbsd - -// Go interface to BSD kqueue process events. -package psnotify - -import ( - "syscall" -) - -const ( - // Flags (from ) - PROC_EVENT_FORK = syscall.NOTE_FORK // fork() events - PROC_EVENT_EXEC = syscall.NOTE_EXEC // exec() events - PROC_EVENT_EXIT = syscall.NOTE_EXIT // exit() events - - // Watch for all process events - PROC_EVENT_ALL = PROC_EVENT_FORK | PROC_EVENT_EXEC | PROC_EVENT_EXIT -) - -type kqueueListener struct { - kq int // The syscall.Kqueue() file descriptor - buf [1]syscall.Kevent_t // An event buffer for Add/Remove watch -} - -// Initialize bsd implementation of the eventListener interface -func createListener() (eventListener, error) { - listener := &kqueueListener{} - kq, err := syscall.Kqueue() - listener.kq = kq - return listener, err -} - -// Initialize Kevent_t fields and propagate changelist for the given pid -func (w *Watcher) kevent(pid int, fflags uint32, flags int) error { - listener, _ := w.listener.(*kqueueListener) - event := &listener.buf[0] - - syscall.SetKevent(event, pid, syscall.EVFILT_PROC, flags) - event.Fflags = fflags - - _, err := syscall.Kevent(listener.kq, listener.buf[:], nil, nil) - - return err -} - -// Delete filter for given pid from the queue -func (w *Watcher) unregister(pid int) error { - return w.kevent(pid, 0, syscall.EV_DELETE) -} - -// Add and enable filter for given pid in the queue -func (w *Watcher) register(pid int, flags uint32) error { - return w.kevent(pid, flags, syscall.EV_ADD|syscall.EV_ENABLE) -} - -// Poll the kqueue file descriptor and dispatch to the Event channels -func (w *Watcher) readEvents() { - listener, _ := w.listener.(*kqueueListener) - events := make([]syscall.Kevent_t, 10) - - for { - if w.isDone() { - return - } - - n, err := syscall.Kevent(listener.kq, nil, events, nil) - if err != nil { - w.Error <- err - continue - } - - for _, ev := range events[:n] { - pid := int(ev.Ident) - - switch ev.Fflags { - case syscall.NOTE_FORK: - w.Fork <- &ProcEventFork{ParentPid: pid} - case syscall.NOTE_EXEC: - w.Exec <- &ProcEventExec{Pid: pid} - case syscall.NOTE_EXIT: - w.RemoveWatch(pid) - w.Exit <- &ProcEventExit{Pid: pid} - } - } - } -} - -// Close our kqueue file descriptor; deletes any remaining filters -func (listener *kqueueListener) close() error { - return syscall.Close(listener.kq) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_linux.go b/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_linux.go deleted file mode 100644 index a4dedbf..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_linux.go +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -// Go interface to the Linux netlink process connector. -// See Documentation/connector/connector.txt in the linux kernel source tree. -package psnotify - -import ( - "bytes" - "encoding/binary" - "os" - "syscall" - - "github.com/elastic/gosigar/sys" -) - -const ( - // internal flags (from ) - _CN_IDX_PROC = 0x1 - _CN_VAL_PROC = 0x1 - - // internal flags (from ) - _PROC_CN_MCAST_LISTEN = 1 - _PROC_CN_MCAST_IGNORE = 2 - - // Flags (from ) - PROC_EVENT_FORK = 0x00000001 // fork() events - PROC_EVENT_EXEC = 0x00000002 // exec() events - PROC_EVENT_EXIT = 0x80000000 // exit() events - - // Watch for all process events - PROC_EVENT_ALL = PROC_EVENT_FORK | PROC_EVENT_EXEC | PROC_EVENT_EXIT -) - -var ( - byteOrder = sys.GetEndian() -) - -// linux/connector.h: struct cb_id -type cbId struct { - Idx uint32 - Val uint32 -} - -// linux/connector.h: struct cb_msg -type cnMsg struct { - Id cbId - Seq uint32 - Ack uint32 - Len uint16 - Flags uint16 -} - -// linux/cn_proc.h: struct proc_event.{what,cpu,timestamp_ns} -type procEventHeader struct { - What uint32 - Cpu uint32 - Timestamp uint64 -} - -// linux/cn_proc.h: struct proc_event.fork -type forkProcEvent struct { - ParentPid uint32 - ParentTgid uint32 - ChildPid uint32 - ChildTgid uint32 -} - -// linux/cn_proc.h: struct proc_event.exec -type execProcEvent struct { - ProcessPid uint32 - ProcessTgid uint32 -} - -// linux/cn_proc.h: struct proc_event.exit -type exitProcEvent struct { - ProcessPid uint32 - ProcessTgid uint32 - ExitCode uint32 - ExitSignal uint32 -} - -// standard netlink header + connector header -type netlinkProcMessage struct { - Header syscall.NlMsghdr - Data cnMsg -} - -type netlinkListener struct { - addr *syscall.SockaddrNetlink // Netlink socket address - sock int // The syscall.Socket() file descriptor - seq uint32 // struct cn_msg.seq -} - -// Initialize linux implementation of the eventListener interface -func createListener() (eventListener, error) { - listener := &netlinkListener{} - err := listener.bind() - return listener, err -} - -// noop on linux -func (w *Watcher) unregister(pid int) error { - return nil -} - -// noop on linux -func (w *Watcher) register(pid int, flags uint32) error { - return nil -} - -// Read events from the netlink socket -func (w *Watcher) readEvents() { - buf := make([]byte, syscall.Getpagesize()) - - listener, _ := w.listener.(*netlinkListener) - - for { - if w.isDone() { - return - } - - nr, _, err := syscall.Recvfrom(listener.sock, buf, 0) - - if err != nil { - w.Error <- err - continue - } - if nr < syscall.NLMSG_HDRLEN { - w.Error <- syscall.EINVAL - continue - } - - msgs, _ := syscall.ParseNetlinkMessage(buf[:nr]) - - for _, m := range msgs { - if m.Header.Type == syscall.NLMSG_DONE { - w.handleEvent(m.Data) - } - } - } -} - -// Internal helper to check if pid && event is being watched -func (w *Watcher) isWatching(pid int, event uint32) bool { - if watch, ok := w.watches[pid]; ok { - return (watch.flags & event) == event - } - return false -} - -// Dispatch events from the netlink socket to the Event channels. -// Unlike bsd kqueue, netlink receives events for all pids, -// so we apply filtering based on the watch table via isWatching() -func (w *Watcher) handleEvent(data []byte) { - buf := bytes.NewBuffer(data) - msg := &cnMsg{} - hdr := &procEventHeader{} - - binary.Read(buf, byteOrder, msg) - binary.Read(buf, byteOrder, hdr) - - switch hdr.What { - case PROC_EVENT_FORK: - event := &forkProcEvent{} - binary.Read(buf, byteOrder, event) - ppid := int(event.ParentTgid) - pid := int(event.ChildTgid) - - if w.isWatching(ppid, PROC_EVENT_EXEC) { - // follow forks - watch, _ := w.watches[ppid] - w.Watch(pid, watch.flags) - } - - if w.isWatching(ppid, PROC_EVENT_FORK) { - w.Fork <- &ProcEventFork{ParentPid: ppid, ChildPid: pid} - } - case PROC_EVENT_EXEC: - event := &execProcEvent{} - binary.Read(buf, byteOrder, event) - pid := int(event.ProcessTgid) - - if w.isWatching(pid, PROC_EVENT_EXEC) { - w.Exec <- &ProcEventExec{Pid: pid} - } - case PROC_EVENT_EXIT: - event := &exitProcEvent{} - binary.Read(buf, byteOrder, event) - pid := int(event.ProcessTgid) - - if w.isWatching(pid, PROC_EVENT_EXIT) { - w.RemoveWatch(pid) - w.Exit <- &ProcEventExit{Pid: pid} - } - } -} - -// Bind our netlink socket and -// send a listen control message to the connector driver. -func (listener *netlinkListener) bind() error { - sock, err := syscall.Socket( - syscall.AF_NETLINK, - syscall.SOCK_DGRAM, - syscall.NETLINK_CONNECTOR) - - if err != nil { - return err - } - - listener.sock = sock - listener.addr = &syscall.SockaddrNetlink{ - Family: syscall.AF_NETLINK, - Groups: _CN_IDX_PROC, - } - - err = syscall.Bind(listener.sock, listener.addr) - - if err != nil { - return err - } - - return listener.send(_PROC_CN_MCAST_LISTEN) -} - -// Send an ignore control message to the connector driver -// and close our netlink socket. -func (listener *netlinkListener) close() error { - err := listener.send(_PROC_CN_MCAST_IGNORE) - syscall.Close(listener.sock) - return err -} - -// Generic method for sending control messages to the connector -// driver; where op is one of PROC_CN_MCAST_{LISTEN,IGNORE} -func (listener *netlinkListener) send(op uint32) error { - listener.seq++ - pr := &netlinkProcMessage{} - plen := binary.Size(pr.Data) + binary.Size(op) - pr.Header.Len = syscall.NLMSG_HDRLEN + uint32(plen) - pr.Header.Type = uint16(syscall.NLMSG_DONE) - pr.Header.Flags = 0 - pr.Header.Seq = listener.seq - pr.Header.Pid = uint32(os.Getpid()) - - pr.Data.Id.Idx = _CN_IDX_PROC - pr.Data.Id.Val = _CN_VAL_PROC - - pr.Data.Len = uint16(binary.Size(op)) - - buf := bytes.NewBuffer(make([]byte, 0, pr.Header.Len)) - binary.Write(buf, byteOrder, pr) - binary.Write(buf, byteOrder, op) - - return syscall.Sendto(listener.sock, buf.Bytes(), 0, listener.addr) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_test.go b/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_test.go deleted file mode 100644 index a72d0af..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/psnotify/psnotify_test.go +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -// +build darwin freebsd netbsd openbsd linux - -package psnotify - -import ( - "fmt" - "os" - "os/exec" - "runtime" - "syscall" - "testing" - "time" -) - -type anyEvent struct { - exits []int - forks []int - execs []int - errors []error - done chan bool -} - -type testWatcher struct { - t *testing.T - watcher *Watcher - events *anyEvent -} - -// General purpose Watcher wrapper for all tests -func newTestWatcher(t *testing.T) *testWatcher { - watcher, err := NewWatcher() - if err != nil { - t.Fatal(err) - } - - events := &anyEvent{ - done: make(chan bool, 1), - } - - tw := &testWatcher{ - t: t, - watcher: watcher, - events: events, - } - - go func() { - for { - select { - case <-events.done: - return - case ev := <-watcher.Fork: - events.forks = append(events.forks, ev.ParentPid) - case ev := <-watcher.Exec: - events.execs = append(events.execs, ev.Pid) - case ev := <-watcher.Exit: - events.exits = append(events.exits, ev.Pid) - case err := <-watcher.Error: - events.errors = append(events.errors, err) - } - } - }() - - return tw -} - -func (tw *testWatcher) close() { - pause := 100 * time.Millisecond - time.Sleep(pause) - - tw.events.done <- true - - tw.watcher.Close() - - time.Sleep(pause) -} - -func skipTest(t *testing.T) bool { - if runtime.GOOS == "linux" && os.Getuid() != 0 { - fmt.Println("SKIP: test must be run as root on linux") - return true - } - return false -} - -func startSleepCommand(t *testing.T) *exec.Cmd { - cmd := exec.Command("sh", "-c", "sleep 100") - if err := cmd.Start(); err != nil { - t.Error(err) - } - return cmd -} - -func runCommand(t *testing.T, name string) *exec.Cmd { - cmd := exec.Command(name) - if err := cmd.Run(); err != nil { - t.Error(err) - } - return cmd -} - -func expectEvents(t *testing.T, num int, name string, pids []int) bool { - if len(pids) != num { - t.Errorf("Expected %d %s events, got=%v", num, name, pids) - return false - } - return true -} - -func expectEventPid(t *testing.T, name string, expect int, pid int) bool { - if expect != pid { - t.Errorf("Expected %s pid=%d, received=%d", name, expect, pid) - return false - } - return true -} - -func TestWatchFork(t *testing.T) { - if skipTest(t) { - return - } - - pid := os.Getpid() - - tw := newTestWatcher(t) - - // no watches added yet, so this fork event will no be captured - runCommand(t, "date") - - // watch fork events for this process - if err := tw.watcher.Watch(pid, PROC_EVENT_FORK); err != nil { - t.Error(err) - } - - // this fork event will be captured, - // the exec and exit events will not be captured - runCommand(t, "cal") - - tw.close() - - if expectEvents(t, 1, "forks", tw.events.forks) { - expectEventPid(t, "fork", pid, tw.events.forks[0]) - } - - expectEvents(t, 0, "execs", tw.events.execs) - expectEvents(t, 0, "exits", tw.events.exits) -} - -func TestWatchExit(t *testing.T) { - if skipTest(t) { - return - } - - tw := newTestWatcher(t) - - cmd := startSleepCommand(t) - - childPid := cmd.Process.Pid - - // watch for exit event of our child process - if err := tw.watcher.Watch(childPid, PROC_EVENT_EXIT); err != nil { - t.Error(err) - } - - // kill our child process, triggers exit event - syscall.Kill(childPid, syscall.SIGTERM) - - cmd.Wait() - - tw.close() - - expectEvents(t, 0, "forks", tw.events.forks) - - expectEvents(t, 0, "execs", tw.events.execs) - - if expectEvents(t, 1, "exits", tw.events.exits) { - expectEventPid(t, "exit", childPid, tw.events.exits[0]) - } -} - -// combined version of TestWatchFork() and TestWatchExit() -func TestWatchForkAndExit(t *testing.T) { - if skipTest(t) { - return - } - - pid := os.Getpid() - - tw := newTestWatcher(t) - - if err := tw.watcher.Watch(pid, PROC_EVENT_FORK); err != nil { - t.Error(err) - } - - cmd := startSleepCommand(t) - - childPid := cmd.Process.Pid - - if err := tw.watcher.Watch(childPid, PROC_EVENT_EXIT); err != nil { - t.Error(err) - } - - syscall.Kill(childPid, syscall.SIGTERM) - - cmd.Wait() - - tw.close() - - if expectEvents(t, 1, "forks", tw.events.forks) { - expectEventPid(t, "fork", pid, tw.events.forks[0]) - } - - expectEvents(t, 0, "execs", tw.events.execs) - - if expectEvents(t, 1, "exits", tw.events.exits) { - expectEventPid(t, "exit", childPid, tw.events.exits[0]) - } -} - -func TestWatchFollowFork(t *testing.T) { - if skipTest(t) { - return - } - - // Darwin is not able to follow forks, as the kqueue fork event - // does not provide the child pid. - if runtime.GOOS != "linux" { - fmt.Println("SKIP: test follow forks is linux only") - return - } - - pid := os.Getpid() - - tw := newTestWatcher(t) - - // watch for all process events related to this process - if err := tw.watcher.Watch(pid, PROC_EVENT_ALL); err != nil { - t.Error(err) - } - - commands := []string{"date", "cal"} - childPids := make([]int, len(commands)) - - // triggers fork/exec/exit events for each command - for i, name := range commands { - cmd := runCommand(t, name) - childPids[i] = cmd.Process.Pid - } - - // remove watch for this process - tw.watcher.RemoveWatch(pid) - - // run commands again to make sure we don't receive any unwanted events - for _, name := range commands { - runCommand(t, name) - } - - tw.close() - - // run commands again to make sure nothing panics after - // closing the watcher - for _, name := range commands { - runCommand(t, name) - } - - num := len(commands) - if expectEvents(t, num, "forks", tw.events.forks) { - for _, epid := range tw.events.forks { - expectEventPid(t, "fork", pid, epid) - } - } - - if expectEvents(t, num, "execs", tw.events.execs) { - for i, epid := range tw.events.execs { - expectEventPid(t, "exec", childPids[i], epid) - } - } - - if expectEvents(t, num, "exits", tw.events.exits) { - for i, epid := range tw.events.exits { - expectEventPid(t, "exit", childPids[i], epid) - } - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_aix.go b/cockroach/patches/github.com/elastic/gosigar/sigar_aix.go deleted file mode 100644 index bcdb7ca..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_aix.go +++ /dev/null @@ -1,564 +0,0 @@ -// +build aix - -package gosigar - -/* -#cgo LDFLAGS: -L/usr/lib -lperfstat - -#include -#include -#include -#include -#include -#include -#include -#include - -*/ -import "C" - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" - "os" - "os/user" - "runtime" - "strconv" - "syscall" - "time" - "unsafe" -) - -var system struct { - ticks uint64 - btime uint64 - pagesize uint64 -} - -func init() { - // sysconf(_SC_CLK_TCK) returns the number of ticks by second. - system.ticks = uint64(C.sysconf(C._SC_CLK_TCK)) - system.pagesize = uint64(os.Getpagesize()) -} - -// utmp can't be used by "encoding/binary" if generated by cgo, -// some pads will be explicitly missing. -type utmp struct { - User [256]uint8 - ID [14]uint8 - Line [64]uint8 - XPad1 int16 - Pid int32 - Type int16 - XPad2 int16 - Time int64 - Termination int16 - Exit int16 - Host [256]uint8 - XdblWordPad int32 - XreservedA [2]int32 - XreservedV [6]int32 -} - -func bootTime() (uint64, error) { - if system.btime != 0 { - return system.btime, nil - } - - // Get boot time from /etc/utmp - file, err := os.Open("/etc/utmp") - if err != nil { - return 0, fmt.Errorf("error while opening /etc/utmp: %s", err) - } - - defer file.Close() - - for { - var utmp utmp - if err := binary.Read(file, binary.BigEndian, &utmp); err != nil { - break - } - - if utmp.Type == C.BOOT_TIME { - system.btime = uint64(utmp.Time) - break - } - } - return system.btime, nil -} - -func tick2msec(val uint64) uint64 { - return val * 1000 / system.ticks -} - -// Get returns the list of file systems -func (self *FileSystemList) Get() error { - var size C.int - _, err := C.mntctl(C.MCTL_QUERY, C.sizeof_int, (*C.char)(unsafe.Pointer(&size))) - if err != nil { - return fmt.Errorf("error while retrieving file system number: %s", err) - } - - buf := make([]byte, size) - num, err := C.mntctl(C.MCTL_QUERY, C.ulong(size), (*C.char)(&buf[0])) - if err != nil { - return fmt.Errorf("error while retrieving file system list: %s", err) - } - - // Vmount structure has a fixed size area for common data (type, - // offsets, etc) and another area with variable length data (devname, - // options, etc). These data can be accessed based on the offsets - // stored in an array inside the fixed part. They can be retrieve - // using index given by C define. - vmt2data := func(buf []byte, ent *C.struct_vmount, idx int, baseOff int) []byte { - off := int(ent.vmt_data[idx].vmt_off) - size := int(ent.vmt_data[idx].vmt_size) - return buf[baseOff+off : baseOff+off+size] - } - - entOff := 0 - - fslist := make([]FileSystem, num) - for i := 0; i < int(num); i++ { - ent := (*C.struct_vmount)(unsafe.Pointer(&buf[entOff])) - fs := &fslist[i] - - // Correspondances taken for /etc/vfs - switch ent.vmt_gfstype { - case C.MNT_AIX: - fs.SysTypeName = "jfs2" - case C.MNT_NAMEFS: - fs.SysTypeName = "namefs" - case C.MNT_NFS: - fs.SysTypeName = "nfs" - case C.MNT_JFS: - fs.SysTypeName = "jfs" - case C.MNT_CDROM: - fs.SysTypeName = "cdrom" - case C.MNT_PROCFS: - fs.SysTypeName = "proc" - case C.MNT_SFS: - fs.SysTypeName = "sfs" - case C.MNT_CACHEFS: - fs.SysTypeName = "cachefs" - case C.MNT_NFS3: - fs.SysTypeName = "nfs3" - case C.MNT_AUTOFS: - fs.SysTypeName = "autofs" - case C.MNT_POOLFS: - fs.SysTypeName = "poolfs" - case C.MNT_UDF: - fs.SysTypeName = "udfs" - case C.MNT_NFS4: - fs.SysTypeName = "nfs4" - case C.MNT_CIFS: - fs.SysTypeName = "cifs" - case C.MNT_PMEMFS: - fs.SysTypeName = "pmemfs" - case C.MNT_AHAFS: - fs.SysTypeName = "ahafs" - case C.MNT_STNFS: - fs.SysTypeName = "stnfs" - default: - if ent.vmt_flags&C.MNT_REMOTE != 0 { - fs.SysTypeName = "network" - } else { - fs.SysTypeName = "none" - } - } - - fs.DirName = convertBytesToString(vmt2data(buf, ent, C.VMT_STUB, entOff)) - fs.Options = convertBytesToString(vmt2data(buf, ent, C.VMT_ARGS, entOff)) - devname := convertBytesToString(vmt2data(buf, ent, C.VMT_OBJECT, entOff)) - if ent.vmt_flags&C.MNT_REMOTE != 0 { - hostname := convertBytesToString(vmt2data(buf, ent, C.VMT_OBJECT, entOff)) - fs.DevName = hostname + ":" + devname - } else { - fs.DevName = devname - } - - entOff += int(ent.vmt_length) - } - - self.List = fslist - - return nil -} - -// Get returns the CPU load average -func (self *LoadAverage) Get() error { - cpudata := C.perfstat_cpu_total_t{} - - if _, err := C.perfstat_cpu_total(nil, &cpudata, C.sizeof_perfstat_cpu_total_t, 1); err != nil { - return fmt.Errorf("perfstat_cpu_total: %s", err) - } - - // from libperfstat.h: - // "To calculate the load average, divide the numbers by (1<." - fixedToFloat64 := func(x uint64) float64 { - return float64(x) / (1 << C.SBITS) - } - self.One = fixedToFloat64(uint64(cpudata.loadavg[0])) - self.Five = fixedToFloat64(uint64(cpudata.loadavg[1])) - self.Fifteen = fixedToFloat64(uint64(cpudata.loadavg[2])) - - return nil -} - -// Get returns the system uptime -func (self *Uptime) Get() error { - btime, err := bootTime() - if err != nil { - return err - } - uptime := time.Now().Sub(time.Unix(int64(btime), 0)) - self.Length = uptime.Seconds() - return nil -} - -// Get returns the current system memory -func (self *Mem) Get() error { - meminfo := C.perfstat_memory_total_t{} - _, err := C.perfstat_memory_total(nil, &meminfo, C.sizeof_perfstat_memory_total_t, 1) - if err != nil { - return fmt.Errorf("perfstat_memory_total: %s", err) - } - - self.Total = uint64(meminfo.real_total) * system.pagesize - self.Free = uint64(meminfo.real_free) * system.pagesize - - kern := uint64(meminfo.numperm) * system.pagesize // number of pages in file cache - - self.Used = self.Total - self.Free - self.ActualFree = self.Free + kern - self.ActualUsed = self.Used - kern - - return nil -} - -// Get returns the current system swap memory -func (self *Swap) Get() error { - ps := C.perfstat_pagingspace_t{} - id := C.perfstat_id_t{} - - id.name[0] = 0 - - for { - // errno can be set during perfstat_pagingspace's call even - // if it succeeds. Thus, only check it when the result is -1. - if r, err := C.perfstat_pagingspace(&id, &ps, C.sizeof_perfstat_pagingspace_t, 1); r == -1 && err != nil { - return fmt.Errorf("perfstat_memory_total: %s", err) - } - - if ps.active != 1 { - continue - } - - // convert MB sizes to bytes - self.Total += uint64(ps.mb_size) * 1024 * 1024 - self.Used += uint64(ps.mb_used) * 1024 * 1024 - - if id.name[0] == 0 { - break - } - } - - self.Free = self.Total - self.Used - - return nil -} - -// Get returns information about a CPU -func (self *Cpu) Get() error { - cpudata := C.perfstat_cpu_total_t{} - - if _, err := C.perfstat_cpu_total(nil, &cpudata, C.sizeof_perfstat_cpu_total_t, 1); err != nil { - return fmt.Errorf("perfstat_cpu_total: %s", err) - } - - self.User = tick2msec(uint64(cpudata.user)) - self.Sys = tick2msec(uint64(cpudata.sys)) - self.Idle = tick2msec(uint64(cpudata.idle)) - self.Wait = tick2msec(uint64(cpudata.wait)) - - return nil -} - -// Get returns the list of CPU used by the system -func (self *CpuList) Get() error { - cpudata := C.perfstat_cpu_t{} - id := C.perfstat_id_t{} - id.name[0] = 0 - - // Retrieve the number of cpu using perfstat_cpu - capacity, err := C.perfstat_cpu(nil, nil, C.sizeof_perfstat_cpu_t, 0) - if err != nil { - return fmt.Errorf("error while retrieving CPU number: %s", err) - } - list := make([]Cpu, 0, capacity) - - for { - if _, err := C.perfstat_cpu(&id, &cpudata, C.sizeof_perfstat_cpu_t, 1); err != nil { - return fmt.Errorf("perfstat_cpu: %s", err) - } - - cpu := Cpu{} - cpu.User = tick2msec(uint64(cpudata.user)) - cpu.Sys = tick2msec(uint64(cpudata.sys)) - cpu.Idle = tick2msec(uint64(cpudata.idle)) - cpu.Wait = tick2msec(uint64(cpudata.wait)) - - list = append(list, cpu) - - if id.name[0] == 0 { - break - } - } - - self.List = list - - return nil -} - -// Get returns the list of all active processes -func (self *ProcList) Get() error { - info := C.struct_procsinfo64{} - pid := C.pid_t(0) - - var list []int - - for { - // getprocs first argument is a void* - num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &pid, 1) - if err != nil { - return err - } - - list = append(list, int(info.pi_pid)) - - if num == 0 { - break - } - } - - self.List = list - - return nil -} - -// Get returns information about a process -func (self *ProcState) Get(pid int) error { - info := C.struct_procsinfo64{} - cpid := C.pid_t(pid) - - num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1) - if err != nil { - return err - } - if num != 1 { - return syscall.ESRCH - } - - self.Name = C.GoString(&info.pi_comm[0]) - self.Ppid = int(info.pi_ppid) - self.Pgid = int(info.pi_pgrp) - self.Nice = int(info.pi_nice) - self.Tty = int(info.pi_ttyd) - self.Priority = int(info.pi_pri) - - switch info.pi_state { - case C.SACTIVE: - self.State = RunStateRun - case C.SIDL: - self.State = RunStateIdle - case C.SSTOP: - self.State = RunStateStop - case C.SZOMB: - self.State = RunStateZombie - case C.SSWAP: - self.State = RunStateSleep - default: - self.State = RunStateUnknown - } - - // Get process username. Fallback to UID if username is not available. - uid := strconv.Itoa(int(info.pi_uid)) - userID, err := user.LookupId(uid) - if err == nil && userID.Username != "" { - self.Username = userID.Username - } else { - self.Username = uid - } - - thrinfo := C.struct_thrdsinfo64{} - tid := C.tid_t(0) - - if _, err := C.getthrds(cpid, unsafe.Pointer(&thrinfo), C.sizeof_struct_thrdsinfo64, &tid, 1); err != nil { - self.Processor = int(thrinfo.ti_affinity) - } - - return nil -} - -//Get returns the current memory usage of a process -func (self *ProcMem) Get(pid int) error { - info := C.struct_procsinfo64{} - cpid := C.pid_t(pid) - - num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1) - if err != nil { - return err - } - if num != 1 { - return syscall.ESRCH - } - - self.Size = uint64(info.pi_size) * system.pagesize - self.Share = uint64(info.pi_sdsize) * system.pagesize - self.Resident = uint64(info.pi_drss+info.pi_trss) * system.pagesize - - self.MinorFaults = uint64(info.pi_minflt) - self.MajorFaults = uint64(info.pi_majflt) - self.PageFaults = self.MinorFaults + self.MajorFaults - - return nil -} - -// Get returns a process uptime -func (self *ProcTime) Get(pid int) error { - info := C.struct_procsinfo64{} - cpid := C.pid_t(pid) - - num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1) - if err != nil { - return err - } - if num != 1 { - return syscall.ESRCH - } - - self.StartTime = uint64(info.pi_start) * 1000 - self.User = uint64(info.pi_utime) * 1000 - self.Sys = uint64(info.pi_stime) * 1000 - self.Total = self.User + self.Sys - - return nil -} - -// Get returns arguments of a process -func (self *ProcArgs) Get(pid int) error { - /* If buffer is not large enough, args are truncated */ - buf := make([]byte, 8192) - info := C.struct_procsinfo64{} - info.pi_pid = C.pid_t(pid) - - if _, err := C.getargs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil { - return err - } - - bbuf := bytes.NewBuffer(buf) - - var args []string - - for { - arg, err := bbuf.ReadBytes(0) - if err == io.EOF || arg[0] == 0 { - break - } - if err != nil { - return err - } - - args = append(args, string(chop(arg))) - } - - self.List = args - return nil -} - -// Get returns the environment of a process -func (self *ProcEnv) Get(pid int) error { - if self.Vars == nil { - self.Vars = map[string]string{} - } - - /* If buffer is not large enough, args are truncated */ - buf := make([]byte, 8192) - info := C.struct_procsinfo64{} - info.pi_pid = C.pid_t(pid) - - if _, err := C.getevars(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil { - return err - } - - bbuf := bytes.NewBuffer(buf) - - delim := []byte{61} // "=" - - for { - line, err := bbuf.ReadBytes(0) - if err == io.EOF || line[0] == 0 { - break - } - if err != nil { - return err - } - - pair := bytes.SplitN(chop(line), delim, 2) - if len(pair) != 2 { - return fmt.Errorf("Error reading process environment for PID: %d", pid) - } - self.Vars[string(pair[0])] = string(pair[1]) - } - - return nil -} - -// Get returns the path of the process executable -func (self *ProcExe) Get(pid int) error { - /* If buffer is not large enough, args are truncated */ - buf := make([]byte, 8192) - info := C.struct_procsinfo64{} - info.pi_pid = C.pid_t(pid) - - if _, err := C.getargs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil { - return err - } - - bbuf := bytes.NewBuffer(buf) - - // retrieve the first argument - cmd, err := bbuf.ReadBytes(0) - if err != nil { - return err - } - self.Name = string(chop(cmd)) - - cwd, err := os.Readlink("/proc/" + strconv.Itoa(pid) + "/cwd") - if err != nil { - if !os.IsNotExist(err) { - return err - } - } - self.Cwd = cwd - - return nil -} - -// Get returns process filesystem usage. Not implimented on AIX. -func (*ProcFDUsage) Get(_ int) error { - return ErrNotImplemented{runtime.GOOS} -} - -// Get returns filesytem usage. Not implimented on AIX. -func (*FDUsage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -// Get returns huge pages info. Not implimented on AIX. -func (*HugeTLBPages) Get() error { - return ErrNotImplemented{runtime.GOOS} -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin.go b/cockroach/patches/github.com/elastic/gosigar/sigar_darwin.go deleted file mode 100644 index 0edebd1..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin.go +++ /dev/null @@ -1,502 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package gosigar - -/* -#include -#include -#include -#include -#include -#include -#include -#include -#include -*/ -import "C" - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" - "os/user" - "runtime" - "strconv" - "syscall" - "time" - "unsafe" -) - -// Get fetches LoadAverage data -func (self *LoadAverage) Get() error { - avg := []C.double{0, 0, 0} - - C.getloadavg(&avg[0], C.int(len(avg))) - - self.One = float64(avg[0]) - self.Five = float64(avg[1]) - self.Fifteen = float64(avg[2]) - - return nil -} - -// Get fetches memory data -func (self *Mem) Get() error { - var vmstat C.vm_statistics_data_t - - if err := sysctlbyname("hw.memsize", &self.Total); err != nil { - return err - } - - if err := vmInfo(&vmstat); err != nil { - return err - } - - kern := uint64(vmstat.inactive_count) << 12 - self.Free = uint64(vmstat.free_count) << 12 - - self.Used = self.Total - self.Free - self.ActualFree = self.Free + kern - self.ActualUsed = self.Used - kern - - return nil -} - -type xswUsage struct { - Total, Avail, Used uint64 -} - -// Get fetches swap data -func (self *Swap) Get() error { - swUsage := xswUsage{} - - if err := sysctlbyname("vm.swapusage", &swUsage); err != nil { - return err - } - - self.Total = swUsage.Total - self.Used = swUsage.Used - self.Free = swUsage.Avail - - return nil -} - -// Get fetches hugepages data -func (self *HugeTLBPages) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -// Get fetches CPU data -func (self *Cpu) Get() error { - var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT - var cpuload C.host_cpu_load_info_data_t - - status := C.host_statistics(C.host_t(C.mach_host_self()), - C.HOST_CPU_LOAD_INFO, - C.host_info_t(unsafe.Pointer(&cpuload)), - &count) - - if status != C.KERN_SUCCESS { - return fmt.Errorf("host_statistics error=%d", status) - } - - self.User = uint64(cpuload.cpu_ticks[C.CPU_STATE_USER]) - self.Sys = uint64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) - self.Idle = uint64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) - self.Nice = uint64(cpuload.cpu_ticks[C.CPU_STATE_NICE]) - - return nil -} - -// Get fetches CPU list data -func (self *CpuList) Get() error { - var count C.mach_msg_type_number_t - var cpuload *C.processor_cpu_load_info_data_t - var ncpu C.natural_t - - status := C.host_processor_info(C.host_t(C.mach_host_self()), - C.PROCESSOR_CPU_LOAD_INFO, - &ncpu, - (*C.processor_info_array_t)(unsafe.Pointer(&cpuload)), - &count) - - if status != C.KERN_SUCCESS { - return fmt.Errorf("host_processor_info error=%d", status) - } - - // jump through some cgo casting hoops and ensure we properly free - // the memory that cpuload points to - target := C.vm_map_t(C.mach_task_self_) - address := C.vm_address_t(uintptr(unsafe.Pointer(cpuload))) - defer C.vm_deallocate(target, address, C.vm_size_t(ncpu)) - - // the body of struct processor_cpu_load_info - // aka processor_cpu_load_info_data_t - var cpuTicks [C.CPU_STATE_MAX]uint32 - - // copy the cpuload array to a []byte buffer - // where we can binary.Read the data - size := int(ncpu) * binary.Size(cpuTicks) - buf := C.GoBytes(unsafe.Pointer(cpuload), C.int(size)) - - bbuf := bytes.NewBuffer(buf) - - self.List = make([]Cpu, 0, ncpu) - - for i := 0; i < int(ncpu); i++ { - cpu := Cpu{} - - err := binary.Read(bbuf, binary.LittleEndian, &cpuTicks) - if err != nil { - return err - } - - cpu.User = uint64(cpuTicks[C.CPU_STATE_USER]) - cpu.Sys = uint64(cpuTicks[C.CPU_STATE_SYSTEM]) - cpu.Idle = uint64(cpuTicks[C.CPU_STATE_IDLE]) - cpu.Nice = uint64(cpuTicks[C.CPU_STATE_NICE]) - - self.List = append(self.List, cpu) - } - - return nil -} - -// Get returns FD usage data -func (self *FDUsage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -// Get returns filesystem data -func (self *FileSystemList) Get() error { - num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT) - if err != nil { - return err - } - - buf := make([]syscall.Statfs_t, num) - - _, err = syscall.Getfsstat(buf, C.MNT_NOWAIT) - if err != nil { - return err - } - - fslist := make([]FileSystem, 0, num) - - for i := 0; i < num; i++ { - fs := FileSystem{} - fmt.Printf("Got Raw buffer: %#v\n", buf[i].Fstypename) - fs.DirName = byteListToString(buf[i].Mntonname[:]) - fs.DevName = byteListToString(buf[i].Mntfromname[:]) - fs.SysTypeName = byteListToString(buf[i].Fstypename[:]) - - fslist = append(fslist, fs) - } - - self.List = fslist - - return err -} - -// Get returns a process list -func (self *ProcList) Get() error { - n := C.proc_listpids(C.PROC_ALL_PIDS, 0, nil, 0) - if n <= 0 { - return syscall.EINVAL - } - buf := make([]byte, n) - n = C.proc_listpids(C.PROC_ALL_PIDS, 0, unsafe.Pointer(&buf[0]), n) - if n <= 0 { - return syscall.ENOMEM - } - - var pid int32 - num := int(n) / binary.Size(pid) - list := make([]int, 0, num) - bbuf := bytes.NewBuffer(buf) - - for i := 0; i < num; i++ { - if err := binary.Read(bbuf, binary.LittleEndian, &pid); err != nil { - return err - } - if pid == 0 { - continue - } - - list = append(list, int(pid)) - } - - self.List = list - - return nil -} - -// Get returns process state data -func (self *ProcState) Get(pid int) error { - info := C.struct_proc_taskallinfo{} - - if err := taskInfo(pid, &info); err != nil { - return err - } - - self.Name = C.GoString(&info.pbsd.pbi_comm[0]) - - switch info.pbsd.pbi_status { - case C.SIDL: - self.State = RunStateIdle - case C.SRUN: - self.State = RunStateRun - case C.SSLEEP: - self.State = RunStateSleep - case C.SSTOP: - self.State = RunStateStop - case C.SZOMB: - self.State = RunStateZombie - default: - self.State = RunStateUnknown - } - - self.Ppid = int(info.pbsd.pbi_ppid) - - self.Pgid = int(info.pbsd.pbi_pgid) - - self.Tty = int(info.pbsd.e_tdev) - - self.Priority = int(info.ptinfo.pti_priority) - - self.Nice = int(info.pbsd.pbi_nice) - - // Get process username. Fallback to UID if username is not available. - uid := strconv.Itoa(int(info.pbsd.pbi_uid)) - user, err := user.LookupId(uid) - if err == nil && user.Username != "" { - self.Username = user.Username - } else { - self.Username = uid - } - - return nil -} - -// Get returns process memory data -func (self *ProcMem) Get(pid int) error { - info := C.struct_proc_taskallinfo{} - - if err := taskInfo(pid, &info); err != nil { - return err - } - - self.Size = uint64(info.ptinfo.pti_virtual_size) - self.Resident = uint64(info.ptinfo.pti_resident_size) - self.PageFaults = uint64(info.ptinfo.pti_faults) - - return nil -} - -// Get returns process time data -func (self *ProcTime) Get(pid int) error { - info := C.struct_proc_taskallinfo{} - - if err := taskInfo(pid, &info); err != nil { - return err - } - - self.User = - uint64(info.ptinfo.pti_total_user) / uint64(time.Millisecond) - - self.Sys = - uint64(info.ptinfo.pti_total_system) / uint64(time.Millisecond) - - self.Total = self.User + self.Sys - - self.StartTime = (uint64(info.pbsd.pbi_start_tvsec) * 1000) + - (uint64(info.pbsd.pbi_start_tvusec) / 1000) - - return nil -} - -// Get returns process arg data -func (self *ProcArgs) Get(pid int) error { - var args []string - - argv := func(arg string) { - args = append(args, arg) - } - - err := kernProcargs(pid, nil, argv, nil) - - self.List = args - - return err -} - -// Get returns process environment data -func (self *ProcEnv) Get(pid int) error { - if self.Vars == nil { - self.Vars = map[string]string{} - } - - env := func(k, v string) { - self.Vars[k] = v - } - - return kernProcargs(pid, nil, nil, env) -} - -// Get returns process exec data -func (self *ProcExe) Get(pid int) error { - exe := func(arg string) { - self.Name = arg - } - - return kernProcargs(pid, exe, nil, nil) -} - -// Get returns process file usage -func (self *ProcFDUsage) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -// kernProcargs is a wrapper around sysctl KERN_PROCARGS2 -// callbacks params are optional, -// up to the caller as to which pieces of data they want -func kernProcargs(pid int, - exe func(string), - argv func(string), - env func(string, string)) error { - - mib := []C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)} - argmax := uintptr(C.ARG_MAX) - buf := make([]byte, argmax) - err := sysctl(mib, &buf[0], &argmax, nil, 0) - if err != nil { - return nil - } - - bbuf := bytes.NewBuffer(buf) - bbuf.Truncate(int(argmax)) - - var argc int32 - binary.Read(bbuf, binary.LittleEndian, &argc) - - path, err := bbuf.ReadBytes(0) - if err != nil { - return fmt.Errorf("Error reading the argv[0]: %v", err) - } - if exe != nil { - exe(string(chop(path))) - } - - // skip trailing \0's - for { - c, err := bbuf.ReadByte() - if err != nil { - return fmt.Errorf("Error skipping nils: %v", err) - } - if c != 0 { - bbuf.UnreadByte() - break // start of argv[0] - } - } - - for i := 0; i < int(argc); i++ { - arg, err := bbuf.ReadBytes(0) - if err == io.EOF { - break - } - if err != nil { - return fmt.Errorf("Error reading args: %v", err) - } - if argv != nil { - argv(string(chop(arg))) - } - } - - if env == nil { - return nil - } - - delim := []byte{61} // "=" - - for { - line, err := bbuf.ReadBytes(0) - if err == io.EOF || line[0] == 0 { - break - } - if err != nil { - return fmt.Errorf("Error reading args: %v", err) - } - pair := bytes.SplitN(chop(line), delim, 2) - - if len(pair) != 2 { - return fmt.Errorf("Error reading process information for PID: %d", pid) - } - - env(string(pair[0]), string(pair[1])) - } - - return nil -} - -// XXX copied from zsyscall_darwin_amd64.go -func sysctl(mib []C.int, old *byte, oldlen *uintptr, - new *byte, newlen uintptr) (err error) { - var p0 unsafe.Pointer - p0 = unsafe.Pointer(&mib[0]) - _, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p0), - uintptr(len(mib)), - uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), - uintptr(unsafe.Pointer(new)), uintptr(newlen)) - if e1 != 0 { - err = e1 - } - return -} - -func vmInfo(vmstat *C.vm_statistics_data_t) error { - var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT - - status := C.host_statistics( - C.host_t(C.mach_host_self()), - C.HOST_VM_INFO, - C.host_info_t(unsafe.Pointer(vmstat)), - &count) - - if status != C.KERN_SUCCESS { - return fmt.Errorf("host_statistics=%d", status) - } - - return nil -} - -// generic Sysctl buffer unmarshalling -func sysctlbyname(name string, data interface{}) (err error) { - val, err := syscall.Sysctl(name) - if err != nil { - return err - } - - buf := []byte(val) - - switch v := data.(type) { - case *uint64: - *v = *(*uint64)(unsafe.Pointer(&buf[0])) - return - } - - bbuf := bytes.NewBuffer([]byte(val)) - return binary.Read(bbuf, binary.LittleEndian, data) -} - -func taskInfo(pid int, info *C.struct_proc_taskallinfo) error { - size := C.int(unsafe.Sizeof(*info)) - ptr := unsafe.Pointer(info) - - n := C.proc_pidinfo(C.int(pid), C.PROC_PIDTASKALLINFO, 0, ptr, size) - if n != size { - return fmt.Errorf("Could not read process info for pid %d", pid) - } - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_386.go b/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_386.go deleted file mode 100644 index 92c7ff0..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_386.go +++ /dev/null @@ -1,18 +0,0 @@ -package gosigar - -import ( - "syscall" - "time" -) - -func (self *Uptime) Get() error { - tv := syscall.Timeval{} - - if err := sysctlbyname("kern.boottime", &tv); err != nil { - return err - } - - self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds() - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_amd64.go b/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_amd64.go deleted file mode 100644 index 29e5b60..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_amd64.go +++ /dev/null @@ -1,18 +0,0 @@ -package gosigar - -import ( - "syscall" - "time" -) - -func (self *Uptime) Get() error { - tv := syscall.Timeval32{} - - if err := sysctlbyname("kern.boottime", &tv); err != nil { - return err - } - - self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds() - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_test.go b/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_test.go deleted file mode 100644 index 8650491..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_darwin_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package gosigar_test - -import ( - "bufio" - "bytes" - "fmt" - "os/exec" - "os/user" - "strconv" - "strings" - "testing" - - sigar "github.com/elastic/gosigar" - "github.com/stretchr/testify/assert" -) - -var procinfo map[string]string - -func setUp(t testing.TB) { - out, err := exec.Command("/bin/ps", "-p1", "-c", "-opid,comm,stat,ppid,pgid,tty,pri,ni").Output() - if err != nil { - t.Fatal(err) - } - rdr := bufio.NewReader(bytes.NewReader(out)) - _, err = rdr.ReadString('\n') // skip header - if err != nil { - t.Fatal(err) - } - data, err := rdr.ReadString('\n') - if err != nil { - t.Fatal(err) - } - procinfo = make(map[string]string, 8) - fields := strings.Fields(data) - procinfo["pid"] = fields[0] - procinfo["name"] = fields[1] - procinfo["stat"] = fields[2] - procinfo["ppid"] = fields[3] - procinfo["pgid"] = fields[4] - procinfo["tty"] = fields[5] - procinfo["prio"] = fields[6] - procinfo["nice"] = fields[7] - -} - -func tearDown(t testing.TB) { -} - -/* ProcState.Get() call task_info, which on Mac OS X requires root - or a signed executable. Skip the test if not running as root - to accommodate automated tests, but let users test locally using - `sudo -E go test` -*/ - -func TestDarwinProcState(t *testing.T) { - setUp(t) - defer tearDown(t) - - state := sigar.ProcState{} - usr, err := user.Current() - if err == nil && usr.Username == "root" { - if assert.NoError(t, state.Get(1)) { - - ppid, _ := strconv.Atoi(procinfo["ppid"]) - pgid, _ := strconv.Atoi(procinfo["pgid"]) - - assert.Equal(t, procinfo["name"], state.Name) - assert.Equal(t, ppid, state.Ppid) - assert.Equal(t, pgid, state.Pgid) - assert.Equal(t, 1, state.Pgid) - assert.Equal(t, 0, state.Ppid) - } - } else { - fmt.Println("Skipping ProcState test; run as root to test") - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_format.go b/cockroach/patches/github.com/elastic/gosigar/sigar_format.go deleted file mode 100644 index ac56c98..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_format.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package gosigar - -import ( - "bufio" - "bytes" - "fmt" - "strconv" - "time" -) - -// Go version of apr_strfsize -func FormatSize(size uint64) string { - ord := []string{"K", "M", "G", "T", "P", "E"} - o := 0 - buf := new(bytes.Buffer) - w := bufio.NewWriter(buf) - - if size < 973 { - fmt.Fprintf(w, "%3d ", size) - w.Flush() - return buf.String() - } - - for { - remain := size & 1023 - size >>= 10 - - if size >= 973 { - o++ - continue - } - - if size < 9 || (size == 9 && remain < 973) { - remain = ((remain * 5) + 256) / 512 - if remain >= 10 { - size++ - remain = 0 - } - - fmt.Fprintf(w, "%d.%d%s", size, remain, ord[o]) - break - } - - if remain >= 512 { - size++ - } - - fmt.Fprintf(w, "%3d%s", size, ord[o]) - break - } - - w.Flush() - return buf.String() -} - -func FormatPercent(percent float64) string { - return strconv.FormatFloat(percent, 'f', -1, 64) + "%" -} - -func (self *FileSystemUsage) UsePercent() float64 { - b_used := (self.Total - self.Free) / 1024 - b_avail := self.Avail / 1024 - utotal := b_used + b_avail - used := b_used - - if utotal != 0 { - u100 := used * 100 - pct := u100 / utotal - if u100%utotal != 0 { - pct += 1 - } - return (float64(pct) / float64(100)) * 100.0 - } - - return 0.0 -} - -func (self *Uptime) Format() string { - buf := new(bytes.Buffer) - w := bufio.NewWriter(buf) - uptime := uint64(self.Length) - - days := uptime / (60 * 60 * 24) - - if days != 0 { - s := "" - if days > 1 { - s = "s" - } - fmt.Fprintf(w, "%d day%s, ", days, s) - } - - minutes := uptime / 60 - hours := minutes / 60 - hours %= 24 - minutes %= 60 - - fmt.Fprintf(w, "%2d:%02d", hours, minutes) - - w.Flush() - return buf.String() -} - -func (self *ProcTime) FormatStartTime() string { - if self.StartTime == 0 { - return "00:00" - } - start := time.Unix(int64(self.StartTime)/1000, 0) - format := "Jan02" - if time.Since(start).Seconds() < (60 * 60 * 24) { - format = "15:04" - } - return start.Format(format) -} - -func (self *ProcTime) FormatTotal() string { - t := self.Total / 1000 - ss := t % 60 - t /= 60 - mm := t % 60 - t /= 60 - hh := t % 24 - return fmt.Sprintf("%02d:%02d:%02d", hh, mm, ss) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_freebsd.go b/cockroach/patches/github.com/elastic/gosigar/sigar_freebsd.go deleted file mode 100644 index 51dd84a..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_freebsd.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copied and modified from sigar_linux.go. - -package gosigar - -import ( - "io/ioutil" - "runtime" - "strconv" - "strings" - "unsafe" -) - -/* -#include -#include -#include -#include -#include -#include -#include -#include -#include -*/ -import "C" - -func init() { - system.ticks = uint64(C.sysconf(C._SC_CLK_TCK)) - - Procd = "/compat/linux/proc" - - getLinuxBootTime() -} - -func getMountTableFileName() string { - return Procd + "/mtab" -} - -func (self *Uptime) Get() error { - ts := C.struct_timespec{} - - if _, err := C.clock_gettime(C.CLOCK_UPTIME, &ts); err != nil { - return err - } - - self.Length = float64(ts.tv_sec) + 1e-9*float64(ts.tv_nsec) - - return nil -} - -func (self *FDUsage) Get() error { - val := C.uint32_t(0) - sc := C.size_t(4) - - name := C.CString("kern.openfiles") - _, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) - C.free(unsafe.Pointer(name)) - if err != nil { - return err - } - self.Open = uint64(val) - - name = C.CString("kern.maxfiles") - _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) - C.free(unsafe.Pointer(name)) - if err != nil { - return err - } - self.Max = uint64(val) - - self.Unused = self.Max - self.Open - - return nil -} - -func (self *ProcFDUsage) Get(pid int) error { - err := readFile("/proc/"+strconv.Itoa(pid)+"/rlimit", func(line string) bool { - if strings.HasPrefix(line, "nofile") { - fields := strings.Fields(line) - if len(fields) == 3 { - self.SoftLimit, _ = strconv.ParseUint(fields[1], 10, 64) - self.HardLimit, _ = strconv.ParseUint(fields[2], 10, 64) - } - return false - } - return true - }) - if err != nil { - return err - } - - // linprocfs only provides this information for this process (self). - fds, err := ioutil.ReadDir(procFileName(pid, "fd")) - if err != nil { - return err - } - self.Open = uint64(len(fds)) - - return nil -} - -func (self *HugeTLBPages) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func parseCpuStat(self *Cpu, line string) error { - fields := strings.Fields(line) - - self.User, _ = strtoull(fields[1]) - self.Nice, _ = strtoull(fields[2]) - self.Sys, _ = strtoull(fields[3]) - self.Idle, _ = strtoull(fields[4]) - return nil -} - -func (self *Mem) Get() error { - val := C.uint32_t(0) - sc := C.size_t(4) - - name := C.CString("vm.stats.vm.v_page_count") - _, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) - C.free(unsafe.Pointer(name)) - if err != nil { - return err - } - pagecount := uint64(val) - - name = C.CString("vm.stats.vm.v_page_size") - _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) - C.free(unsafe.Pointer(name)) - if err != nil { - return err - } - pagesize := uint64(val) - - name = C.CString("vm.stats.vm.v_free_count") - _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) - C.free(unsafe.Pointer(name)) - if err != nil { - return err - } - self.Free = uint64(val) * pagesize - - name = C.CString("vm.stats.vm.v_inactive_count") - _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) - C.free(unsafe.Pointer(name)) - if err != nil { - return err - } - kern := uint64(val) - - self.Total = uint64(pagecount * pagesize) - - self.Used = self.Total - self.Free - self.ActualFree = self.Free + (kern * pagesize) - self.ActualUsed = self.Used - (kern * pagesize) - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_illumos.go b/cockroach/patches/github.com/elastic/gosigar/sigar_illumos.go deleted file mode 100644 index 08e361c..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_illumos.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2020 Oxide Computer Company - -package gosigar - -import ( - "runtime" - "strings" - - "golang.org/x/sys/unix" -) - -func (c *Cpu) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (l *LoadAverage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (m *Mem) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (s *Swap) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (s *HugeTLBPages) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (f *FDUsage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcTime) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *CpuList) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcState) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcExe) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcMem) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcFDUsage) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcEnv) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcList) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcArgs) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *Rusage) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *FileSystemList) Get() error { - capacity := len(self.List) - if capacity == 0 { - capacity = 10 - } - - fslist := make([]FileSystem, 0, capacity) - - err := readFile("/etc/mnttab", func(line string) bool { - fields := strings.Fields(line) - - fs := FileSystem{} - fs.DevName = fields[0] - fs.DirName = fields[1] - fs.SysTypeName = fields[2] - fs.Options = fields[3] - - fslist = append(fslist, fs) - - return true - }) - - if err == nil { - self.List = fslist - } - return err -} - -func (self *FileSystemUsage) Get(path string) error { - var fs unix.Statvfs_t - if err := unix.Statvfs(path, &fs); err != nil { - return err - } - - self.Total = uint64(fs.Blocks) * uint64(fs.Frsize) - self.Free = uint64(fs.Bfree) * uint64(fs.Frsize) - self.Avail = uint64(fs.Bavail) * uint64(fs.Frsize) - self.Used = self.Total - self.Free - self.Files = fs.Files - self.FreeFiles = fs.Ffree - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_interface.go b/cockroach/patches/github.com/elastic/gosigar/sigar_interface.go deleted file mode 100644 index 57501b9..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_interface.go +++ /dev/null @@ -1,239 +0,0 @@ -package gosigar - -import ( - "time" -) - -// ErrNotImplemented is returned when a particular statistic isn't implemented on the host OS. -type ErrNotImplemented struct { - OS string -} - -func (e ErrNotImplemented) Error() string { - return "not implemented on " + e.OS -} - -// IsNotImplemented returns true if the error is ErrNotImplemented -func IsNotImplemented(err error) bool { - switch err.(type) { - case ErrNotImplemented, *ErrNotImplemented: - return true - default: - return false - } -} - -// Sigar is an interface for gathering system host stats -type Sigar interface { - CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{}) - GetLoadAverage() (LoadAverage, error) - GetMem() (Mem, error) - GetSwap() (Swap, error) - GetHugeTLBPages(HugeTLBPages, error) - GetFileSystemUsage(string) (FileSystemUsage, error) - GetFDUsage() (FDUsage, error) - GetRusage(who int) (Rusage, error) -} - -// Cpu contains CPU time stats -type Cpu struct { - User uint64 - Nice uint64 - Sys uint64 - Idle uint64 - Wait uint64 - Irq uint64 - SoftIrq uint64 - Stolen uint64 -} - -// Total returns total CPU time -func (cpu *Cpu) Total() uint64 { - return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle + - cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen -} - -// Delta returns the difference between two Cpu stat objects -func (cpu Cpu) Delta(other Cpu) Cpu { - return Cpu{ - User: cpu.User - other.User, - Nice: cpu.Nice - other.Nice, - Sys: cpu.Sys - other.Sys, - Idle: cpu.Idle - other.Idle, - Wait: cpu.Wait - other.Wait, - Irq: cpu.Irq - other.Irq, - SoftIrq: cpu.SoftIrq - other.SoftIrq, - Stolen: cpu.Stolen - other.Stolen, - } -} - -// LoadAverage reports standard load averages -type LoadAverage struct { - One, Five, Fifteen float64 -} - -// Uptime reports system uptime -type Uptime struct { - Length float64 -} - -// Mem contains host memory stats -type Mem struct { - Total uint64 - Used uint64 - Free uint64 - ActualFree uint64 - ActualUsed uint64 -} - -// Swap contains stats on swap space -type Swap struct { - Total uint64 - Used uint64 - Free uint64 -} - -// HugeTLBPages contains HugePages stats -type HugeTLBPages struct { - Total uint64 - Free uint64 - Reserved uint64 - Surplus uint64 - DefaultSize uint64 - TotalAllocatedSize uint64 -} - -// CpuList contains a list of CPUs on the host system -type CpuList struct { - List []Cpu -} - -// FDUsage contains stats on filesystem usage -type FDUsage struct { - Open uint64 - Unused uint64 - Max uint64 -} - -// FileSystem contains basic information about a given mounted filesystem -type FileSystem struct { - DirName string - DevName string - TypeName string - SysTypeName string - Options string - Flags uint32 -} - -// FileSystemList gets a list of mounted filesystems -type FileSystemList struct { - List []FileSystem -} - -// FileSystemUsage contains basic stats for the specified filesystem -type FileSystemUsage struct { - Total uint64 - Used uint64 - Free uint64 - Avail uint64 - Files uint64 - FreeFiles uint64 -} - -// ProcList contains a list of processes found on the host system -type ProcList struct { - List []int -} - -// RunState is a byte-long code used to specify the current runtime state of a process -type RunState byte - -const ( - // RunStateSleep corresponds to a sleep state - RunStateSleep = 'S' - // RunStateRun corresponds to a running state - RunStateRun = 'R' - // RunStateStop corresponds to a stopped state - RunStateStop = 'T' - // RunStateZombie marks a zombie process - RunStateZombie = 'Z' - // RunStateIdle corresponds to an idle state - RunStateIdle = 'D' - // RunStateUnknown corresponds to a process in an unknown state - RunStateUnknown = '?' -) - -// ProcState contains basic metadata and process ownership info for the specified process -type ProcState struct { - Name string - Username string - State RunState - Ppid int - Pgid int - Tty int - Priority int - Nice int - Processor int -} - -// ProcMem contains memory statistics for a specified process -type ProcMem struct { - Size uint64 - Resident uint64 - Share uint64 - MinorFaults uint64 - MajorFaults uint64 - PageFaults uint64 -} - -// ProcTime contains run time statistics for a specified process -type ProcTime struct { - StartTime uint64 - User uint64 - Sys uint64 - Total uint64 -} - -// ProcArgs contains a list of args for a specified process -type ProcArgs struct { - List []string -} - -// ProcEnv contains a map of environment variables for specified process -type ProcEnv struct { - Vars map[string]string -} - -// ProcExe contains basic data about a specified process -type ProcExe struct { - Name string - Cwd string - Root string -} - -// ProcFDUsage contains data on file limits and usage -type ProcFDUsage struct { - Open uint64 - SoftLimit uint64 - HardLimit uint64 -} - -// Rusage contains data on resource usage for a specified process -type Rusage struct { - Utime time.Duration - Stime time.Duration - Maxrss int64 - Ixrss int64 - Idrss int64 - Isrss int64 - Minflt int64 - Majflt int64 - Nswap int64 - Inblock int64 - Oublock int64 - Msgsnd int64 - Msgrcv int64 - Nsignals int64 - Nvcsw int64 - Nivcsw int64 -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_interface_test.go b/cockroach/patches/github.com/elastic/gosigar/sigar_interface_test.go deleted file mode 100644 index 5457387..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_interface_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package gosigar_test - -import ( - "os" - "os/user" - "path/filepath" - "runtime" - "strings" - "testing" - "time" - - . "github.com/elastic/gosigar" - "github.com/stretchr/testify/assert" -) - -const invalidPid = 666666 - -func TestCpu(t *testing.T) { - cpu := Cpu{} - assert.NoError(t, cpu.Get()) -} - -func TestLoadAverage(t *testing.T) { - avg := LoadAverage{} - assert.NoError(t, skipNotImplemented(t, avg.Get(), "windows")) -} - -func TestUptime(t *testing.T) { - uptime := Uptime{} - if assert.NoError(t, uptime.Get()) { - assert.True(t, uptime.Length > 0, "Uptime (%f) must be positive", uptime.Length) - } -} - -func TestMem(t *testing.T) { - mem := Mem{} - if assert.NoError(t, mem.Get()) { - assert.True(t, mem.Total > 0, "mem.Total (%d) must be positive", mem.Total) - assert.True(t, (mem.Used+mem.Free) <= mem.Total, - "mem.Used (%d) + mem.Free (%d) must <= mem.Total (%d)", - mem.Used, mem.Free, mem.Total) - } -} - -func TestSwap(t *testing.T) { - swap := Swap{} - if assert.NoError(t, swap.Get()) { - assert.True(t, (swap.Used+swap.Free) <= swap.Total, - "swap.Used (%d) + swap.Free (%d) must <= swap.Total (%d)", - swap.Used, swap.Free, swap.Total) - } -} - -func TestCpuList(t *testing.T) { - cpuList := CpuList{} - if assert.NoError(t, cpuList.Get()) { - numCore := len(cpuList.List) - numCpu := runtime.NumCPU() - assert.True(t, numCore >= numCpu, "Number of cores (%d) >= number of logical CPUs (%d)", - numCore, numCpu) - } -} - -func TestFileSystemList(t *testing.T) { - fsList := FileSystemList{} - if assert.NoError(t, fsList.Get()) { - assert.True(t, len(fsList.List) > 0) - } -} - -func TestFileSystemUsage(t *testing.T) { - root := "/" - if runtime.GOOS == "windows" { - root = `C:\` - } - fsusage := FileSystemUsage{} - if assert.NoError(t, fsusage.Get(root)) { - assert.True(t, fsusage.Total > 0) - } - assert.Error(t, fsusage.Get("T O T A L L Y B O G U S")) -} - -func TestProcList(t *testing.T) { - pids := ProcList{} - if assert.NoError(t, pids.Get()) { - assert.True(t, len(pids.List) > 2) - } -} - -func TestProcState(t *testing.T) { - u, err := user.Current() - if err != nil { - t.Fatal(err) - } - - state := ProcState{} - if assert.NoError(t, state.Get(os.Getppid())) { - assert.Contains(t, []RunState{RunStateRun, RunStateSleep}, state.State) - assert.Regexp(t, "go(.exe)?", state.Name) - assert.Equal(t, u.Username, state.Username) - assert.True(t, state.Ppid > 0, "ppid=%v is non-positive", state.Ppid) - } - assert.Error(t, state.Get(invalidPid)) -} - -func TestProcMem(t *testing.T) { - mem := ProcMem{} - assert.NoError(t, mem.Get(os.Getppid())) - - assert.Error(t, mem.Get(invalidPid)) -} - -func TestProcTime(t *testing.T) { - procTime := ProcTime{} - if assert.NoError(t, procTime.Get(os.Getppid())) { - // Sanity check the start time of the "go test" process. - delta := time.Now().Sub(time.Unix(0, int64(procTime.StartTime*uint64(time.Millisecond)))) - assert.True(t, delta > 0 && delta < 2*time.Minute, "ProcTime.StartTime differs by %v", delta) - } - - assert.Error(t, procTime.Get(invalidPid)) -} - -func TestProcArgs(t *testing.T) { - procArgs := ProcArgs{} - if assert.NoError(t, procArgs.Get(os.Getppid())) { - assert.NotEmpty(t, procArgs.List) - } - if runtime.GOOS != "darwin" { - assert.Error(t, procArgs.Get(invalidPid)) - } -} - -func TestProcEnv(t *testing.T) { - env := &ProcEnv{} - if assert.NoError(t, skipNotImplemented(t, env.Get(os.Getpid()), "windows", "openbsd")) { - assert.True(t, len(env.Vars) > 0, "env is empty") - - for k, v := range env.Vars { - assert.Equal(t, strings.TrimSpace(os.Getenv(k)), strings.TrimSpace(v)) - } - } -} - -func TestProcExe(t *testing.T) { - exe := ProcExe{} - if assert.NoError(t, skipNotImplemented(t, exe.Get(os.Getppid()), "windows")) { - assert.Regexp(t, "go(.exe)?", filepath.Base(exe.Name)) - } -} - -func skipNotImplemented(t testing.TB, err error, goos ...string) error { - for _, os := range goos { - if runtime.GOOS == os { - if err == nil { - t.Fatal("expected ErrNotImplemented") - } else if IsNotImplemented(err) { - t.Skipf("Skipping test on %s", runtime.GOOS) - } - - break - } - } - - return err -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_linux.go b/cockroach/patches/github.com/elastic/gosigar/sigar_linux.go deleted file mode 100644 index e04e8a9..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_linux.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package gosigar - -import ( - "io/ioutil" - "strconv" - "strings" - "syscall" -) - -func init() { - system.ticks = 100 // C.sysconf(C._SC_CLK_TCK) - - Procd = "/proc" - - getLinuxBootTime() -} - -func getMountTableFileName() string { - return "/etc/mtab" -} - -func (self *Uptime) Get() error { - sysinfo := syscall.Sysinfo_t{} - - if err := syscall.Sysinfo(&sysinfo); err != nil { - return err - } - - self.Length = float64(sysinfo.Uptime) - - return nil -} - -func (self *FDUsage) Get() error { - return readFile(Procd+"/sys/fs/file-nr", func(line string) bool { - fields := strings.Fields(line) - if len(fields) == 3 { - self.Open, _ = strconv.ParseUint(fields[0], 10, 64) - self.Unused, _ = strconv.ParseUint(fields[1], 10, 64) - self.Max, _ = strconv.ParseUint(fields[2], 10, 64) - } - return false - }) -} - -func (self *HugeTLBPages) Get() error { - table, err := parseMeminfo() - if err != nil { - return err - } - - self.Total, _ = table["HugePages_Total"] - self.Free, _ = table["HugePages_Free"] - self.Reserved, _ = table["HugePages_Rsvd"] - self.Surplus, _ = table["HugePages_Surp"] - self.DefaultSize, _ = table["Hugepagesize"] - - if totalSize, found := table["Hugetlb"]; found { - self.TotalAllocatedSize = totalSize - } else { - // If Hugetlb is not present, or huge pages of different sizes - // are used, this figure can be unaccurate. - // TODO (jsoriano): Extract information from /sys/kernel/mm/hugepages too - self.TotalAllocatedSize = (self.Total - self.Free + self.Reserved) * self.DefaultSize - } - - return nil -} - -func (self *ProcFDUsage) Get(pid int) error { - err := readFile(procFileName(pid, "limits"), func(line string) bool { - if strings.HasPrefix(line, "Max open files") { - fields := strings.Fields(line) - if len(fields) == 6 { - self.SoftLimit, _ = strconv.ParseUint(fields[3], 10, 64) - self.HardLimit, _ = strconv.ParseUint(fields[4], 10, 64) - } - return false - } - return true - }) - if err != nil { - return err - } - fds, err := ioutil.ReadDir(procFileName(pid, "fd")) - if err != nil { - return err - } - self.Open = uint64(len(fds)) - return nil -} - -func parseCpuStat(self *Cpu, line string) error { - fields := strings.Fields(line) - - self.User, _ = strtoull(fields[1]) - self.Nice, _ = strtoull(fields[2]) - self.Sys, _ = strtoull(fields[3]) - self.Idle, _ = strtoull(fields[4]) - self.Wait, _ = strtoull(fields[5]) - self.Irq, _ = strtoull(fields[6]) - self.SoftIrq, _ = strtoull(fields[7]) - self.Stolen, _ = strtoull(fields[8]) - - return nil -} - -func (self *Mem) Get() error { - - table, err := parseMeminfo() - if err != nil { - return err - } - - self.Total, _ = table["MemTotal"] - self.Free, _ = table["MemFree"] - buffers, _ := table["Buffers"] - cached, _ := table["Cached"] - - if available, ok := table["MemAvailable"]; ok { - // MemAvailable is in /proc/meminfo (kernel 3.14+) - self.ActualFree = available - } else { - self.ActualFree = self.Free + buffers + cached - } - - self.Used = self.Total - self.Free - self.ActualUsed = self.Total - self.ActualFree - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_linux_common.go b/cockroach/patches/github.com/elastic/gosigar/sigar_linux_common.go deleted file mode 100644 index 66d2807..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_linux_common.go +++ /dev/null @@ -1,436 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -// +build freebsd linux - -package gosigar - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "os/user" - "path/filepath" - "strconv" - "strings" - "syscall" -) - -var system struct { - ticks uint64 - btime uint64 -} - -var Procd string - -func getLinuxBootTime() { - // grab system boot time - readFile(Procd+"/stat", func(line string) bool { - if strings.HasPrefix(line, "btime") { - system.btime, _ = strtoull(line[6:]) - return false // stop reading - } - return true - }) -} - -func (self *LoadAverage) Get() error { - line, err := ioutil.ReadFile(Procd + "/loadavg") - if err != nil { - return nil - } - - fields := strings.Fields(string(line)) - - self.One, _ = strconv.ParseFloat(fields[0], 64) - self.Five, _ = strconv.ParseFloat(fields[1], 64) - self.Fifteen, _ = strconv.ParseFloat(fields[2], 64) - - return nil -} - -func (self *Swap) Get() error { - - table, err := parseMeminfo() - if err != nil { - return err - } - self.Total, _ = table["SwapTotal"] - self.Free, _ = table["SwapFree"] - - self.Used = self.Total - self.Free - return nil -} - -func (self *Cpu) Get() error { - return readFile(Procd+"/stat", func(line string) bool { - if len(line) > 4 && line[0:4] == "cpu " { - parseCpuStat(self, line) - return false - } - return true - - }) -} - -func (self *CpuList) Get() error { - capacity := len(self.List) - if capacity == 0 { - capacity = 4 - } - list := make([]Cpu, 0, capacity) - - err := readFile(Procd+"/stat", func(line string) bool { - if len(line) > 3 && line[0:3] == "cpu" && line[3] != ' ' { - cpu := Cpu{} - parseCpuStat(&cpu, line) - list = append(list, cpu) - } - return true - }) - - self.List = list - - return err -} - -func (self *FileSystemList) Get() error { - capacity := len(self.List) - if capacity == 0 { - capacity = 10 - } - fslist := make([]FileSystem, 0, capacity) - - err := readFile(getMountTableFileName(), func(line string) bool { - fields := strings.Fields(line) - - fs := FileSystem{} - fs.DevName = fields[0] - fs.DirName = fields[1] - fs.SysTypeName = fields[2] - fs.Options = fields[3] - - fslist = append(fslist, fs) - - return true - }) - - self.List = fslist - - return err -} - -func (self *ProcList) Get() error { - dir, err := os.Open(Procd) - if err != nil { - return err - } - defer dir.Close() - - const readAllDirnames = -1 // see os.File.Readdirnames doc - - names, err := dir.Readdirnames(readAllDirnames) - if err != nil { - return err - } - - capacity := len(names) - list := make([]int, 0, capacity) - - for _, name := range names { - if name[0] < '0' || name[0] > '9' { - continue - } - pid, err := strconv.Atoi(name) - if err == nil { - list = append(list, pid) - } - } - - self.List = list - - return nil -} - -func (self *ProcState) Get(pid int) error { - data, err := readProcFile(pid, "stat") - if err != nil { - return err - } - - // Extract the comm value with is surrounded by parentheses. - lIdx := bytes.Index(data, []byte("(")) - rIdx := bytes.LastIndex(data, []byte(")")) - if lIdx < 0 || rIdx < 0 || lIdx >= rIdx || rIdx+2 >= len(data) { - return fmt.Errorf("failed to extract comm for pid %d from '%v'", pid, string(data)) - } - self.Name = string(data[lIdx+1 : rIdx]) - - // Extract the rest of the fields that we are interested in. - fields := bytes.Fields(data[rIdx+2:]) - if len(fields) <= 36 { - return fmt.Errorf("expected more stat fields for pid %d from '%v'", pid, string(data)) - } - - interests := bytes.Join([][]byte{ - fields[0], // state - fields[1], // ppid - fields[2], // pgrp - fields[4], // tty_nr - fields[15], // priority - fields[16], // nice - fields[36], // processor (last processor executed on) - }, []byte(" ")) - - var state string - _, err = fmt.Fscan(bytes.NewBuffer(interests), - &state, - &self.Ppid, - &self.Pgid, - &self.Tty, - &self.Priority, - &self.Nice, - &self.Processor, - ) - if err != nil { - return fmt.Errorf("failed to parse stat fields for pid %d from '%v': %v", pid, string(data), err) - } - self.State = RunState(state[0]) - - // Read /proc/[pid]/status to get the uid, then lookup uid to get username. - status, err := getProcStatus(pid) - if err != nil { - return fmt.Errorf("failed to read process status for pid %d: %v", pid, err) - } - uids, err := getUIDs(status) - if err != nil { - return fmt.Errorf("failed to read process status for pid %d: %v", pid, err) - } - user, err := user.LookupId(uids[0]) - if err == nil { - self.Username = user.Username - } else { - self.Username = uids[0] - } - - return nil -} - -func (self *ProcMem) Get(pid int) error { - contents, err := readProcFile(pid, "statm") - if err != nil { - return err - } - - fields := strings.Fields(string(contents)) - - size, _ := strtoull(fields[0]) - self.Size = size << 12 - - rss, _ := strtoull(fields[1]) - self.Resident = rss << 12 - - share, _ := strtoull(fields[2]) - self.Share = share << 12 - - contents, err = readProcFile(pid, "stat") - if err != nil { - return err - } - - fields = strings.Fields(string(contents)) - - self.MinorFaults, _ = strtoull(fields[10]) - self.MajorFaults, _ = strtoull(fields[12]) - self.PageFaults = self.MinorFaults + self.MajorFaults - - return nil -} - -func (self *ProcTime) Get(pid int) error { - contents, err := readProcFile(pid, "stat") - if err != nil { - return err - } - - fields := strings.Fields(string(contents)) - - user, _ := strtoull(fields[13]) - sys, _ := strtoull(fields[14]) - // convert to millis - self.User = user * (1000 / system.ticks) - self.Sys = sys * (1000 / system.ticks) - self.Total = self.User + self.Sys - - // convert to millis - self.StartTime, _ = strtoull(fields[21]) - self.StartTime /= system.ticks - self.StartTime += system.btime - self.StartTime *= 1000 - - return nil -} - -func (self *ProcArgs) Get(pid int) error { - contents, err := readProcFile(pid, "cmdline") - if err != nil { - return err - } - - bbuf := bytes.NewBuffer(contents) - - var args []string - - for { - arg, err := bbuf.ReadBytes(0) - if err == io.EOF { - break - } - args = append(args, string(chop(arg))) - } - - self.List = args - - return nil -} - -func (self *ProcEnv) Get(pid int) error { - contents, err := readProcFile(pid, "environ") - if err != nil { - return err - } - - if self.Vars == nil { - self.Vars = map[string]string{} - } - - pairs := bytes.Split(contents, []byte{0}) - for _, kv := range pairs { - parts := bytes.SplitN(kv, []byte{'='}, 2) - if len(parts) != 2 { - continue - } - - key := string(bytes.TrimSpace(parts[0])) - if key == "" { - continue - } - - self.Vars[key] = string(bytes.TrimSpace(parts[1])) - } - - return nil -} - -func (self *ProcExe) Get(pid int) error { - fields := map[string]*string{ - "exe": &self.Name, - "cwd": &self.Cwd, - "root": &self.Root, - } - - for name, field := range fields { - val, err := os.Readlink(procFileName(pid, name)) - - if err != nil { - return err - } - - *field = val - } - - return nil -} - -func parseMeminfo() (map[string]uint64, error) { - table := map[string]uint64{} - - err := readFile(Procd+"/meminfo", func(line string) bool { - fields := strings.Split(line, ":") - - if len(fields) != 2 { - return true // skip on errors - } - - valueUnit := strings.Fields(fields[1]) - value, err := strtoull(valueUnit[0]) - if err != nil { - return true // skip on errors - } - - if len(valueUnit) > 1 && valueUnit[1] == "kB" { - value *= 1024 - } - table[fields[0]] = value - - return true - }) - return table, err -} - -func strtoull(val string) (uint64, error) { - return strconv.ParseUint(val, 10, 64) -} - -func procFileName(pid int, name string) string { - return Procd + "/" + strconv.Itoa(pid) + "/" + name -} - -func readProcFile(pid int, name string) (content []byte, err error) { - path := procFileName(pid, name) - - // Panics have been reported when reading proc files, let's recover and - // report the path if this happens - // See https://github.com/elastic/beats/issues/6692 - defer func() { - if r := recover(); r != nil { - content = nil - err = fmt.Errorf("recovered panic when reading proc file '%s': %v", path, r) - } - }() - contents, err := ioutil.ReadFile(path) - - if err != nil { - if perr, ok := err.(*os.PathError); ok { - if perr.Err == syscall.ENOENT { - return nil, syscall.ESRCH - } - } - } - - return contents, err -} - -// getProcStatus reads /proc/[pid]/status which contains process status -// information in human readable form. -func getProcStatus(pid int) (map[string]string, error) { - status := make(map[string]string, 42) - path := filepath.Join(Procd, strconv.Itoa(pid), "status") - err := readFile(path, func(line string) bool { - fields := strings.SplitN(line, ":", 2) - if len(fields) == 2 { - status[fields[0]] = strings.TrimSpace(fields[1]) - } - - return true - }) - return status, err -} - -// getUIDs reads the "Uid" value from status and splits it into four values -- -// real, effective, saved set, and file system UIDs. -func getUIDs(status map[string]string) ([]string, error) { - uidLine, ok := status["Uid"] - if !ok { - return nil, fmt.Errorf("Uid not found in proc status") - } - - uidStrs := strings.Fields(uidLine) - if len(uidStrs) != 4 { - return nil, fmt.Errorf("Uid line ('%s') did not contain four values", uidLine) - } - - return uidStrs, nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_linux_test.go b/cockroach/patches/github.com/elastic/gosigar/sigar_linux_test.go deleted file mode 100644 index f1075be..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_linux_test.go +++ /dev/null @@ -1,677 +0,0 @@ -package gosigar_test - -import ( - "fmt" - "io/ioutil" - "math/rand" - "os" - "path/filepath" - "strconv" - "testing" - "time" - - sigar "github.com/elastic/gosigar" - "github.com/stretchr/testify/assert" -) - -var procd string - -func setUp(t testing.TB) { - var err error - procd, err = ioutil.TempDir("", "sigarTests") - if err != nil { - t.Fatal(err) - } - sigar.Procd = procd -} - -func tearDown(t testing.TB) { - sigar.Procd = "/proc" - err := os.RemoveAll(procd) - if err != nil { - t.Fatal(err) - } -} - -func TestLinuxProcState(t *testing.T) { - setUp(t) - defer tearDown(t) - - var procNames = []string{ - "cron", - "a very long process name", - "(sd-pam)", - "]", - "(", - } - - for _, n := range procNames { - func() { - pid := rand.Int() - pidDir := filepath.Join(procd, strconv.Itoa(pid)) - err := os.Mkdir(pidDir, 0755) - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(pidDir) - pidStatFile := filepath.Join(pidDir, "stat") - writePidStats(pid, n, pidStatFile) - if err != nil { - t.Fatal(err) - } - - pidStatusFile := filepath.Join(pidDir, "status") - uid := 123456789 - writePidStatus(n, pid, uid, pidStatusFile) - if err != nil { - t.Fatal(err) - } - - state := sigar.ProcState{} - if assert.NoError(t, state.Get(pid)) { - expected := sigar.ProcState{ - Name: n, - Username: strconv.Itoa(uid), - State: 'S', - Ppid: 1, - Pgid: 2, - Tty: 4, - Priority: 15, - Nice: 16, - Processor: 36, - } - assert.Equal(t, expected, state) - } - }() - } -} - -func TestLinuxCPU(t *testing.T) { - setUp(t) - defer tearDown(t) - - tests := []struct { - stat string - user uint64 - }{ - {"cpu 25 1 2 3 4 5 6 7", 25}, - // Ignore empty lines - {"cpu ", 0}, - } - - statFile := procd + "/stat" - for _, test := range tests { - func() { - statContents := []byte(test.stat) - err := ioutil.WriteFile(statFile, statContents, 0644) - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(statFile) - - cpu := sigar.Cpu{} - if assert.NoError(t, cpu.Get()) { - assert.Equal(t, uint64(test.user), cpu.User, "cpu.User") - } - }() - } -} - -func TestLinuxCollectCpuStats(t *testing.T) { - setUp(t) - defer tearDown(t) - - statFile := procd + "/stat" - statContents := []byte("cpu 25 1 2 3 4 5 6 7") - err := ioutil.WriteFile(statFile, statContents, 0644) - if err != nil { - t.Fatal(err) - } - - concreteSigar := &sigar.ConcreteSigar{} - cpuUsages, stop := concreteSigar.CollectCpuStats(500 * time.Millisecond) - - assert.Equal(t, sigar.Cpu{ - User: uint64(25), - Nice: uint64(1), - Sys: uint64(2), - Idle: uint64(3), - Wait: uint64(4), - Irq: uint64(5), - SoftIrq: uint64(6), - Stolen: uint64(7), - }, <-cpuUsages) - - statContents = []byte("cpu 30 3 7 10 25 55 36 65") - err = ioutil.WriteFile(statFile, statContents, 0644) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, sigar.Cpu{ - User: uint64(5), - Nice: uint64(2), - Sys: uint64(5), - Idle: uint64(7), - Wait: uint64(21), - Irq: uint64(50), - SoftIrq: uint64(30), - Stolen: uint64(58), - }, <-cpuUsages) - - stop <- struct{}{} -} - -func TestLinuxMemAndSwap(t *testing.T) { - setUp(t) - defer tearDown(t) - - meminfoContents := ` -MemTotal: 374256 kB -MemFree: 274460 kB -Buffers: 9764 kB -Cached: 38648 kB -SwapCached: 0 kB -Active: 33772 kB -Inactive: 31184 kB -Active(anon): 16572 kB -Inactive(anon): 552 kB -Active(file): 17200 kB -Inactive(file): 30632 kB -Unevictable: 0 kB -Mlocked: 0 kB -SwapTotal: 786428 kB -SwapFree: 786428 kB -Dirty: 0 kB -Writeback: 0 kB -AnonPages: 16564 kB -Mapped: 6612 kB -Shmem: 584 kB -Slab: 19092 kB -SReclaimable: 9128 kB -SUnreclaim: 9964 kB -KernelStack: 672 kB -PageTables: 1864 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 973556 kB -Committed_AS: 55880 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 21428 kB -VmallocChunk: 34359713596 kB -HardwareCorrupted: 0 kB -AnonHugePages: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 59328 kB -DirectMap2M: 333824 kB -` - - meminfoFile := procd + "/meminfo" - err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444) - if err != nil { - t.Fatal(err) - } - - mem := sigar.Mem{} - if assert.NoError(t, mem.Get()) { - assert.Equal(t, uint64(374256*1024), mem.Total) - assert.Equal(t, uint64(274460*1024), mem.Free) - assert.Equal(t, uint64(mem.Total-mem.Free), mem.Used) - assert.Equal(t, uint64((274460+9764+38648)*1024), mem.ActualFree) - assert.Equal(t, uint64(mem.Total-mem.ActualFree), mem.ActualUsed) - } - - swap := sigar.Swap{} - if assert.NoError(t, swap.Get()) { - assert.Equal(t, uint64(786428*1024), swap.Total) - assert.Equal(t, uint64(786428*1024), swap.Free) - } -} - -func TestLinuxMemAndSwapKernel_3_14(t *testing.T) { - setUp(t) - defer tearDown(t) - - meminfoContents := ` -MemTotal: 500184 kB -MemFree: 31360 kB -MemAvailable: 414168 kB -Buffers: 28740 kB -Cached: 325408 kB -SwapCached: 264 kB -Active: 195476 kB -Inactive: 198612 kB -Active(anon): 14920 kB -Inactive(anon): 27268 kB -Active(file): 180556 kB -Inactive(file): 171344 kB -Unevictable: 0 kB -Mlocked: 0 kB -SwapTotal: 524284 kB -SwapFree: 520352 kB -Dirty: 0 kB -Writeback: 0 kB -AnonPages: 39772 kB -Mapped: 24132 kB -Shmem: 2236 kB -Slab: 57988 kB -SReclaimable: 43524 kB -SUnreclaim: 14464 kB -KernelStack: 2464 kB -PageTables: 3096 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 774376 kB -Committed_AS: 490916 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 0 kB -CmaTotal: 0 kB -CmaFree: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 63424 kB -DirectMap2M: 460800 kB -` - - meminfoFile := procd + "/meminfo" - err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444) - if err != nil { - t.Fatal(err) - } - - mem := sigar.Mem{} - if assert.NoError(t, mem.Get()) { - assert.Equal(t, uint64(500184*1024), mem.Total) - assert.Equal(t, uint64(31360*1024), mem.Free) - assert.Equal(t, uint64(414168*1024), mem.ActualFree) - assert.Equal(t, uint64(mem.Total-mem.Free), mem.Used) - assert.Equal(t, uint64(mem.Total-mem.ActualFree), mem.ActualUsed) - } - - swap := sigar.Swap{} - if assert.NoError(t, swap.Get()) { - assert.Equal(t, uint64(524284*1024), swap.Total) - assert.Equal(t, uint64(520352*1024), swap.Free) - } -} - -func TestLinuxMemAndSwapMissingMemTotal(t *testing.T) { - setUp(t) - defer tearDown(t) - - meminfoContents := ` -MemFree: 31360 kB -MemAvailable: 414168 kB -Buffers: 28740 kB -Cached: 325408 kB -SwapCached: 264 kB -Active: 195476 kB -Inactive: 198612 kB -Active(anon): 14920 kB -Inactive(anon): 27268 kB -Active(file): 180556 kB -Inactive(file): 171344 kB -Unevictable: 0 kB -Mlocked: 0 kB -SwapTotal: 524284 kB -SwapFree: 520352 kB -Dirty: 0 kB -Writeback: 0 kB -AnonPages: 39772 kB -Mapped: 24132 kB -Shmem: 2236 kB -Slab: 57988 kB -SReclaimable: 43524 kB -SUnreclaim: 14464 kB -KernelStack: 2464 kB -PageTables: 3096 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 774376 kB -Committed_AS: 490916 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 0 kB -CmaTotal: 0 kB -CmaFree: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 63424 kB -DirectMap2M: 460800 kB -` - - meminfoFile := procd + "/meminfo" - err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444) - if err != nil { - t.Fatal(err) - } - - mem := sigar.Mem{} - if assert.NoError(t, mem.Get()) { - assert.Equal(t, uint64(0), mem.Total) - assert.Equal(t, uint64(31360*1024), mem.Free) - assert.Equal(t, uint64(414168*1024), mem.ActualFree) - } - - swap := sigar.Swap{} - if assert.NoError(t, swap.Get()) { - assert.Equal(t, uint64(524284*1024), swap.Total) - assert.Equal(t, uint64(520352*1024), swap.Free) - } -} - -func TestLinuxMemAndSwapKernel_3_14_memavailable_zero(t *testing.T) { - setUp(t) - defer tearDown(t) - - meminfoContents := ` -MemTotal: 148535680 kB -MemFree: 417356 kB -MemAvailable: 0 kB -Buffers: 1728 kB -Cached: 129928 kB -SwapCached: 8208 kB -Active: 141088676 kB -Inactive: 5568132 kB -Active(anon): 141076780 kB -Inactive(anon): 5556936 kB -Active(file): 11896 kB -Inactive(file): 11196 kB -Unevictable: 3648 kB -Mlocked: 3648 kB -SwapTotal: 4882428 kB -SwapFree: 0 kB -Dirty: 808 kB -Writeback: 220 kB -AnonPages: 146521272 kB -Mapped: 41384 kB -Shmem: 105864 kB -Slab: 522648 kB -SReclaimable: 233508 kB -SUnreclaim: 289140 kB -KernelStack: 85024 kB -PageTables: 368760 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 79150268 kB -Committed_AS: 272491684 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 0 kB -VmallocChunk: 0 kB -HardwareCorrupted: 0 kB -AnonHugePages: 78061568 kB -ShmemHugePages: 0 kB -ShmemPmdMapped: 0 kB -CmaTotal: 0 kB -CmaFree: 0 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 124388 kB -DirectMap2M: 5105664 kB -DirectMap1G: 147849216 kB -` - - meminfoFile := procd + "/meminfo" - err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444) - if err != nil { - t.Fatal(err) - } - - mem := sigar.Mem{} - if assert.NoError(t, mem.Get()) { - assert.Equal(t, uint64(148535680*1024), mem.Total) - assert.Equal(t, uint64(417356*1024), mem.Free) - assert.Equal(t, uint64(0), mem.ActualFree) - } - - swap := sigar.Swap{} - if assert.NoError(t, swap.Get()) { - assert.Equal(t, uint64(4882428*1024), swap.Total) - assert.Equal(t, uint64(0), swap.Free) - } - -} - -func TestLinuxHugeTLBPages(t *testing.T) { - setUp(t) - defer tearDown(t) - - meminfoContents := ` -MemTotal: 374256 kB -MemFree: 274460 kB -Buffers: 9764 kB -Cached: 38648 kB -SwapCached: 0 kB -Active: 33772 kB -Inactive: 31184 kB -Active(anon): 16572 kB -Inactive(anon): 552 kB -Active(file): 17200 kB -Inactive(file): 30632 kB -Unevictable: 0 kB -Mlocked: 0 kB -SwapTotal: 786428 kB -SwapFree: 786428 kB -Dirty: 0 kB -Writeback: 0 kB -AnonPages: 16564 kB -Mapped: 6612 kB -Shmem: 584 kB -Slab: 19092 kB -SReclaimable: 9128 kB -SUnreclaim: 9964 kB -KernelStack: 672 kB -PageTables: 1864 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 973556 kB -Committed_AS: 55880 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 21428 kB -VmallocChunk: 34359713596 kB -HardwareCorrupted: 0 kB -AnonHugePages: 0 kB -HugePages_Total: 16 -HugePages_Free: 14 -HugePages_Rsvd: 2 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 59328 kB -DirectMap2M: 333824 kB -` - - meminfoFile := procd + "/meminfo" - err := ioutil.WriteFile(meminfoFile, []byte(meminfoContents), 0444) - if err != nil { - t.Fatal(err) - } - - hugePages := sigar.HugeTLBPages{} - if assert.NoError(t, hugePages.Get()) { - assert.Equal(t, uint64(16), hugePages.Total) - assert.Equal(t, uint64(14), hugePages.Free) - assert.Equal(t, uint64(2), hugePages.Reserved) - assert.Equal(t, uint64(0), hugePages.Surplus) - assert.Equal(t, uint64(2048*1024), hugePages.DefaultSize) - assert.Equal(t, uint64(4*2048*1024), hugePages.TotalAllocatedSize) - } -} - -func TestFDUsage(t *testing.T) { - setUp(t) - defer tearDown(t) - - // There is no Uint63 until 2.0 - open := uint64(rand.Uint32()) - unused := uint64(rand.Uint32()) - max := uint64(rand.Uint32()) - fileNRContents := fmt.Sprintf("%d %d %d", open, unused, max) - - fileNRPath := procd + "/sys/fs" - os.MkdirAll(fileNRPath, 0755) - fileNRFile := fileNRPath + "/file-nr" - err := ioutil.WriteFile(fileNRFile, []byte(fileNRContents), 0444) - if err != nil { - t.Fatal(err) - } - - fd := sigar.FDUsage{} - if assert.NoError(t, fd.Get()) { - assert.Equal(t, open, fd.Open) - assert.Equal(t, unused, fd.Unused) - assert.Equal(t, max, fd.Max) - } -} - -func TestProcFDUsage(t *testing.T) { - setUp(t) - defer tearDown(t) - - pid := rand.Intn(32768) - pidDir := fmt.Sprintf("%s/%d", procd, pid) - err := os.Mkdir(pidDir, 0755) - if err != nil { - t.Fatal(err) - } - soft := uint64(rand.Uint32()) - // subtract to prevent the posibility of overflow - if soft != 0 { - soft -= 1 - } - // max sure hard is always bigger than soft - hard := soft + uint64(rand.Uint32()) - - limitsContents := `Limit Soft Limit Hard Limit Units -Max cpu time unlimited unlimited seconds -Max file size unlimited unlimited bytes -Max data size unlimited unlimited bytes -Max stack size 8388608 unlimited bytes -Max core file size 0 unlimited bytes -Max resident set unlimited unlimited bytes -Max processes 29875 29875 processes -Max open files %d %d files -Max locked memory 65536 65536 bytes -Max address space unlimited unlimited bytes -Max file locks unlimited unlimited locks -Max pending signals 29875 29875 signals -Max msgqueue size 819200 819200 bytes -Max nice priority 0 0 -Max realtime priority 0 0 -Max realtime timeout unlimited unlimited us -` - - limitsContents = fmt.Sprintf(limitsContents, soft, hard) - - limitsFile := pidDir + "/limits" - err = ioutil.WriteFile(limitsFile, []byte(limitsContents), 0444) - if err != nil { - t.Fatal(err) - } - open := rand.Intn(32768) - if err = writeFDs(pid, open); err != nil { - t.Fatal(err) - } - - procFD := sigar.ProcFDUsage{} - if assert.NoError(t, procFD.Get(pid)) { - assert.Equal(t, uint64(open), procFD.Open) - assert.Equal(t, soft, procFD.SoftLimit) - assert.Equal(t, hard, procFD.HardLimit) - } -} - -func writeFDs(pid int, count int) error { - fdDir := fmt.Sprintf("%s/%d/fd", procd, pid) - err := os.Mkdir(fdDir, 0755) - if err != nil { - return err - } - - for i := 0; i < count; i++ { - fdPath := fmt.Sprintf("%s/%d", fdDir, i) - f, err := os.Create(fdPath) - if err != nil { - return err - } - f.Close() - } - return nil -} - -func writePidStats(pid int, procName string, path string) error { - stats := "S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 " + - "20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 " + - "35 36 37 38 39" - - statContents := []byte(fmt.Sprintf("%d (%s) %s", pid, procName, stats)) - return ioutil.WriteFile(path, statContents, 0644) -} - -func writePidStatus(name string, pid int, uid int, pidStatusFile string) error { - status := ` -Name: %s -State: R (running) -Tgid: 5452 -Pid: %d -PPid: 743 -TracerPid: 0 -Uid: %d %d %d %d -Gid: 100 100 100 100 -FDSize: 256 -Groups: 100 14 16 -VmPeak: 5004 kB -VmSize: 5004 kB -VmLck: 0 kB -VmHWM: 476 kB -VmRSS: 476 kB -RssAnon: 352 kB -RssFile: 120 kB -RssShmem: 4 kB -VmData: 156 kB -VmStk: 88 kB -VmExe: 68 kB -VmLib: 1412 kB -VmPTE: 20 kb -VmSwap: 0 kB -HugetlbPages: 0 kB -Threads: 1 -SigQ: 0/28578 -SigPnd: 0000000000000000 -ShdPnd: 0000000000000000 -SigBlk: 0000000000000000 -SigIgn: 0000000000000000 -SigCgt: 0000000000000000 -CapInh: 00000000fffffeff -CapPrm: 0000000000000000 -CapEff: 0000000000000000 -CapBnd: ffffffffffffffff -Seccomp: 0 -voluntary_ctxt_switches: 0 -nonvoluntary_ctxt_switches: 1` - - statusContents := []byte(fmt.Sprintf(status, name, pid, uid)) - return ioutil.WriteFile(pidStatusFile, statusContents, 0644) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_openbsd.go b/cockroach/patches/github.com/elastic/gosigar/sigar_openbsd.go deleted file mode 100644 index c537f02..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_openbsd.go +++ /dev/null @@ -1,426 +0,0 @@ -// Copyright (c) 2016 Jasper Lievisse Adriaanse . - -// +build openbsd - -package gosigar - -/* -#include -#include -#include -#include -#include -#include -#include -#include -*/ -import "C" - -//import "github.com/davecgh/go-spew/spew" - -import ( - "runtime" - "syscall" - "time" - "unsafe" -) - -type Uvmexp struct { - pagesize uint32 - pagemask uint32 - pageshift uint32 - npages uint32 - free uint32 - active uint32 - inactive uint32 - paging uint32 - wired uint32 - zeropages uint32 - reserve_pagedaemon uint32 - reserve_kernel uint32 - anonpages uint32 - vnodepages uint32 - vtextpages uint32 - freemin uint32 - freetarg uint32 - inactarg uint32 - wiredmax uint32 - anonmin uint32 - vtextmin uint32 - vnodemin uint32 - anonminpct uint32 - vtextmi uint32 - npct uint32 - vnodeminpct uint32 - nswapdev uint32 - swpages uint32 - swpginuse uint32 - swpgonly uint32 - nswget uint32 - nanon uint32 - nanonneeded uint32 - nfreeanon uint32 - faults uint32 - traps uint32 - intrs uint32 - swtch uint32 - softs uint32 - syscalls uint32 - pageins uint32 - obsolete_swapins uint32 - obsolete_swapouts uint32 - pgswapin uint32 - pgswapout uint32 - forks uint32 - forks_ppwait uint32 - forks_sharevm uint32 - pga_zerohit uint32 - pga_zeromiss uint32 - zeroaborts uint32 - fltnoram uint32 - fltnoanon uint32 - fltpgwait uint32 - fltpgrele uint32 - fltrelck uint32 - fltrelckok uint32 - fltanget uint32 - fltanretry uint32 - fltamcopy uint32 - fltnamap uint32 - fltnomap uint32 - fltlget uint32 - fltget uint32 - flt_anon uint32 - flt_acow uint32 - flt_obj uint32 - flt_prcopy uint32 - flt_przero uint32 - pdwoke uint32 - pdrevs uint32 - pdswout uint32 - pdfreed uint32 - pdscans uint32 - pdanscan uint32 - pdobscan uint32 - pdreact uint32 - pdbusy uint32 - pdpageouts uint32 - pdpending uint32 - pddeact uint32 - pdreanon uint32 - pdrevnode uint32 - pdrevtext uint32 - fpswtch uint32 - kmapent uint32 -} - -type Bcachestats struct { - numbufs uint64 - numbufpages uint64 - numdirtypages uint64 - numcleanpages uint64 - pendingwrites uint64 - pendingreads uint64 - numwrites uint64 - numreads uint64 - cachehits uint64 - busymapped uint64 - dmapages uint64 - highpages uint64 - delwribufs uint64 - kvaslots uint64 - kvaslots_avail uint64 -} - -type Swapent struct { - se_dev C.dev_t - se_flags int32 - se_nblks int32 - se_inuse int32 - se_priority int32 - sw_path []byte -} - -func (self *FileSystemList) Get() error { - num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT) - if err != nil { - return err - } - - buf := make([]syscall.Statfs_t, num) - - _, err = syscall.Getfsstat(buf, C.MNT_NOWAIT) - if err != nil { - return err - } - - fslist := make([]FileSystem, 0, num) - - for i := 0; i < num; i++ { - fs := FileSystem{} - - fs.DirName = byteListToString(buf[i].F_mntonname[:]) - fs.DevName = byteListToString(buf[i].F_mntfromname[:]) - fs.SysTypeName = byteListToString(buf[i].F_fstypename[:]) - - fslist = append(fslist, fs) - } - - self.List = fslist - - return err -} - -func (self *FileSystemUsage) Get(path string) error { - stat := syscall.Statfs_t{} - err := syscall.Statfs(path, &stat) - if err != nil { - return err - } - - self.Total = uint64(stat.F_blocks) * uint64(stat.F_bsize) - self.Free = uint64(stat.F_bfree) * uint64(stat.F_bsize) - self.Avail = uint64(stat.F_bavail) * uint64(stat.F_bsize) - self.Used = self.Total - self.Free - self.Files = stat.F_files - self.FreeFiles = stat.F_ffree - - return nil -} - -func (self *FDUsage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *LoadAverage) Get() error { - avg := []C.double{0, 0, 0} - - C.getloadavg(&avg[0], C.int(len(avg))) - - self.One = float64(avg[0]) - self.Five = float64(avg[1]) - self.Fifteen = float64(avg[2]) - - return nil -} - -func (self *Uptime) Get() error { - tv := syscall.Timeval{} - mib := [2]int32{C.CTL_KERN, C.KERN_BOOTTIME} - - n := uintptr(0) - // First we determine how much memory we'll need to pass later on (via `n`) - _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) - - if errno != 0 || n == 0 { - return nil - } - - // Now perform the actual sysctl(3) call, storing the result in tv - _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&tv)), uintptr(unsafe.Pointer(&n)), 0, 0) - - if errno != 0 || n == 0 { - return nil - } - - self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds() - - return nil -} - -func (self *Mem) Get() error { - n := uintptr(0) - - var uvmexp Uvmexp - mib := [2]int32{C.CTL_VM, C.VM_UVMEXP} - n = uintptr(0) - // First we determine how much memory we'll need to pass later on (via `n`) - _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - - _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&uvmexp)), uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - - var bcachestats Bcachestats - mib3 := [3]int32{C.CTL_VFS, C.VFS_GENERIC, C.VFS_BCACHESTAT} - n = uintptr(0) - _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, 0, uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, uintptr(unsafe.Pointer(&bcachestats)), uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - - self.Total = uint64(uvmexp.npages) << uvmexp.pageshift - self.Used = uint64(uvmexp.npages-uvmexp.free) << uvmexp.pageshift - self.Free = uint64(uvmexp.free) << uvmexp.pageshift - - self.ActualFree = self.Free + (uint64(bcachestats.numbufpages) << uvmexp.pageshift) - self.ActualUsed = self.Used - (uint64(bcachestats.numbufpages) << uvmexp.pageshift) - - return nil -} - -func (self *Swap) Get() error { - nswap := C.swapctl(C.SWAP_NSWAP, unsafe.Pointer(uintptr(0)), 0) - - // If there are no swap devices, nothing to do here. - if nswap == 0 { - return nil - } - - swdev := make([]Swapent, nswap) - - rnswap := C.swapctl(C.SWAP_STATS, unsafe.Pointer(&swdev[0]), nswap) - if rnswap == 0 { - return nil - } - - for i := 0; i < int(nswap); i++ { - if swdev[i].se_flags&C.SWF_ENABLE == 2 { - self.Used = self.Used + uint64(swdev[i].se_inuse/(1024/C.DEV_BSIZE)) - self.Total = self.Total + uint64(swdev[i].se_nblks/(1024/C.DEV_BSIZE)) - } - } - - self.Free = self.Total - self.Used - - return nil -} - -func (self *HugeTLBPages) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *Cpu) Get() error { - load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE} - - mib := [2]int32{C.CTL_KERN, C.KERN_CPTIME} - n := uintptr(0) - // First we determine how much memory we'll need to pass later on (via `n`) - _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - - _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&load)), uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - - self.User = uint64(load[0]) - self.Nice = uint64(load[1]) - self.Sys = uint64(load[2]) - self.Irq = uint64(load[3]) - self.Idle = uint64(load[4]) - - return nil -} - -func (self *CpuList) Get() error { - mib := [2]int32{C.CTL_HW, C.HW_NCPU} - var ncpu int - - n := uintptr(0) - // First we determine how much memory we'll need to pass later on (via `n`) - _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0) - - if errno != 0 || n == 0 { - return nil - } - - // Now perform the actual sysctl(3) call, storing the result in ncpu - _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&ncpu)), uintptr(unsafe.Pointer(&n)), 0, 0) - - if errno != 0 || n == 0 { - return nil - } - - load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE} - - self.List = make([]Cpu, ncpu) - for curcpu := range self.List { - sysctlCptime(ncpu, curcpu, &load) - fillCpu(&self.List[curcpu], load) - } - - return nil -} - -func (self *ProcList) Get() error { - return nil -} - -func (self *ProcArgs) Get(pid int) error { - return nil -} - -func (self *ProcEnv) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *ProcState) Get(pid int) error { - return nil -} - -func (self *ProcMem) Get(pid int) error { - return nil -} - -func (self *ProcTime) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *ProcExe) Get(pid int) error { - return nil -} - -func (self *ProcFDUsage) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *Rusage) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func fillCpu(cpu *Cpu, load [C.CPUSTATES]C.long) { - cpu.User = uint64(load[0]) - cpu.Nice = uint64(load[1]) - cpu.Sys = uint64(load[2]) - cpu.Irq = uint64(load[3]) - cpu.Idle = uint64(load[4]) -} - -func sysctlCptime(ncpu int, curcpu int, load *[C.CPUSTATES]C.long) error { - var mib []int32 - - // Use the correct mib based on the number of CPUs and fill out the - // current CPU number in case of SMP. (0 indexed cf. self.List) - if ncpu == 0 { - mib = []int32{C.CTL_KERN, C.KERN_CPTIME} - } else { - mib = []int32{C.CTL_KERN, C.KERN_CPTIME2, int32(curcpu)} - } - - len := len(mib) - - n := uintptr(0) - // First we determine how much memory we'll need to pass later on (via `n`) - _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), 0, uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - - _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), uintptr(unsafe.Pointer(load)), uintptr(unsafe.Pointer(&n)), 0, 0) - if errno != 0 || n == 0 { - return nil - } - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_stub.go b/cockroach/patches/github.com/elastic/gosigar/sigar_stub.go deleted file mode 100644 index 58d2516..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_stub.go +++ /dev/null @@ -1,75 +0,0 @@ -// +build !aix,!darwin,!freebsd,!linux,!openbsd,!windows,!illumos - -package gosigar - -import ( - "runtime" -) - -func (c *Cpu) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (l *LoadAverage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (m *Mem) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (s *Swap) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (s *HugeTLBPages) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (f *FDUsage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcTime) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *FileSystemUsage) Get(path string) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *CpuList) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcState) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcExe) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcMem) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcFDUsage) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcEnv) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcList) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (p *ProcArgs) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *Rusage) Get(int) error { - return ErrNotImplemented{runtime.GOOS} -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_unix.go b/cockroach/patches/github.com/elastic/gosigar/sigar_unix.go deleted file mode 100644 index e423419..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_unix.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -// +build aix darwin freebsd linux - -package gosigar - -import ( - "syscall" - "time" - - "golang.org/x/sys/unix" -) - -func (self *FileSystemUsage) Get(path string) error { - stat := syscall.Statfs_t{} - err := syscall.Statfs(path, &stat) - if err != nil { - return err - } - - self.Total = uint64(stat.Blocks) * uint64(stat.Bsize) - self.Free = uint64(stat.Bfree) * uint64(stat.Bsize) - self.Avail = uint64(stat.Bavail) * uint64(stat.Bsize) - self.Used = self.Total - self.Free - self.Files = stat.Files - self.FreeFiles = uint64(stat.Ffree) - - return nil -} - -func (r *Rusage) Get(who int) error { - ru, err := getResourceUsage(who) - if err != nil { - return err - } - - uTime := convertRtimeToDur(ru.Utime) - sTime := convertRtimeToDur(ru.Stime) - - r.Utime = uTime - r.Stime = sTime - r.Maxrss = int64(ru.Maxrss) - r.Ixrss = int64(ru.Ixrss) - r.Idrss = int64(ru.Idrss) - r.Isrss = int64(ru.Isrss) - r.Minflt = int64(ru.Minflt) - r.Majflt = int64(ru.Majflt) - r.Nswap = int64(ru.Nswap) - r.Inblock = int64(ru.Inblock) - r.Oublock = int64(ru.Oublock) - r.Msgsnd = int64(ru.Msgsnd) - r.Msgrcv = int64(ru.Msgrcv) - r.Nsignals = int64(ru.Nsignals) - r.Nvcsw = int64(ru.Nvcsw) - r.Nivcsw = int64(ru.Nivcsw) - - return nil -} - -func getResourceUsage(who int) (unix.Rusage, error) { - r := unix.Rusage{} - err := unix.Getrusage(who, &r) - - return r, err -} - -func convertRtimeToDur(t unix.Timeval) time.Duration { - return time.Duration(t.Nano()) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_unix_common.go b/cockroach/patches/github.com/elastic/gosigar/sigar_unix_common.go deleted file mode 100644 index 93b0fa8..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_unix_common.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -// +build freebsd linux illumos - -package gosigar - -import ( - "bufio" - "bytes" - "io" - "io/ioutil" -) - -func readFile(file string, handler func(string) bool) error { - contents, err := ioutil.ReadFile(file) - if err != nil { - return err - } - - reader := bufio.NewReader(bytes.NewBuffer(contents)) - - for { - line, _, err := reader.ReadLine() - if err == io.EOF { - break - } - if !handler(string(line)) { - break - } - } - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_util.go b/cockroach/patches/github.com/elastic/gosigar/sigar_util.go deleted file mode 100644 index 586d488..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_util.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package gosigar - -import ( - "bytes" -) - -// byteListToString converts the raw byte arrays we get into a string. This is a bit of a process, as byte strings are normally []uint8 -func byteListToString(raw []int8) string { - byteList := make([]byte, len(raw)) - - for pos, singleByte := range raw { - byteList[pos] = byte(singleByte) - if singleByte == 0 { - break - } - } - - return string(bytes.Trim(byteList, "\x00")) -} - -func chop(buf []byte) []byte { - return buf[0 : len(buf)-1] -} - -// convertBytesToString trims null bytes and returns a string -func convertBytesToString(arr []byte) string { - return string(bytes.Trim(arr, "\x00")) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_util_test.go b/cockroach/patches/github.com/elastic/gosigar/sigar_util_test.go deleted file mode 100644 index c00aa38..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_util_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package gosigar - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func TestByteArrayToString(t *testing.T) { - testIn := [16]int8{97, 112, 102, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - output := byteListToString(testIn[:]) - assert.Equal(t, "apfs", output) - -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sigar_windows.go b/cockroach/patches/github.com/elastic/gosigar/sigar_windows.go deleted file mode 100644 index d1204b8..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sigar_windows.go +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright (c) 2012 VMware, Inc. - -package gosigar - -import ( - "fmt" - "os" - "path/filepath" - "runtime" - "strings" - "syscall" - "time" - - "github.com/elastic/gosigar/sys/windows" - "github.com/pkg/errors" -) - -var ( - // version is Windows version of the host OS. - version = windows.GetWindowsVersion() - - // processQueryLimitedInfoAccess is set to PROCESS_QUERY_INFORMATION for Windows - // 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer - // OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION. - processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION -) - -func init() { - if !version.IsWindowsVistaOrGreater() { - // PROCESS_QUERY_LIMITED_INFORMATION cannot be used on 2003 or XP. - processQueryLimitedInfoAccess = syscall.PROCESS_QUERY_INFORMATION - } -} - -func (self *LoadAverage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *FDUsage) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *ProcEnv) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *ProcExe) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *ProcFDUsage) Get(pid int) error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *Uptime) Get() error { - // Minimum supported OS is Windows Vista. - if !version.IsWindowsVistaOrGreater() { - return ErrNotImplemented{runtime.GOOS} - } - uptimeMs, err := windows.GetTickCount64() - if err != nil { - return errors.Wrap(err, "failed to get boot time using GetTickCount64 api") - } - self.Length = float64(time.Duration(uptimeMs)*time.Millisecond) / float64(time.Second) - return nil -} - -func (self *Mem) Get() error { - memoryStatusEx, err := windows.GlobalMemoryStatusEx() - if err != nil { - return errors.Wrap(err, "GlobalMemoryStatusEx failed") - } - - self.Total = memoryStatusEx.TotalPhys - self.Free = memoryStatusEx.AvailPhys - self.Used = self.Total - self.Free - self.ActualFree = self.Free - self.ActualUsed = self.Used - return nil -} - -func (self *Swap) Get() error { - memoryStatusEx, err := windows.GlobalMemoryStatusEx() - if err != nil { - return errors.Wrap(err, "GlobalMemoryStatusEx failed") - } - - self.Total = memoryStatusEx.TotalPageFile - self.Free = memoryStatusEx.AvailPageFile - self.Used = self.Total - self.Free - return nil -} - -func (self *HugeTLBPages) Get() error { - return ErrNotImplemented{runtime.GOOS} -} - -func (self *Cpu) Get() error { - idle, kernel, user, err := windows.GetSystemTimes() - if err != nil { - return errors.Wrap(err, "GetSystemTimes failed") - } - - // CPU times are reported in milliseconds by gosigar. - self.Idle = uint64(idle / time.Millisecond) - self.Sys = uint64(kernel / time.Millisecond) - self.User = uint64(user / time.Millisecond) - return nil -} - -func (self *CpuList) Get() error { - cpus, err := windows.NtQuerySystemProcessorPerformanceInformation() - if err != nil { - return errors.Wrap(err, "NtQuerySystemProcessorPerformanceInformation failed") - } - - self.List = make([]Cpu, 0, len(cpus)) - for _, cpu := range cpus { - self.List = append(self.List, Cpu{ - Idle: uint64(cpu.IdleTime / time.Millisecond), - Sys: uint64(cpu.KernelTime / time.Millisecond), - User: uint64(cpu.UserTime / time.Millisecond), - }) - } - return nil -} - -func (self *FileSystemList) Get() error { - drives, err := windows.GetAccessPaths() - if err != nil { - return errors.Wrap(err, "GetAccessPaths failed") - } - - for _, drive := range drives { - dt, err := windows.GetDriveType(drive) - if err != nil { - return errors.Wrapf(err, "GetDriveType failed") - } - - self.List = append(self.List, FileSystem{ - DirName: drive, - DevName: drive, - TypeName: dt.String(), - }) - } - return nil -} - -// Get retrieves a list of all process identifiers (PIDs) in the system. -func (self *ProcList) Get() error { - pids, err := windows.EnumProcesses() - if err != nil { - return errors.Wrap(err, "EnumProcesses failed") - } - - // Convert uint32 PIDs to int. - self.List = make([]int, 0, len(pids)) - for _, pid := range pids { - self.List = append(self.List, int(pid)) - } - return nil -} - -func (self *ProcState) Get(pid int) error { - var errs []error - - var err error - self.Name, err = getProcName(pid) - if err != nil { - errs = append(errs, errors.Wrap(err, "getProcName failed")) - } - - self.State, err = getProcStatus(pid) - if err != nil { - errs = append(errs, errors.Wrap(err, "getProcStatus failed")) - } - - self.Ppid, err = getParentPid(pid) - if err != nil { - errs = append(errs, errors.Wrap(err, "getParentPid failed")) - } - - // getProcCredName will often fail when run as a non-admin user. This is - // caused by strict ACL of the process token belonging to other users. - // Instead of failing completely, ignore this error and still return most - // data with an empty Username. - self.Username, _ = getProcCredName(pid) - - if len(errs) > 0 { - errStrs := make([]string, 0, len(errs)) - for _, e := range errs { - errStrs = append(errStrs, e.Error()) - } - return errors.New(strings.Join(errStrs, "; ")) - } - return nil -} - -// getProcName returns the process name associated with the PID. -func getProcName(pid int) (string, error) { - handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) - if err != nil { - return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) - } - defer syscall.CloseHandle(handle) - - filename, err := windows.GetProcessImageFileName(handle) - if err != nil { - return "", errors.Wrapf(err, "GetProcessImageFileName failed for pid=%v", pid) - } - - return filepath.Base(filename), nil -} - -// getProcStatus returns the status of a process. -func getProcStatus(pid int) (RunState, error) { - handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) - if err != nil { - return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) - } - defer syscall.CloseHandle(handle) - - var exitCode uint32 - err = syscall.GetExitCodeProcess(handle, &exitCode) - if err != nil { - return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v", pid) - } - - if exitCode == 259 { //still active - return RunStateRun, nil - } - return RunStateSleep, nil -} - -// getParentPid returns the parent process ID of a process. -func getParentPid(pid int) (int, error) { - handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) - if err != nil { - return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) - } - defer syscall.CloseHandle(handle) - - procInfo, err := windows.NtQueryProcessBasicInformation(handle) - if err != nil { - return 0, errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid) - } - - return int(procInfo.InheritedFromUniqueProcessID), nil -} - -func getProcCredName(pid int) (string, error) { - handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) - if err != nil { - return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) - } - defer syscall.CloseHandle(handle) - - // Find process token via win32. - var token syscall.Token - err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token) - if err != nil { - return "", errors.Wrapf(err, "OpenProcessToken failed for pid=%v", pid) - } - // Close token to prevent handle leaks. - defer token.Close() - - // Find the token user. - tokenUser, err := token.GetTokenUser() - if err != nil { - return "", errors.Wrapf(err, "GetTokenInformation failed for pid=%v", pid) - } - - // Look up domain account by SID. - account, domain, _, err := tokenUser.User.Sid.LookupAccount("") - if err != nil { - sid, sidErr := tokenUser.User.Sid.String() - if sidErr != nil { - return "", errors.Wrapf(err, "failed while looking up account name for pid=%v", pid) - } - return "", errors.Wrapf(err, "failed while looking up account name for SID=%v of pid=%v", sid, pid) - } - - return fmt.Sprintf(`%s\%s`, domain, account), nil -} - -func (self *ProcMem) Get(pid int) error { - handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid)) - if err != nil { - return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) - } - defer syscall.CloseHandle(handle) - - counters, err := windows.GetProcessMemoryInfo(handle) - if err != nil { - return errors.Wrapf(err, "GetProcessMemoryInfo failed for pid=%v", pid) - } - - self.Resident = uint64(counters.WorkingSetSize) - self.Size = uint64(counters.PrivateUsage) - return nil -} - -func (self *ProcTime) Get(pid int) error { - cpu, err := getProcTimes(pid) - if err != nil { - return err - } - - // Windows epoch times are expressed as time elapsed since midnight on - // January 1, 1601 at Greenwich, England. This converts the Filetime to - // unix epoch in milliseconds. - self.StartTime = uint64(cpu.CreationTime.Nanoseconds() / 1e6) - - // Convert to millis. - self.User = uint64(windows.FiletimeToDuration(&cpu.UserTime).Nanoseconds() / 1e6) - self.Sys = uint64(windows.FiletimeToDuration(&cpu.KernelTime).Nanoseconds() / 1e6) - self.Total = self.User + self.Sys - - return nil -} - -func getProcTimes(pid int) (*syscall.Rusage, error) { - handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) - if err != nil { - return nil, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) - } - defer syscall.CloseHandle(handle) - - var cpu syscall.Rusage - if err := syscall.GetProcessTimes(handle, &cpu.CreationTime, &cpu.ExitTime, &cpu.KernelTime, &cpu.UserTime); err != nil { - return nil, errors.Wrapf(err, "GetProcessTimes failed for pid=%v", pid) - } - - return &cpu, nil -} - -func (self *ProcArgs) Get(pid int) error { - // The minimum supported client for Win32_Process is Windows Vista. - if !version.IsWindowsVistaOrGreater() { - return ErrNotImplemented{runtime.GOOS} - } - handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid)) - if err != nil { - return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) - } - defer syscall.CloseHandle(handle) - pbi, err := windows.NtQueryProcessBasicInformation(handle) - if err != nil { - return errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid) - } - if err != nil { - return nil - } - userProcParams, err := windows.GetUserProcessParams(handle, pbi) - if err != nil { - return nil - } - if argsW, err := windows.ReadProcessUnicodeString(handle, &userProcParams.CommandLine); err == nil { - self.List, err = windows.ByteSliceToStringSlice(argsW) - if err != nil { - return err - } - } - return nil -} - -func (self *FileSystemUsage) Get(path string) error { - freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, err := windows.GetDiskFreeSpaceEx(path) - if err != nil { - return errors.Wrap(err, "GetDiskFreeSpaceEx failed") - } - - self.Total = totalNumberOfBytes - self.Free = totalNumberOfFreeBytes - self.Used = self.Total - self.Free - self.Avail = freeBytesAvailable - return nil -} - -func (self *Rusage) Get(who int) error { - if who != 0 { - return ErrNotImplemented{runtime.GOOS} - } - - pid := os.Getpid() - cpu, err := getProcTimes(pid) - if err != nil { - return err - } - - self.Utime = windows.FiletimeToDuration(&cpu.UserTime) - self.Stime = windows.FiletimeToDuration(&cpu.KernelTime) - - return nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/endian.go b/cockroach/patches/github.com/elastic/gosigar/sys/endian.go deleted file mode 100644 index d9f3e41..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/endian.go +++ /dev/null @@ -1,16 +0,0 @@ -package sys - -import ( - "encoding/binary" - "unsafe" -) - -func GetEndian() binary.ByteOrder { - var i int32 = 0x1 - v := (*[4]byte)(unsafe.Pointer(&i)) - if v[0] == 0 { - return binary.BigEndian - } else { - return binary.LittleEndian - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/linux/inetdiag.go b/cockroach/patches/github.com/elastic/gosigar/sys/linux/inetdiag.go deleted file mode 100644 index cca3f2c..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/linux/inetdiag.go +++ /dev/null @@ -1,381 +0,0 @@ -// +build linux - -package linux - -import ( - "bytes" - "encoding/binary" - "fmt" - "hash/fnv" - "io" - "net" - "os" - "syscall" - "unsafe" - - "github.com/elastic/gosigar/sys" - "github.com/pkg/errors" -) - -// Enums / Constants - -const ( - // AllTCPStates is a flag to request all sockets in any TCP state. - AllTCPStates = ^uint32(0) - - // TCPDIAG_GETSOCK is the netlink message type for requesting TCP diag data. - // https://github.com/torvalds/linux/blob/v4.0/include/uapi/linux/inet_diag.h#L7 - TCPDIAG_GETSOCK = 18 - - // SOCK_DIAG_BY_FAMILY is the netlink message type for requestion socket - // diag data by family. This is newer and can be used with inet_diag_req_v2. - // https://github.com/torvalds/linux/blob/v4.0/include/uapi/linux/sock_diag.h#L6 - SOCK_DIAG_BY_FAMILY = 20 -) - -// AddressFamily is the address family of the socket. -type AddressFamily uint8 - -// https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/include/linux/socket.h#L159 -const ( - AF_INET AddressFamily = 2 - AF_INET6 = 10 -) - -var addressFamilyNames = map[AddressFamily]string{ - AF_INET: "ipv4", - AF_INET6: "ipv6", -} - -func (af AddressFamily) String() string { - if fam, found := addressFamilyNames[af]; found { - return fam - } - return fmt.Sprintf("UNKNOWN (%d)", af) -} - -// TCPState represents the state of a TCP connection. -type TCPState uint8 - -// https://github.com/torvalds/linux/blob/5924bbecd0267d87c24110cbe2041b5075173a25/include/net/tcp_states.h#L16 -const ( - TCP_ESTABLISHED TCPState = iota + 1 - TCP_SYN_SENT - TCP_SYN_RECV - TCP_FIN_WAIT1 - TCP_FIN_WAIT2 - TCP_TIME_WAIT - TCP_CLOSE - TCP_CLOSE_WAIT - TCP_LAST_ACK - TCP_LISTEN - TCP_CLOSING /* Now a valid state */ -) - -var tcpStateNames = map[TCPState]string{ - TCP_ESTABLISHED: "ESTAB", - TCP_SYN_SENT: "SYN-SENT", - TCP_SYN_RECV: "SYN-RECV", - TCP_FIN_WAIT1: "FIN-WAIT-1", - TCP_FIN_WAIT2: "FIN-WAIT-2", - TCP_TIME_WAIT: "TIME-WAIT", - TCP_CLOSE: "UNCONN", - TCP_CLOSE_WAIT: "CLOSE-WAIT", - TCP_LAST_ACK: "LAST-ACK", - TCP_LISTEN: "LISTEN", - TCP_CLOSING: "CLOSING", -} - -func (s TCPState) String() string { - if state, found := tcpStateNames[s]; found { - return state - } - return "UNKNOWN" -} - -// Extensions that can be used in the InetDiagReqV2 request to ask for -// additional data. -// https://github.com/torvalds/linux/blob/v4.0/include/uapi/linux/inet_diag.h#L103 -const ( - INET_DIAG_NONE = 0 - INET_DIAG_MEMINFO = 1 << iota - INET_DIAG_INFO - INET_DIAG_VEGASINFO - INET_DIAG_CONG - INET_DIAG_TOS - INET_DIAG_TCLASS - INET_DIAG_SKMEMINFO - INET_DIAG_SHUTDOWN - INET_DIAG_DCTCPINFO - INET_DIAG_PROTOCOL /* response attribute only */ - INET_DIAG_SKV6ONLY - INET_DIAG_LOCALS - INET_DIAG_PEERS - INET_DIAG_PAD - INET_DIAG_MARK -) - -var ( - byteOrder = sys.GetEndian() -) - -// NetlinkInetDiag sends the given netlink request parses the responses with the -// assumption that they are inet_diag_msgs. This will allocate a temporary -// buffer for reading from the socket whose size will be the length of a page -// (usually 32k). Use NetlinkInetDiagWithBuf if you want to provide your own -// buffer. -func NetlinkInetDiag(request syscall.NetlinkMessage) ([]*InetDiagMsg, error) { - return NetlinkInetDiagWithBuf(request, nil, nil) -} - -// NetlinkInetDiagWithBuf sends the given netlink request parses the responses -// with the assumption that they are inet_diag_msgs. readBuf will be used to -// hold the raw data read from the socket. If the length is not large enough to -// hold the socket contents the data will be truncated. If readBuf is nil then a -// temporary buffer will be allocated for each invocation. The resp writer, if -// non-nil, will receive a copy of all bytes read (this is useful for -// debugging). -func NetlinkInetDiagWithBuf(request syscall.NetlinkMessage, readBuf []byte, resp io.Writer) ([]*InetDiagMsg, error) { - s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_INET_DIAG) - if err != nil { - return nil, err - } - defer syscall.Close(s) - - lsa := &syscall.SockaddrNetlink{Family: syscall.AF_NETLINK} - if err := syscall.Sendto(s, serialize(request), 0, lsa); err != nil { - return nil, err - } - - if len(readBuf) == 0 { - // Default size used in libnl. - readBuf = make([]byte, os.Getpagesize()) - } - - var inetDiagMsgs []*InetDiagMsg -done: - for { - buf := readBuf - nr, _, err := syscall.Recvfrom(s, buf, 0) - if err != nil { - return nil, err - } - if nr < syscall.NLMSG_HDRLEN { - return nil, syscall.EINVAL - } - - buf = buf[:nr] - - // Dump raw data for inspection purposes. - if resp != nil { - if _, err := resp.Write(buf); err != nil { - return nil, err - } - } - - msgs, err := syscall.ParseNetlinkMessage(buf) - if err != nil { - return nil, err - } - - for _, m := range msgs { - if m.Header.Type == syscall.NLMSG_DONE { - break done - } - if m.Header.Type == syscall.NLMSG_ERROR { - return nil, ParseNetlinkError(m.Data) - } - - inetDiagMsg, err := ParseInetDiagMsg(m.Data) - if err != nil { - return nil, err - } - inetDiagMsgs = append(inetDiagMsgs, inetDiagMsg) - } - } - return inetDiagMsgs, nil -} - -func serialize(msg syscall.NetlinkMessage) []byte { - msg.Header.Len = uint32(syscall.SizeofNlMsghdr + len(msg.Data)) - b := make([]byte, msg.Header.Len) - byteOrder.PutUint32(b[0:4], msg.Header.Len) - byteOrder.PutUint16(b[4:6], msg.Header.Type) - byteOrder.PutUint16(b[6:8], msg.Header.Flags) - byteOrder.PutUint32(b[8:12], msg.Header.Seq) - byteOrder.PutUint32(b[12:16], msg.Header.Pid) - copy(b[16:], msg.Data) - return b -} - -// Request messages. - -var sizeofInetDiagReq = int(unsafe.Sizeof(InetDiagReq{})) - -// InetDiagReq (inet_diag_req) is used to request diagnostic data from older -// kernels. -// https://github.com/torvalds/linux/blob/v4.0/include/uapi/linux/inet_diag.h#L25 -type InetDiagReq struct { - Family uint8 - SrcLen uint8 - DstLen uint8 - Ext uint8 - ID InetDiagSockID - States uint32 // States to dump. - DBs uint32 // Tables to dump. -} - -func (r InetDiagReq) toWireFormat() []byte { - buf := bytes.NewBuffer(make([]byte, sizeofInetDiagReq)) - buf.Reset() - if err := binary.Write(buf, byteOrder, r); err != nil { - // This never returns an error. - panic(err) - } - return buf.Bytes() -} - -// NewInetDiagReq returns a new NetlinkMessage whose payload is an InetDiagReq. -// Callers should set their own sequence number in the returned message header. -func NewInetDiagReq() syscall.NetlinkMessage { - hdr := syscall.NlMsghdr{ - Type: uint16(TCPDIAG_GETSOCK), - Flags: uint16(syscall.NLM_F_DUMP | syscall.NLM_F_REQUEST), - Pid: uint32(0), - } - req := InetDiagReq{ - Family: uint8(AF_INET), // This returns both ipv4 and ipv6. - States: AllTCPStates, - } - - return syscall.NetlinkMessage{Header: hdr, Data: req.toWireFormat()} -} - -// V2 Request - -var sizeofInetDiagReqV2 = int(unsafe.Sizeof(InetDiagReqV2{})) - -// InetDiagReqV2 (inet_diag_req_v2) is used to request diagnostic data. -// https://github.com/torvalds/linux/blob/v4.0/include/uapi/linux/inet_diag.h#L37 -type InetDiagReqV2 struct { - Family uint8 - Protocol uint8 - Ext uint8 - Pad uint8 - States uint32 - ID InetDiagSockID -} - -func (r InetDiagReqV2) toWireFormat() []byte { - buf := bytes.NewBuffer(make([]byte, sizeofInetDiagReqV2)) - buf.Reset() - if err := binary.Write(buf, byteOrder, r); err != nil { - // This never returns an error. - panic(err) - } - return buf.Bytes() -} - -// NewInetDiagReqV2 returns a new NetlinkMessage whose payload is an -// InetDiagReqV2. Callers should set their own sequence number in the returned -// message header. -func NewInetDiagReqV2(af AddressFamily) syscall.NetlinkMessage { - hdr := syscall.NlMsghdr{ - Type: uint16(SOCK_DIAG_BY_FAMILY), - Flags: uint16(syscall.NLM_F_DUMP | syscall.NLM_F_REQUEST), - Pid: uint32(0), - } - req := InetDiagReqV2{ - Family: uint8(af), - Protocol: syscall.IPPROTO_TCP, - States: AllTCPStates, - } - - return syscall.NetlinkMessage{Header: hdr, Data: req.toWireFormat()} -} - -// Response messages. - -// InetDiagMsg (inet_diag_msg) is the base info structure. It contains socket -// identity (addrs/ports/cookie) and the information shown by netstat. -// https://github.com/torvalds/linux/blob/v4.0/include/uapi/linux/inet_diag.h#L86 -type InetDiagMsg struct { - Family uint8 // Address family. - State uint8 // TCP State - Timer uint8 - Retrans uint8 - - ID InetDiagSockID - - Expires uint32 - RQueue uint32 // Recv-Q - WQueue uint32 // Send-Q - UID uint32 // UID - Inode uint32 // Inode of socket. -} - -// ParseInetDiagMsg parse an InetDiagMsg from a byte slice. It assumes the -// InetDiagMsg starts at the beginning of b. Invoke this method to parse the -// payload of a netlink response. -func ParseInetDiagMsg(b []byte) (*InetDiagMsg, error) { - r := bytes.NewReader(b) - inetDiagMsg := &InetDiagMsg{} - err := binary.Read(r, byteOrder, inetDiagMsg) - if err != nil { - return nil, errors.Wrap(err, "failed to unmarshal inet_diag_msg") - } - return inetDiagMsg, nil -} - -// SrcPort returns the source (local) port. -func (m InetDiagMsg) SrcPort() int { return int(binary.BigEndian.Uint16(m.ID.SPort[:])) } - -// DstPort returns the destination (remote) port. -func (m InetDiagMsg) DstPort() int { return int(binary.BigEndian.Uint16(m.ID.DPort[:])) } - -// SrcIP returns the source (local) IP. -func (m InetDiagMsg) SrcIP() net.IP { return ip(m.ID.Src, AddressFamily(m.Family)) } - -// DstIP returns the destination (remote) IP. -func (m InetDiagMsg) DstIP() net.IP { return ip(m.ID.Dst, AddressFamily(m.Family)) } - -func (m InetDiagMsg) srcIPBytes() []byte { return ipBytes(m.ID.Src, AddressFamily(m.Family)) } -func (m InetDiagMsg) dstIPBytes() []byte { return ipBytes(m.ID.Dst, AddressFamily(m.Family)) } - -func ip(data [16]byte, af AddressFamily) net.IP { - if af == AF_INET { - return net.IPv4(data[0], data[1], data[2], data[3]) - } - return net.IP(data[:]) -} - -func ipBytes(data [16]byte, af AddressFamily) []byte { - if af == AF_INET { - return data[:4] - } - - return data[:] -} - -// FastHash returns a hash calculated using FNV-1 of the source and destination -// addresses. -func (m *InetDiagMsg) FastHash() uint64 { - // Hash using FNV-1 algorithm. - h := fnv.New64() - h.Write(m.srcIPBytes()) // Must trim non-zero garbage from ipv4 buffers. - h.Write(m.dstIPBytes()) - h.Write(m.ID.SPort[:]) - h.Write(m.ID.DPort[:]) - return h.Sum64() -} - -// InetDiagSockID (inet_diag_sockid) contains the socket identity. -// https://github.com/torvalds/linux/blob/v4.0/include/uapi/linux/inet_diag.h#L13 -type InetDiagSockID struct { - SPort [2]byte // Source port (big-endian). - DPort [2]byte // Destination port (big-endian). - Src [16]byte // Source IP - Dst [16]byte // Destination IP - If uint32 - Cookie [2]uint32 -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/linux/inetdiag_test.go b/cockroach/patches/github.com/elastic/gosigar/sys/linux/inetdiag_test.go deleted file mode 100644 index d4ff64b..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/linux/inetdiag_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// +build linux - -package linux - -import ( - "bytes" - "encoding/hex" - "io/ioutil" - "syscall" - "testing" - - "github.com/stretchr/testify/assert" -) - -// TestParseInetDiagMsgs reads netlink messages stored in a file (these can be -// captured with ss -diag ). -func TestParseInetDiagMsgs(t *testing.T) { - data, err := ioutil.ReadFile("testdata/inet-dump-rhel6-2.6.32-504.3.3.el6.x86_64.bin") - if err != nil { - t.Fatal(err) - } - - t.Log("Netlink data length: ", len(data)) - netlinkMsgs, err := syscall.ParseNetlinkMessage(data) - if err != nil { - t.Fatal(err) - } - - t.Logf("Parsed %d netlink messages", len(netlinkMsgs)) - done := false - for _, m := range netlinkMsgs { - if m.Header.Type == syscall.NLMSG_DONE { - done = true - break - } - - inetDiagMsg, err := ParseInetDiagMsg(m.Data) - if err != nil { - t.Fatal("parse error", err) - } - - if inetDiagMsg.DstPort() == 0 { - assert.EqualValues(t, TCP_LISTEN, inetDiagMsg.State) - } else { - assert.EqualValues(t, TCP_ESTABLISHED, inetDiagMsg.State) - } - } - - assert.True(t, done, "missing NLMSG_DONE message") -} - -// TestNetlinkInetDiag sends a inet_diag_req to the kernel, checks for errors, -// and inspects the responses based on some invariant rules. -func TestNetlinkInetDiag(t *testing.T) { - req := NewInetDiagReq() - req.Header.Seq = 12345 - - dump := new(bytes.Buffer) - msgs, err := NetlinkInetDiagWithBuf(req, nil, dump) - if err != nil { - t.Fatal(err) - } - - t.Logf("Received %d messages decoded from %d bytes", len(msgs), dump.Len()) - for _, m := range msgs { - if m.Family != uint8(AF_INET) && m.Family != uint8(AF_INET6) { - t.Errorf("invalid Family (%v)", m.Family) - } - - if m.DstPort() == 0 { - assert.True(t, m.DstIP().IsUnspecified(), "dport is 0, dst ip should be unspecified") - assert.EqualValues(t, m.State, TCP_LISTEN) - } - } - - if t.Failed() { - t.Log("Raw newlink response:\n", hex.Dump(dump.Bytes())) - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/linux/netlink.go b/cockroach/patches/github.com/elastic/gosigar/sys/linux/netlink.go deleted file mode 100644 index 9db8429..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/linux/netlink.go +++ /dev/null @@ -1,112 +0,0 @@ -// +build linux - -package linux - -import ( - "errors" - - "github.com/elastic/gosigar/sys" -) - -// Netlink Error Code Handling - -// ParseNetlinkError parses the errno from the data section of a -// syscall.NetlinkMessage. If netlinkData is less than 4 bytes an error -// describing the problem will be returned. -func ParseNetlinkError(netlinkData []byte) error { - if len(netlinkData) >= 4 { - errno := -sys.GetEndian().Uint32(netlinkData[:4]) - return NetlinkErrno(errno) - } - return errors.New("received netlink error (data too short to read errno)") -} - -// NetlinkErrno represent the error code contained in a netlink message of -// type NLMSG_ERROR. -type NetlinkErrno uint32 - -// Netlink error codes. -const ( - NLE_SUCCESS NetlinkErrno = iota - NLE_FAILURE - NLE_INTR - NLE_BAD_SOCK - NLE_AGAIN - NLE_NOMEM - NLE_EXIST - NLE_INVAL - NLE_RANGE - NLE_MSGSIZE - NLE_OPNOTSUPP - NLE_AF_NOSUPPORT - NLE_OBJ_NOTFOUND - NLE_NOATTR - NLE_MISSING_ATTR - NLE_AF_MISMATCH - NLE_SEQ_MISMATCH - NLE_MSG_OVERFLOW - NLE_MSG_TRUNC - NLE_NOADDR - NLE_SRCRT_NOSUPPORT - NLE_MSG_TOOSHORT - NLE_MSGTYPE_NOSUPPORT - NLE_OBJ_MISMATCH - NLE_NOCACHE - NLE_BUSY - NLE_PROTO_MISMATCH - NLE_NOACCESS - NLE_PERM - NLE_PKTLOC_FILE - NLE_PARSE_ERR - NLE_NODEV - NLE_IMMUTABLE - NLE_DUMP_INTR - NLE_ATTRSIZE -) - -// https://github.com/thom311/libnl/blob/libnl3_2_28/lib/error.c -var netlinkErrorMsgs = map[NetlinkErrno]string{ - NLE_SUCCESS: "Success", - NLE_FAILURE: "Unspecific failure", - NLE_INTR: "Interrupted system call", - NLE_BAD_SOCK: "Bad socket", - NLE_AGAIN: "Try again", - NLE_NOMEM: "Out of memory", - NLE_EXIST: "Object exists", - NLE_INVAL: "Invalid input data or parameter", - NLE_RANGE: "Input data out of range", - NLE_MSGSIZE: "Message size not sufficient", - NLE_OPNOTSUPP: "Operation not supported", - NLE_AF_NOSUPPORT: "Address family not supported", - NLE_OBJ_NOTFOUND: "Object not found", - NLE_NOATTR: "Attribute not available", - NLE_MISSING_ATTR: "Missing attribute", - NLE_AF_MISMATCH: "Address family mismatch", - NLE_SEQ_MISMATCH: "Message sequence number mismatch", - NLE_MSG_OVERFLOW: "Kernel reported message overflow", - NLE_MSG_TRUNC: "Kernel reported truncated message", - NLE_NOADDR: "Invalid address for specified address family", - NLE_SRCRT_NOSUPPORT: "Source based routing not supported", - NLE_MSG_TOOSHORT: "Netlink message is too short", - NLE_MSGTYPE_NOSUPPORT: "Netlink message type is not supported", - NLE_OBJ_MISMATCH: "Object type does not match cache", - NLE_NOCACHE: "Unknown or invalid cache type", - NLE_BUSY: "Object busy", - NLE_PROTO_MISMATCH: "Protocol mismatch", - NLE_NOACCESS: "No Access", - NLE_PERM: "Operation not permitted", - NLE_PKTLOC_FILE: "Unable to open packet location file", - NLE_PARSE_ERR: "Unable to parse object", - NLE_NODEV: "No such device", - NLE_IMMUTABLE: "Immutable attribute", - NLE_DUMP_INTR: "Dump inconsistency detected, interrupted", - NLE_ATTRSIZE: "Attribute max length exceeded", -} - -func (e NetlinkErrno) Error() string { - if msg, found := netlinkErrorMsgs[e]; found { - return msg - } - - return netlinkErrorMsgs[NLE_FAILURE] -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/linux/netlink_test.go b/cockroach/patches/github.com/elastic/gosigar/sys/linux/netlink_test.go deleted file mode 100644 index 099812f..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/linux/netlink_test.go +++ /dev/null @@ -1,22 +0,0 @@ -// +build linux - -package linux - -import ( - "bytes" - "encoding/binary" - "testing" - - "github.com/elastic/gosigar/sys" - "github.com/stretchr/testify/assert" -) - -func TestParseNetlinkErrorDataTooShort(t *testing.T) { - assert.Error(t, ParseNetlinkError(nil), "too short") -} - -func TestParseNetlinkErrorErrno(t *testing.T) { - buf := new(bytes.Buffer) - binary.Write(buf, sys.GetEndian(), -1*int32(NLE_MSG_TOOSHORT)) - assert.Equal(t, ParseNetlinkError(buf.Bytes()), NLE_MSG_TOOSHORT) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/linux/sysconf_cgo.go b/cockroach/patches/github.com/elastic/gosigar/sys/linux/sysconf_cgo.go deleted file mode 100644 index e557a66..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/linux/sysconf_cgo.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build linux,cgo - -package linux - -/* -#include -*/ -import "C" - -// GetClockTicks returns the number of click ticks in one jiffie. -func GetClockTicks() int { - return int(C.sysconf(C._SC_CLK_TCK)) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/linux/sysconf_nocgo.go b/cockroach/patches/github.com/elastic/gosigar/sys/linux/sysconf_nocgo.go deleted file mode 100644 index 005e0c1..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/linux/sysconf_nocgo.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build !cgo !linux - -package linux - -// GetClockTicks returns the number of click ticks in one jiffie. -func GetClockTicks() int { - return 100 -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/linux/testdata/inet-dump-rhel6-2.6.32-504.3.3.el6.x86_64.bin b/cockroach/patches/github.com/elastic/gosigar/sys/linux/testdata/inet-dump-rhel6-2.6.32-504.3.3.el6.x86_64.bin deleted file mode 100644 index c259788..0000000 Binary files a/cockroach/patches/github.com/elastic/gosigar/sys/linux/testdata/inet-dump-rhel6-2.6.32-504.3.3.el6.x86_64.bin and /dev/null differ diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/doc.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/doc.go deleted file mode 100644 index 9dca125..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package windows contains various Windows system call. -package windows - -// Use "go generate -v -x ." to generate the source. - -// Add -trace to enable debug prints around syscalls. -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=true -output zsyscall_windows.go syscall_windows.go -//go:generate go run fix_generated.go -input zsyscall_windows.go diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/fix_generated.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/fix_generated.go deleted file mode 100644 index 80bc6de..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/fix_generated.go +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//+build ignore - -package main - -import ( - "flag" - "io/ioutil" - "log" - "regexp" -) - -func main() { - var filename string - - log.SetFlags(0) - flag.StringVar(&filename, "input", "", "name of generated source file to fix") - flag.Parse() - - if filename == "" { - log.Fatal("Name of generated file must be specified with -input flag") - } - - if err := fixGeneratedCode(filename); err != nil { - log.Fatal(err) - } -} - -var lazySystemRegex = regexp.MustCompile(`(?m)\sNewLazySystemDLL`) -var unsafeImportRegex = regexp.MustCompile(`(?m)"unsafe"`) - -// fixGeneratedCode adds "windows." to locations in the generated source code -// that reference "NewLazySystemDLL" without the package name. -func fixGeneratedCode(filename string) error { - data, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - - data = lazySystemRegex.ReplaceAll(data, []byte(" windows.NewLazySystemDLL")) - data = unsafeImportRegex.ReplaceAll(data, []byte(`"unsafe"`+"\n\n\t"+`"golang.org/x/sys/windows"`)) - - return ioutil.WriteFile(filename, data, 0644) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/ntquery.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/ntquery.go deleted file mode 100644 index 85de365..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/ntquery.go +++ /dev/null @@ -1,132 +0,0 @@ -// +build windows - -package windows - -import ( - "bytes" - "encoding/binary" - "io" - "runtime" - "syscall" - "time" - "unsafe" - - "github.com/pkg/errors" -) - -// On both 32-bit and 64-bit systems NtQuerySystemInformation expects the -// size of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION to be 48. -const sizeofSystemProcessorPerformanceInformation = 48 - -// ProcessBasicInformation is an equivalent representation of -// PROCESS_BASIC_INFORMATION in the Windows API. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx -type ProcessBasicInformation struct { - ExitStatus uint - PebBaseAddress uintptr - AffinityMask uint - BasePriority uint - UniqueProcessID uint - InheritedFromUniqueProcessID uint -} - -// NtQueryProcessBasicInformation queries basic information about the process -// associated with the given handle (provided by OpenProcess). It uses the -// NtQueryInformationProcess function to collect the data. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx -func NtQueryProcessBasicInformation(handle syscall.Handle) (ProcessBasicInformation, error) { - var processBasicInfo ProcessBasicInformation - processBasicInfoPtr := (*byte)(unsafe.Pointer(&processBasicInfo)) - size := uint32(unsafe.Sizeof(processBasicInfo)) - ntStatus, _ := _NtQueryInformationProcess(handle, 0, processBasicInfoPtr, size, nil) - if ntStatus != 0 { - return ProcessBasicInformation{}, errors.Errorf("NtQueryInformationProcess failed, NTSTATUS=0x%X", ntStatus) - } - - return processBasicInfo, nil -} - -// SystemProcessorPerformanceInformation contains CPU performance information -// for a single CPU. -type SystemProcessorPerformanceInformation struct { - IdleTime time.Duration // Amount of time spent idle. - KernelTime time.Duration // Kernel time does NOT include time spent in idle. - UserTime time.Duration // Amount of time spent executing in user mode. -} - -// _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION is an equivalent representation of -// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION in the Windows API. This struct is -// used internally with NtQuerySystemInformation call and is not exported. The -// exported equivalent is SystemProcessorPerformanceInformation. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx -type _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION struct { - IdleTime int64 - KernelTime int64 - UserTime int64 - Reserved1 [2]int64 - Reserved2 uint32 -} - -// NtQuerySystemProcessorPerformanceInformation queries CPU performance -// information for each CPU. It uses the NtQuerySystemInformation function to -// collect the SystemProcessorPerformanceInformation. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx -func NtQuerySystemProcessorPerformanceInformation() ([]SystemProcessorPerformanceInformation, error) { - // NTSTATUS code for success. - // https://msdn.microsoft.com/en-us/library/cc704588.aspx - const STATUS_SUCCESS = 0 - - // From the _SYSTEM_INFORMATION_CLASS enum. - // http://processhacker.sourceforge.net/doc/ntexapi_8h.html#ad5d815b48e8f4da1ef2eb7a2f18a54e0 - const systemProcessorPerformanceInformation = 8 - - // Create a buffer large enough to hold an entry for each processor. - b := make([]byte, runtime.NumCPU()*sizeofSystemProcessorPerformanceInformation) - - // Query the performance information. Note that this function uses 0 to - // indicate success. Most other Windows functions use non-zero for success. - var returnLength uint32 - ntStatus, _ := _NtQuerySystemInformation(systemProcessorPerformanceInformation, &b[0], uint32(len(b)), &returnLength) - if ntStatus != STATUS_SUCCESS { - return nil, errors.Errorf("NtQuerySystemInformation failed, NTSTATUS=0x%X, bufLength=%v, returnLength=%v", ntStatus, len(b), returnLength) - } - - return readSystemProcessorPerformanceInformationBuffer(b) -} - -// readSystemProcessorPerformanceInformationBuffer reads from a buffer -// containing SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION data. The buffer should -// contain one entry for each CPU. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx -func readSystemProcessorPerformanceInformationBuffer(b []byte) ([]SystemProcessorPerformanceInformation, error) { - n := len(b) / sizeofSystemProcessorPerformanceInformation - r := bytes.NewReader(b) - - rtn := make([]SystemProcessorPerformanceInformation, 0, n) - for i := 0; i < n; i++ { - _, err := r.Seek(int64(i*sizeofSystemProcessorPerformanceInformation), io.SeekStart) - if err != nil { - return nil, errors.Wrapf(err, "failed to seek to cpuN=%v in buffer", i) - } - - times := make([]uint64, 3) - for j := range times { - err := binary.Read(r, binary.LittleEndian, ×[j]) - if err != nil { - return nil, errors.Wrapf(err, "failed reading cpu times for cpuN=%v", i) - } - } - - idleTime := time.Duration(times[0] * 100) - kernelTime := time.Duration(times[1] * 100) - userTime := time.Duration(times[2] * 100) - - rtn = append(rtn, SystemProcessorPerformanceInformation{ - IdleTime: idleTime, - KernelTime: kernelTime - idleTime, // Subtract out idle time from kernel time. - UserTime: userTime, - }) - } - - return rtn, nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/privileges.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/privileges.go deleted file mode 100644 index 28c78fd..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/privileges.go +++ /dev/null @@ -1,272 +0,0 @@ -// +build windows - -package windows - -import ( - "bytes" - "encoding/binary" - "encoding/json" - "fmt" - "runtime" - "strings" - "sync" - "syscall" - - "github.com/pkg/errors" - "golang.org/x/sys/windows" -) - -// Cache of privilege names to LUIDs. -var ( - privNames = make(map[string]int64) - privNameMutex sync.Mutex -) - -const ( - // SeDebugPrivilege is the name of the privilege used to debug programs. - SeDebugPrivilege = "SeDebugPrivilege" -) - -// Errors returned by AdjustTokenPrivileges. -const ( - ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300 -) - -// Attribute bits for privileges. -const ( - _SE_PRIVILEGE_ENABLED_BY_DEFAULT uint32 = 0x00000001 - _SE_PRIVILEGE_ENABLED uint32 = 0x00000002 - _SE_PRIVILEGE_REMOVED uint32 = 0x00000004 - _SE_PRIVILEGE_USED_FOR_ACCESS uint32 = 0x80000000 -) - -// Privilege contains information about a single privilege associated with a -// Token. -type Privilege struct { - LUID int64 `json:"-"` // Locally unique identifier (guaranteed only until the system is restarted). - Name string `json:"-"` - EnabledByDefault bool `json:"enabled_by_default,omitempty"` - Enabled bool `json:"enabled"` - Removed bool `json:"removed,omitempty"` - Used bool `json:"used,omitempty"` -} - -func (p Privilege) String() string { - var buf bytes.Buffer - buf.WriteString(p.Name) - buf.WriteString("=(") - - opts := make([]string, 0, 4) - if p.EnabledByDefault { - opts = append(opts, "Default") - } - if p.Enabled { - opts = append(opts, "Enabled") - } - if !p.EnabledByDefault && !p.Enabled { - opts = append(opts, "Disabled") - } - if p.Removed { - opts = append(opts, "Removed") - } - if p.Used { - opts = append(opts, "Used") - } - - buf.WriteString(strings.Join(opts, ", ")) - buf.WriteString(")") - - // Example: SeDebugPrivilege=(Default, Enabled) - return buf.String() -} - -// User represent the information about a Windows account. -type User struct { - SID string - Account string - Domain string - Type uint32 -} - -func (u User) String() string { - return fmt.Sprintf(`User:%v\%v, SID:%v, Type:%v`, u.Domain, u.Account, u.SID, u.Type) -} - -// DebugInfo contains general debug info about the current process. -type DebugInfo struct { - OSVersion Version // OS version info. - Arch string // Architecture of the machine. - NumCPU int // Number of CPUs. - User User // User that this process is running as. - ProcessPrivs map[string]Privilege // Privileges held by the process. -} - -func (d DebugInfo) String() string { - bytes, _ := json.Marshal(d) - return string(bytes) -} - -// LookupPrivilegeName looks up a privilege name given a LUID value. -func LookupPrivilegeName(systemName string, luid int64) (string, error) { - buf := make([]uint16, 256) - bufSize := uint32(len(buf)) - err := _LookupPrivilegeName(systemName, &luid, &buf[0], &bufSize) - if err != nil { - return "", errors.Wrapf(err, "LookupPrivilegeName failed for luid=%v", luid) - } - - return syscall.UTF16ToString(buf), nil -} - -// mapPrivileges maps privilege names to LUID values. -func mapPrivileges(names []string) ([]int64, error) { - var privileges []int64 - privNameMutex.Lock() - defer privNameMutex.Unlock() - for _, name := range names { - p, ok := privNames[name] - if !ok { - err := _LookupPrivilegeValue("", name, &p) - if err != nil { - return nil, errors.Wrapf(err, "LookupPrivilegeValue failed on '%v'", name) - } - privNames[name] = p - } - privileges = append(privileges, p) - } - return privileges, nil -} - -// EnableTokenPrivileges enables the specified privileges in the given -// Token. The token must have TOKEN_ADJUST_PRIVILEGES access. If the token -// does not already contain the privilege it cannot be enabled. -func EnableTokenPrivileges(token syscall.Token, privileges ...string) error { - privValues, err := mapPrivileges(privileges) - if err != nil { - return err - } - - var b bytes.Buffer - binary.Write(&b, binary.LittleEndian, uint32(len(privValues))) - for _, p := range privValues { - binary.Write(&b, binary.LittleEndian, p) - binary.Write(&b, binary.LittleEndian, uint32(_SE_PRIVILEGE_ENABLED)) - } - - success, err := _AdjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(b.Len()), nil, nil) - if !success { - return err - } - if err == ERROR_NOT_ALL_ASSIGNED { - return errors.Wrap(err, "error not all privileges were assigned") - } - - return nil -} - -// GetTokenPrivileges returns a list of privileges associated with a token. -// The provided token must have at a minimum TOKEN_QUERY access. This is a -// wrapper around the GetTokenInformation function. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx -func GetTokenPrivileges(token syscall.Token) (map[string]Privilege, error) { - // Determine the required buffer size. - var size uint32 - syscall.GetTokenInformation(token, syscall.TokenPrivileges, nil, 0, &size) - - // This buffer will receive a TOKEN_PRIVILEGE structure. - b := bytes.NewBuffer(make([]byte, size)) - err := syscall.GetTokenInformation(token, syscall.TokenPrivileges, &b.Bytes()[0], uint32(b.Len()), &size) - if err != nil { - return nil, errors.Wrap(err, "GetTokenInformation failed") - } - - var privilegeCount uint32 - err = binary.Read(b, binary.LittleEndian, &privilegeCount) - if err != nil { - return nil, errors.Wrap(err, "failed to read PrivilegeCount") - } - - rtn := make(map[string]Privilege, privilegeCount) - for i := 0; i < int(privilegeCount); i++ { - var luid int64 - err = binary.Read(b, binary.LittleEndian, &luid) - if err != nil { - return nil, errors.Wrap(err, "failed to read LUID value") - } - - var attributes uint32 - err = binary.Read(b, binary.LittleEndian, &attributes) - if err != nil { - return nil, errors.Wrap(err, "failed to read attributes") - } - - name, err := LookupPrivilegeName("", luid) - if err != nil { - return nil, errors.Wrapf(err, "LookupPrivilegeName failed for LUID=%v", luid) - } - - rtn[name] = Privilege{ - LUID: luid, - Name: name, - EnabledByDefault: (attributes & _SE_PRIVILEGE_ENABLED_BY_DEFAULT) > 0, - Enabled: (attributes & _SE_PRIVILEGE_ENABLED) > 0, - Removed: (attributes & _SE_PRIVILEGE_REMOVED) > 0, - Used: (attributes & _SE_PRIVILEGE_USED_FOR_ACCESS) > 0, - } - } - - return rtn, nil -} - -// GetTokenUser returns the User associated with the given Token. -func GetTokenUser(token syscall.Token) (User, error) { - tokenUser, err := token.GetTokenUser() - if err != nil { - return User{}, errors.Wrap(err, "GetTokenUser failed") - } - - var user User - user.SID, err = tokenUser.User.Sid.String() - if err != nil { - return user, errors.Wrap(err, "ConvertSidToStringSid failed") - } - - user.Account, user.Domain, user.Type, err = tokenUser.User.Sid.LookupAccount("") - if err != nil { - return user, errors.Wrap(err, "LookupAccountSid failed") - } - - return user, nil -} - -// GetDebugInfo returns general debug info about the current process. -func GetDebugInfo() (*DebugInfo, error) { - h, err := windows.GetCurrentProcess() - if err != nil { - return nil, err - } - - var token syscall.Token - err = syscall.OpenProcessToken(syscall.Handle(h), syscall.TOKEN_QUERY, &token) - if err != nil { - return nil, err - } - - privs, err := GetTokenPrivileges(token) - if err != nil { - return nil, err - } - - user, err := GetTokenUser(token) - if err != nil { - return nil, err - } - - return &DebugInfo{ - User: user, - ProcessPrivs: privs, - OSVersion: GetWindowsVersion(), - Arch: runtime.GOARCH, - NumCPU: runtime.NumCPU(), - }, nil -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/privileges_test.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/privileges_test.go deleted file mode 100644 index 0bce86d..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/privileges_test.go +++ /dev/null @@ -1,82 +0,0 @@ -// +build windows - -package windows - -import ( - "syscall" - "testing" - - "github.com/stretchr/testify/assert" - "golang.org/x/sys/windows" -) - -func TestGetDebugInfo(t *testing.T) { - debug, err := GetDebugInfo() - if err != nil { - t.Fatal(err) - } - - t.Logf("%+v", debug) -} - -func TestGetTokenPrivileges(t *testing.T) { - h, err := windows.GetCurrentProcess() - if err != nil { - t.Fatal("GetCurrentProcess", err) - } - - var token syscall.Token - err = syscall.OpenProcessToken(syscall.Handle(h), syscall.TOKEN_QUERY, &token) - if err != nil { - t.Fatal("OpenProcessToken", err) - } - - privs, err := GetTokenPrivileges(token) - if err != nil { - t.Fatal("GetTokenPrivileges", err) - } - - for _, priv := range privs { - t.Log(priv) - } -} - -func TestEnableTokenPrivileges(t *testing.T) { - h, err := windows.GetCurrentProcess() - if err != nil { - t.Fatal("GetCurrentProcess", err) - } - - var token syscall.Token - err = syscall.OpenProcessToken(syscall.Handle(h), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, &token) - if err != nil { - t.Fatal("OpenProcessToken", err) - } - - privs, err := GetTokenPrivileges(token) - if err != nil { - t.Fatal("GetTokenPrivileges", err) - } - - priv, found := privs[SeDebugPrivilege] - if found { - t.Logf("Token has privilege: %v", priv) - } else { - t.Logf("Token is missing privilege %v", SeDebugPrivilege) - } - - err = EnableTokenPrivileges(token, SeDebugPrivilege) - if err != nil { - t.Fatal("EnableTokenPrivileges", err) - } - - privs, err = GetTokenPrivileges(token) - if err != nil { - t.Fatal("GetTokenPrivileges", err) - } - - priv, found = privs[SeDebugPrivilege] - if found && assert.True(t, priv.Enabled, "%v is not enabled. %v", SeDebugPrivilege, priv) { - t.Logf("%v is enabled.", SeDebugPrivilege) - } -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/syscall_windows.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/syscall_windows.go deleted file mode 100644 index 371eb25..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/syscall_windows.go +++ /dev/null @@ -1,605 +0,0 @@ -package windows - -import ( - "fmt" - "syscall" - "time" - "unsafe" - - "github.com/pkg/errors" -) - -var ( - sizeofUint32 = 4 - sizeofProcessEntry32 = uint32(unsafe.Sizeof(ProcessEntry32{})) - sizeofProcessMemoryCountersEx = uint32(unsafe.Sizeof(ProcessMemoryCountersEx{})) - sizeofMemoryStatusEx = uint32(unsafe.Sizeof(MemoryStatusEx{})) -) - -// Process-specific access rights. Others are declared in the syscall package. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx -const ( - PROCESS_QUERY_LIMITED_INFORMATION uint32 = 0x1000 - PROCESS_VM_READ uint32 = 0x0010 -) - -// SizeOfRtlUserProcessParameters gives the size -// of the RtlUserProcessParameters struct. -const SizeOfRtlUserProcessParameters = unsafe.Sizeof(RtlUserProcessParameters{}) - -// MAX_PATH is the maximum length for a path in Windows. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx -const MAX_PATH = 260 - -// DriveType represents a type of drive (removable, fixed, CD-ROM, RAM disk, or -// network drive). -type DriveType uint32 - -// Drive types as returned by GetDriveType. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx -const ( - DRIVE_UNKNOWN DriveType = iota - DRIVE_NO_ROOT_DIR - DRIVE_REMOVABLE - DRIVE_FIXED - DRIVE_REMOTE - DRIVE_CDROM - DRIVE_RAMDISK -) - -// UnicodeString is Go's equivalent for the _UNICODE_STRING struct. -type UnicodeString struct { - Size uint16 - MaximumLength uint16 - Buffer uintptr -} - -// RtlUserProcessParameters is Go's equivalent for the -// _RTL_USER_PROCESS_PARAMETERS struct. -// A few undocumented fields are exposed. -type RtlUserProcessParameters struct { - Reserved1 [16]byte - Reserved2 [5]uintptr - CurrentDirectoryPath UnicodeString - CurrentDirectoryHandle uintptr - DllPath UnicodeString - ImagePathName UnicodeString - CommandLine UnicodeString -} - -func (dt DriveType) String() string { - names := map[DriveType]string{ - DRIVE_UNKNOWN: "unknown", - DRIVE_NO_ROOT_DIR: "invalid", - DRIVE_REMOVABLE: "removable", - DRIVE_FIXED: "fixed", - DRIVE_REMOTE: "remote", - DRIVE_CDROM: "cdrom", - DRIVE_RAMDISK: "ramdisk", - } - - name, found := names[dt] - if !found { - return "unknown DriveType value" - } - return name -} - -// Flags that can be used with CreateToolhelp32Snapshot. -const ( - TH32CS_INHERIT uint32 = 0x80000000 // Indicates that the snapshot handle is to be inheritable. - TH32CS_SNAPHEAPLIST uint32 = 0x00000001 // Includes all heaps of the process specified in th32ProcessID in the snapshot. - TH32CS_SNAPMODULE uint32 = 0x00000008 // Includes all modules of the process specified in th32ProcessID in the snapshot. - TH32CS_SNAPMODULE32 uint32 = 0x00000010 // Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process. - TH32CS_SNAPPROCESS uint32 = 0x00000002 // Includes all processes in the system in the snapshot. - TH32CS_SNAPTHREAD uint32 = 0x00000004 // Includes all threads in the system in the snapshot. -) - -// ProcessEntry32 is an equivalent representation of PROCESSENTRY32 in the -// Windows API. It contains a process's information. Do not modify or reorder. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx -type ProcessEntry32 struct { - size uint32 - CntUsage uint32 - ProcessID uint32 - DefaultHeapID uintptr - ModuleID uint32 - CntThreads uint32 - ParentProcessID uint32 - PriorityClassBase int32 - Flags uint32 - exeFile [MAX_PATH]uint16 -} - -// ExeFile returns the name of the executable file for the process. It does -// not contain the full path. -func (p ProcessEntry32) ExeFile() string { - return syscall.UTF16ToString(p.exeFile[:]) -} - -func (p ProcessEntry32) String() string { - return fmt.Sprintf("{CntUsage:%v ProcessID:%v DefaultHeapID:%v ModuleID:%v "+ - "CntThreads:%v ParentProcessID:%v PriorityClassBase:%v Flags:%v ExeFile:%v", - p.CntUsage, p.ProcessID, p.DefaultHeapID, p.ModuleID, p.CntThreads, - p.ParentProcessID, p.PriorityClassBase, p.Flags, p.ExeFile()) -} - -// MemoryStatusEx is an equivalent representation of MEMORYSTATUSEX in the -// Windows API. It contains information about the current state of both physical -// and virtual memory, including extended memory. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770 -type MemoryStatusEx struct { - length uint32 - MemoryLoad uint32 - TotalPhys uint64 - AvailPhys uint64 - TotalPageFile uint64 - AvailPageFile uint64 - TotalVirtual uint64 - AvailVirtual uint64 - AvailExtendedVirtual uint64 -} - -// ProcessMemoryCountersEx is an equivalent representation of -// PROCESS_MEMORY_COUNTERS_EX in the Windows API. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874(v=vs.85).aspx -type ProcessMemoryCountersEx struct { - cb uint32 - PageFaultCount uint32 - PeakWorkingSetSize uintptr - WorkingSetSize uintptr - QuotaPeakPagedPoolUsage uintptr - QuotaPagedPoolUsage uintptr - QuotaPeakNonPagedPoolUsage uintptr - QuotaNonPagedPoolUsage uintptr - PagefileUsage uintptr - PeakPagefileUsage uintptr - PrivateUsage uintptr -} - -// GetLogicalDriveStrings returns a list of drives in the system. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364975(v=vs.85).aspx -func GetLogicalDriveStrings() ([]string, error) { - // Determine the size of the buffer required to receive all drives. - bufferLength, err := _GetLogicalDriveStringsW(0, nil) - if err != nil { - return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed to get buffer length") - } - if bufferLength < 0 { - return nil, errors.New("GetLogicalDriveStringsW returned an invalid buffer length") - } - - buffer := make([]uint16, bufferLength) - _, err = _GetLogicalDriveStringsW(uint32(len(buffer)), &buffer[0]) - if err != nil { - return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed") - } - - return UTF16SliceToStringSlice(buffer), nil -} - -// GetAccessPaths returns the list of access paths for volumes in the system. -func GetAccessPaths() ([]string, error) { - volumes, err := GetVolumes() - if err != nil { - return nil, errors.Wrap(err, "GetVolumes failed") - } - - var paths []string - for _, volumeName := range volumes { - volumePaths, err := GetVolumePathsForVolume(volumeName) - if err != nil { - return nil, errors.Wrapf(err, "failed to get list of access paths for volume '%s'", volumeName) - } - if len(volumePaths) == 0 { - continue - } - - // Get only the first path - paths = append(paths, volumePaths[0]) - } - - return paths, nil -} - -// GetVolumes returs the list of volumes in the system. -// https://docs.microsoft.com/es-es/windows/desktop/api/fileapi/nf-fileapi-findfirstvolumew -func GetVolumes() ([]string, error) { - buffer := make([]uint16, MAX_PATH+1) - - var volumes []string - - h, err := _FindFirstVolume(&buffer[0], uint32(len(buffer))) - if err != nil { - return nil, errors.Wrap(err, "FindFirstVolumeW failed") - } - defer _FindVolumeClose(h) - - for { - volumes = append(volumes, syscall.UTF16ToString(buffer)) - - err = _FindNextVolume(h, &buffer[0], uint32(len(buffer))) - if err != nil { - if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES { - break - } - return nil, errors.Wrap(err, "FindNextVolumeW failed") - } - } - - return volumes, nil -} - -// GetVolumePathsForVolume returns the list of volume paths for a volume. -// https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-getvolumepathnamesforvolumenamew -func GetVolumePathsForVolume(volumeName string) ([]string, error) { - var length uint32 - err := _GetVolumePathNamesForVolumeName(volumeName, nil, 0, &length) - if errors.Cause(err) != syscall.ERROR_MORE_DATA { - return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed to get needed buffer length") - } - if length == 0 { - // Not mounted, no paths, that's ok - return nil, nil - } - - buffer := make([]uint16, length*(MAX_PATH+1)) - err = _GetVolumePathNamesForVolumeName(volumeName, &buffer[0], length, &length) - if err != nil { - return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed") - } - - return UTF16SliceToStringSlice(buffer), nil -} - -// GlobalMemoryStatusEx retrieves information about the system's current usage -// of both physical and virtual memory. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx -func GlobalMemoryStatusEx() (MemoryStatusEx, error) { - memoryStatusEx := MemoryStatusEx{length: sizeofMemoryStatusEx} - err := _GlobalMemoryStatusEx(&memoryStatusEx) - if err != nil { - return MemoryStatusEx{}, errors.Wrap(err, "GlobalMemoryStatusEx failed") - } - - return memoryStatusEx, nil -} - -// GetProcessMemoryInfo retrieves information about the memory usage of the -// specified process. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx -func GetProcessMemoryInfo(handle syscall.Handle) (ProcessMemoryCountersEx, error) { - processMemoryCountersEx := ProcessMemoryCountersEx{cb: sizeofProcessMemoryCountersEx} - err := _GetProcessMemoryInfo(handle, &processMemoryCountersEx, processMemoryCountersEx.cb) - if err != nil { - return ProcessMemoryCountersEx{}, errors.Wrap(err, "GetProcessMemoryInfo failed") - } - - return processMemoryCountersEx, nil -} - -// GetProcessImageFileName Retrieves the name of the executable file for the -// specified process. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx -func GetProcessImageFileName(handle syscall.Handle) (string, error) { - buffer := make([]uint16, MAX_PATH) - _, err := _GetProcessImageFileName(handle, &buffer[0], uint32(len(buffer))) - if err != nil { - return "", errors.Wrap(err, "GetProcessImageFileName failed") - } - - return syscall.UTF16ToString(buffer), nil -} - -// GetSystemTimes retrieves system timing information. On a multiprocessor -// system, the values returned are the sum of the designated times across all -// processors. The returned kernel time does not include the system idle time. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724400(v=vs.85).aspx -func GetSystemTimes() (idle, kernel, user time.Duration, err error) { - var idleTime, kernelTime, userTime syscall.Filetime - err = _GetSystemTimes(&idleTime, &kernelTime, &userTime) - if err != nil { - return 0, 0, 0, errors.Wrap(err, "GetSystemTimes failed") - } - - idle = FiletimeToDuration(&idleTime) - kernel = FiletimeToDuration(&kernelTime) // Kernel time includes idle time so we subtract it out. - user = FiletimeToDuration(&userTime) - - return idle, kernel - idle, user, nil -} - -// FiletimeToDuration converts a Filetime to a time.Duration. Do not use this -// method to convert a Filetime to an actual clock time, for that use -// Filetime.Nanosecond(). -func FiletimeToDuration(ft *syscall.Filetime) time.Duration { - n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals - return time.Duration(n * 100) -} - -// GetDriveType Determines whether a disk drive is a removable, fixed, CD-ROM, -// RAM disk, or network drive. A trailing backslash is required on the -// rootPathName. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939 -func GetDriveType(rootPathName string) (DriveType, error) { - rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName) - if err != nil { - return DRIVE_UNKNOWN, errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName) - } - - dt, err := _GetDriveType(rootPathNamePtr) - if err != nil { - return DRIVE_UNKNOWN, errors.Wrapf(err, "GetDriveType failed for rootPathName=%v", rootPathName) - } - - return dt, nil -} - -// EnumProcesses retrieves the process identifier for each process object in the -// system. This function can return a max of 65536 PIDs. If there are more -// processes than that then this will not return them all. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682629(v=vs.85).aspx -func EnumProcesses() ([]uint32, error) { - enumProcesses := func(size int) ([]uint32, error) { - var ( - pids = make([]uint32, size) - sizeBytes = len(pids) * sizeofUint32 - bytesWritten uint32 - ) - - err := _EnumProcesses(&pids[0], uint32(sizeBytes), &bytesWritten) - - pidsWritten := int(bytesWritten) / sizeofUint32 - if int(bytesWritten)%sizeofUint32 != 0 || pidsWritten > len(pids) { - return nil, errors.Errorf("EnumProcesses returned an invalid bytesWritten value of %v", bytesWritten) - } - pids = pids[:pidsWritten] - - return pids, err - } - - // Retry the EnumProcesses call with larger arrays if needed. - size := 2048 - var pids []uint32 - for tries := 0; tries < 5; tries++ { - var err error - pids, err = enumProcesses(size) - if err != nil { - return nil, errors.Wrap(err, "EnumProcesses failed") - } - - if len(pids) < size { - break - } - - // Increase the size the pids array and retry the enumProcesses call - // because the array wasn't large enough to hold all of the processes. - size *= 2 - } - - return pids, nil -} - -// GetDiskFreeSpaceEx retrieves information about the amount of space that is -// available on a disk volume, which is the total amount of space, the total -// amount of free space, and the total amount of free space available to the -// user that is associated with the calling thread. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx -func GetDiskFreeSpaceEx(directoryName string) (freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64, err error) { - directoryNamePtr, err := syscall.UTF16PtrFromString(directoryName) - if err != nil { - return 0, 0, 0, errors.Wrapf(err, "UTF16PtrFromString failed for directoryName=%v", directoryName) - } - - err = _GetDiskFreeSpaceEx(directoryNamePtr, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes) - if err != nil { - return 0, 0, 0, err - } - - return freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, nil -} - -// CreateToolhelp32Snapshot takes a snapshot of the specified processes, as well -// as the heaps, modules, and threads used by these processes. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682489(v=vs.85).aspx -func CreateToolhelp32Snapshot(flags, pid uint32) (syscall.Handle, error) { - h, err := _CreateToolhelp32Snapshot(flags, pid) - if err != nil { - return syscall.InvalidHandle, err - } - if h == syscall.InvalidHandle { - return syscall.InvalidHandle, syscall.GetLastError() - } - - return h, nil -} - -// Process32First retrieves information about the first process encountered in a -// system snapshot. -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684834 -func Process32First(handle syscall.Handle) (ProcessEntry32, error) { - processEntry32 := ProcessEntry32{size: sizeofProcessEntry32} - err := _Process32First(handle, &processEntry32) - if err != nil { - return ProcessEntry32{}, errors.Wrap(err, "Process32First failed") - } - - return processEntry32, nil -} - -// Process32Next retrieves information about the next process recorded in a -// system snapshot. When there are no more processes to iterate then -// syscall.ERROR_NO_MORE_FILES is returned (use errors.Cause() to unwrap). -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684836 -func Process32Next(handle syscall.Handle) (ProcessEntry32, error) { - processEntry32 := ProcessEntry32{size: sizeofProcessEntry32} - err := _Process32Next(handle, &processEntry32) - if err != nil { - return ProcessEntry32{}, errors.Wrap(err, "Process32Next failed") - } - - return processEntry32, nil -} - -// UTF16SliceToStringSlice converts slice of uint16 containing a list of UTF16 -// strings to a slice of strings. -func UTF16SliceToStringSlice(buffer []uint16) []string { - // Split the uint16 slice at null-terminators. - var startIdx int - var stringsUTF16 [][]uint16 - for i, value := range buffer { - if value == 0 { - stringsUTF16 = append(stringsUTF16, buffer[startIdx:i]) - startIdx = i + 1 - } - } - - // Convert the utf16 slices to strings. - result := make([]string, 0, len(stringsUTF16)) - for _, stringUTF16 := range stringsUTF16 { - if len(stringUTF16) > 0 { - result = append(result, syscall.UTF16ToString(stringUTF16)) - } - } - - return result -} - -func GetUserProcessParams(handle syscall.Handle, pbi ProcessBasicInformation) (params RtlUserProcessParameters, err error) { - const is32bitProc = unsafe.Sizeof(uintptr(0)) == 4 - - // Offset of params field within PEB structure. - // This structure is different in 32 and 64 bit. - paramsOffset := 0x20 - if is32bitProc { - paramsOffset = 0x10 - } - - // Read the PEB from the target process memory - pebSize := paramsOffset + 8 - peb := make([]byte, pebSize) - nRead, err := ReadProcessMemory(handle, pbi.PebBaseAddress, peb) - if err != nil { - return params, err - } - if nRead != uintptr(pebSize) { - return params, errors.Errorf("PEB: short read (%d/%d)", nRead, pebSize) - } - - // Get the RTL_USER_PROCESS_PARAMETERS struct pointer from the PEB - paramsAddr := *(*uintptr)(unsafe.Pointer(&peb[paramsOffset])) - - // Read the RTL_USER_PROCESS_PARAMETERS from the target process memory - paramsBuf := make([]byte, SizeOfRtlUserProcessParameters) - nRead, err = ReadProcessMemory(handle, paramsAddr, paramsBuf) - if err != nil { - return params, err - } - if nRead != uintptr(SizeOfRtlUserProcessParameters) { - return params, errors.Errorf("RTL_USER_PROCESS_PARAMETERS: short read (%d/%d)", nRead, SizeOfRtlUserProcessParameters) - } - - params = *(*RtlUserProcessParameters)(unsafe.Pointer(¶msBuf[0])) - return params, nil -} - -// ReadProcessUnicodeString returns a zero-terminated UTF-16 string from another -// process's memory. -func ReadProcessUnicodeString(handle syscall.Handle, s *UnicodeString) ([]byte, error) { - // Allocate an extra UTF-16 null character at the end in case the read string - // is not terminated. - extra := 2 - if s.Size&1 != 0 { - extra = 3 // If size is odd, need 3 nulls to terminate. - } - buf := make([]byte, int(s.Size)+extra) - nRead, err := ReadProcessMemory(handle, s.Buffer, buf[:s.Size]) - if err != nil { - return nil, err - } - if nRead != uintptr(s.Size) { - return nil, errors.Errorf("unicode string: short read: (%d/%d)", nRead, s.Size) - } - return buf, nil -} - -// ByteSliceToStringSlice uses CommandLineToArgv API to split an UTF-16 command -// line string into a list of parameters. -func ByteSliceToStringSlice(utf16 []byte) ([]string, error) { - n := len(utf16) - // Discard odd byte - if n&1 != 0 { - n-- - utf16 = utf16[:n] - } - if n == 0 { - return nil, nil - } - terminated := false - for i := 0; i < n && !terminated; i += 2 { - terminated = utf16[i] == 0 && utf16[i+1] == 0 - } - if !terminated { - // Append a null uint16 at the end if terminator is missing - utf16 = append(utf16, 0, 0) - } - var numArgs int32 - argsWide, err := syscall.CommandLineToArgv((*uint16)(unsafe.Pointer(&utf16[0])), &numArgs) - if err != nil { - return nil, err - } - - // Free memory allocated for CommandLineToArgvW arguments. - defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(argsWide))) - - args := make([]string, numArgs) - for idx := range args { - args[idx] = syscall.UTF16ToString(argsWide[idx][:]) - } - return args, nil -} - -// ReadProcessMemory reads from another process memory. The Handle needs to have -// the PROCESS_VM_READ right. -// A zero-byte read is a no-op, no error is returned. -func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (numRead uintptr, err error) { - n := len(dest) - if n == 0 { - return 0, nil - } - if err = _ReadProcessMemory(handle, baseAddress, uintptr(unsafe.Pointer(&dest[0])), uintptr(n), &numRead); err != nil { - return 0, err - } - return numRead, nil -} - -func GetTickCount64() (uptime uint64, err error) { - if uptime, err = _GetTickCount64(); err != nil { - return 0, err - } - return uptime, nil -} - -// Windows API calls -//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx -//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW -//sys _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) = psapi.GetProcessMemoryInfo -//sys _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) = psapi.GetProcessImageFileNameW -//sys _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes -//sys _GetDriveType(rootPathName *uint16) (dt DriveType, err error) = kernel32.GetDriveTypeW -//sys _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses -//sys _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = kernel32.GetDiskFreeSpaceExW -//sys _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32FirstW -//sys _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32NextW -//sys _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) = kernel32.CreateToolhelp32Snapshot -//sys _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQuerySystemInformation -//sys _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQueryInformationProcess -//sys _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW -//sys _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) = advapi32.LookupPrivilegeValueW -//sys _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges -//sys _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) = kernel32.FindFirstVolumeW -//sys _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) = kernel32.FindNextVolumeW -//sys _FindVolumeClose(handle syscall.Handle) (err error) = kernel32.FindVolumeClose -//sys _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) = kernel32.GetVolumePathNamesForVolumeNameW -//sys _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) = kernel32.ReadProcessMemory -//sys _GetTickCount64() (uptime uint64, err error) = kernel32.GetTickCount64 diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/syscall_windows_test.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/syscall_windows_test.go deleted file mode 100644 index 61eff28..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/syscall_windows_test.go +++ /dev/null @@ -1,393 +0,0 @@ -package windows - -import ( - "encoding/binary" - "os" - "runtime" - "syscall" - "testing" - "unsafe" - - "github.com/pkg/errors" - "github.com/stretchr/testify/assert" -) - -func TestGetProcessImageFileName(t *testing.T) { - h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(syscall.Getpid())) - if err != nil { - t.Fatal(err) - } - - filename, err := GetProcessImageFileName(h) - if err != nil { - t.Fatal(err) - } - - t.Logf("GetProcessImageFileName: %v", filename) -} - -func TestGetProcessMemoryInfo(t *testing.T) { - h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(syscall.Getpid())) - if err != nil { - t.Fatal(err) - } - counters, err := GetProcessMemoryInfo(h) - if err != nil { - t.Fatal(err) - } - - t.Logf("GetProcessMemoryInfo: ProcessMemoryCountersEx=%+v", counters) -} - -func TestGetLogicalDriveStrings(t *testing.T) { - drives, err := GetLogicalDriveStrings() - if err != nil { - t.Fatal(err) - } - - t.Logf("GetLogicalDriveStrings: %v", drives) -} - -func TestGetDriveType(t *testing.T) { - drives, err := GetLogicalDriveStrings() - if err != nil { - t.Fatal(err) - } - - for _, drive := range drives { - dt, err := GetDriveType(drive) - if err != nil { - t.Fatal(err) - } - - t.Logf("GetDriveType: drive=%v, type=%v", drive, dt) - } -} - -func TestGetSystemTimes(t *testing.T) { - idle, kernel, user, err := GetSystemTimes() - if err != nil { - t.Fatal(err) - } - - t.Logf("GetSystemTimes: idle=%v, kernel=%v, user=%v", idle, kernel, user) -} - -func TestGlobalMemoryStatusEx(t *testing.T) { - mem, err := GlobalMemoryStatusEx() - if err != nil { - t.Fatal(err) - } - - t.Logf("GlobalMemoryStatusEx: %+v", mem) -} - -func TestEnumProcesses(t *testing.T) { - pids, err := EnumProcesses() - if err != nil { - t.Fatal(err) - } - - t.Logf("EnumProcesses: %v", pids) -} - -func TestGetDiskFreeSpaceEx(t *testing.T) { - drives, err := GetLogicalDriveStrings() - if err != nil { - t.Fatal(err) - } - - for _, drive := range drives { - dt, err := GetDriveType(drive) - if err != nil { - t.Fatal(err) - } - - // Ignore CDROM drives. They return an error if the drive is emtpy. - if dt != DRIVE_CDROM { - free, total, totalFree, err := GetDiskFreeSpaceEx(drive) - if err != nil { - t.Fatal(err) - } - t.Logf("GetDiskFreeSpaceEx: %v, %v, %v", free, total, totalFree) - } - } -} - -func TestGetWindowsVersion(t *testing.T) { - ver := GetWindowsVersion() - assert.True(t, ver.Major >= 5) - t.Logf("GetWindowsVersion: %+v", ver) -} - -func TestCreateToolhelp32Snapshot(t *testing.T) { - handle, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) - if err != nil { - t.Fatal(err) - } - defer syscall.CloseHandle(syscall.Handle(handle)) - - // Iterate over the snapshots until our PID is found. - pid := uint32(syscall.Getpid()) - for { - process, err := Process32Next(handle) - if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES { - break - } - if err != nil { - t.Fatal(err) - } - - t.Logf("CreateToolhelp32Snapshot: ProcessEntry32=%v", process) - - if process.ProcessID == pid { - assert.EqualValues(t, syscall.Getppid(), process.ParentProcessID) - return - } - } - - assert.Fail(t, "Snapshot not found for PID=%v", pid) -} - -func TestNtQuerySystemProcessorPerformanceInformation(t *testing.T) { - cpus, err := NtQuerySystemProcessorPerformanceInformation() - if err != nil { - t.Fatal(err) - } - - assert.Len(t, cpus, runtime.NumCPU()) - - for i, cpu := range cpus { - assert.NotZero(t, cpu.IdleTime) - assert.NotZero(t, cpu.KernelTime) - assert.NotZero(t, cpu.UserTime) - - t.Logf("CPU=%v SystemProcessorPerformanceInformation=%v", i, cpu) - } -} - -func TestNtQueryProcessBasicInformation(t *testing.T) { - h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(syscall.Getpid())) - if err != nil { - t.Fatal(err) - } - - info, err := NtQueryProcessBasicInformation(h) - if err != nil { - t.Fatal(err) - } - defer syscall.CloseHandle(h) - assert.EqualValues(t, os.Getpid(), info.UniqueProcessID) - assert.EqualValues(t, os.Getppid(), info.InheritedFromUniqueProcessID) - - t.Logf("NtQueryProcessBasicInformation: %+v", info) -} - -func TestGetTickCount64(t *testing.T) { - uptime, err := GetTickCount64() - if err != nil { - t.Fatal(err) - } - assert.NotZero(t, uptime) -} - -func TestGetUserProcessParams(t *testing.T) { - h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, false, uint32(syscall.Getpid())) - if err != nil { - t.Fatal(err) - } - info, err := NtQueryProcessBasicInformation(h) - if err != nil { - t.Fatal(err) - } - userProc, err := GetUserProcessParams(h, info) - if err != nil { - t.Fatal(err) - } - defer syscall.CloseHandle(h) - assert.NoError(t, err) - assert.EqualValues(t, os.Getpid(), info.UniqueProcessID) - assert.EqualValues(t, os.Getppid(), info.InheritedFromUniqueProcessID) - assert.NotEmpty(t, userProc.CommandLine) -} - -func TestGetUserProcessParamsInvalidHandle(t *testing.T) { - var handle syscall.Handle - var info = ProcessBasicInformation{PebBaseAddress: uintptr(0)} - userProc, err := GetUserProcessParams(handle, info) - assert.EqualValues(t, err.Error(), "The handle is invalid.") - assert.Empty(t, userProc) -} - -func TestReadProcessUnicodeString(t *testing.T) { - h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, false, uint32(syscall.Getpid())) - if err != nil { - t.Fatal(err) - } - defer syscall.CloseHandle(h) - info, err := NtQueryProcessBasicInformation(h) - if err != nil { - t.Fatal(err) - } - userProc, err := GetUserProcessParams(h, info) - if err != nil { - t.Fatal(err) - } - read, err := ReadProcessUnicodeString(h, &userProc.CommandLine) - if err != nil { - t.Fatal(err) - } - assert.NoError(t, err) - assert.NotEmpty(t, read) -} - -const currentProcessHandle = syscall.Handle(^uintptr(0)) - -func TestReadProcessUnicodeStringTerminator(t *testing.T) { - data := []byte{'H', 0, 'E', 0, 'L', 0, 'L', 0, 'O', 0, 0, 0} - for n := len(data); n >= 0; n-- { - us := UnicodeString{ - Buffer: uintptr(unsafe.Pointer(&data[0])), - Size: uint16(n), - } - read, err := ReadProcessUnicodeString(currentProcessHandle, &us) - if err != nil { - t.Fatal(err) - } - nRead := len(read) - // Strings must match - assert.True(t, nRead >= n) - assert.Equal(t, data[:n], read[:n]) - // result is an array of uint16, can't have odd length. - assert.True(t, nRead&1 == 0) - // Must include a zero terminator at the end. - assert.True(t, nRead >= 2) - assert.Zero(t, read[nRead-1]) - assert.Zero(t, read[nRead-2]) - } -} - -func TestReadProcessUnicodeStringInvalidHandle(t *testing.T) { - var handle syscall.Handle - var cmd = UnicodeString{Size: 5, MaximumLength: 400, Buffer: 400} - read, err := ReadProcessUnicodeString(handle, &cmd) - assert.EqualValues(t, err.Error(), "The handle is invalid.") - assert.Empty(t, read) -} - -func TestByteSliceToStringSlice(t *testing.T) { - cmd := syscall.GetCommandLine() - b := make([]byte, unsafe.Sizeof(cmd)) - binary.LittleEndian.PutUint16(b, *cmd) - hes, err := ByteSliceToStringSlice(b) - assert.NoError(t, err) - assert.NotEmpty(t, hes) -} - -func TestByteSliceToStringSliceEmptyBytes(t *testing.T) { - b := make([]byte, 0) - cmd, err := ByteSliceToStringSlice(b) - assert.NoError(t, err) - assert.Empty(t, cmd) -} - -func mkUtf16bytes(s string) []byte { - n := len(s) - b := make([]byte, n*2) - for idx, val := range s { - *(*uint16)(unsafe.Pointer(&b[idx*2])) = uint16(val) - } - return b -} - -func TestByteSliceToStringSliceNotTerminated(t *testing.T) { - b := mkUtf16bytes("Hello World") - cmd, err := ByteSliceToStringSlice(b) - assert.NoError(t, err) - assert.Len(t, cmd, 2) - assert.Equal(t, "Hello", cmd[0]) - assert.Equal(t, "World", cmd[1]) -} - -func TestByteSliceToStringSliceNotOddSize(t *testing.T) { - b := mkUtf16bytes("BAD")[:5] - cmd, err := ByteSliceToStringSlice(b) - assert.NoError(t, err) - assert.Len(t, cmd, 1) - // Odd character is dropped - assert.Equal(t, "BA", cmd[0]) -} - -func TestReadProcessMemory(t *testing.T) { - h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, false, uint32(syscall.Getpid())) - if err != nil { - t.Fatal(err) - } - info, err := NtQueryProcessBasicInformation(h) - if err != nil { - t.Fatal(err) - } - pebSize := 0x20 + 8 - if unsafe.Sizeof(uintptr(0)) == 4 { - pebSize = 0x10 + 8 - } - defer syscall.CloseHandle(h) - peb := make([]byte, pebSize) - nRead, err := ReadProcessMemory(h, info.PebBaseAddress, peb) - assert.NoError(t, err) - assert.NotEmpty(t, nRead) - assert.EqualValues(t, nRead, uintptr(pebSize)) -} - -// A zero-byte read is a no-op, no error is returned. -func TestReadProcessMemoryZeroByteRead(t *testing.T) { - peb := make([]byte, 0) - var h syscall.Handle - var address uintptr - nRead, err := ReadProcessMemory(h, address, peb) - assert.NoError(t, err) - assert.Empty(t, nRead) -} - -func TestReadProcessMemoryInvalidHandler(t *testing.T) { - peb := make([]byte, 10) - var h syscall.Handle - var address uintptr - nRead, err := ReadProcessMemory(h, address, peb) - assert.Error(t, err) - assert.EqualValues(t, err.Error(), "The handle is invalid.") - assert.Empty(t, nRead) -} - -func TestGetAccessPaths(t *testing.T) { - paths, err := GetAccessPaths() - if err != nil { - t.Fatal(err) - } - assert.NotEmpty(t, paths) - assert.True(t, len(paths) >= 1) -} - -func TestGetVolumes(t *testing.T) { - paths, err := GetVolumes() - if err != nil { - t.Fatal(err) - } - assert.NotEmpty(t, paths) - assert.True(t, len(paths) >= 1) -} - -func TestGetVolumePathsForVolume(t *testing.T) { - volumes, err := GetVolumes() - if err != nil { - t.Fatal(err) - } - assert.NotNil(t, volumes) - assert.True(t, len(volumes) >= 1) - volumePath, err := GetVolumePathsForVolume(volumes[0]) - if err != nil { - t.Fatal(err) - } - assert.NotNil(t, volumePath) - assert.True(t, len(volumePath) >= 1) -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/version.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/version.go deleted file mode 100644 index d0bca89..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/version.go +++ /dev/null @@ -1,43 +0,0 @@ -// +build windows - -package windows - -import ( - "fmt" - "syscall" -) - -// Version identifies a Windows version by major, minor, and build number. -type Version struct { - Major int - Minor int - Build int -} - -// GetWindowsVersion returns the Windows version information. Applications not -// manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version -// value (6.2). -// -// For a table of version numbers see: -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx -func GetWindowsVersion() Version { - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx - ver, err := syscall.GetVersion() - if err != nil { - // GetVersion should never return an error. - panic(fmt.Errorf("GetVersion failed: %v", err)) - } - - return Version{ - Major: int(ver & 0xFF), - Minor: int(ver >> 8 & 0xFF), - Build: int(ver >> 16), - } -} - -// IsWindowsVistaOrGreater returns true if the Windows version is Vista or -// greater. -func (v Version) IsWindowsVistaOrGreater() bool { - // Vista is 6.0. - return v.Major >= 6 && v.Minor >= 0 -} diff --git a/cockroach/patches/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go b/cockroach/patches/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go deleted file mode 100644 index 75f19c0..0000000 --- a/cockroach/patches/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go +++ /dev/null @@ -1,378 +0,0 @@ -// Code generated by 'go generate'; DO NOT EDIT. - -package windows - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return nil - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) - return e -} - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - modpsapi = windows.NewLazySystemDLL("psapi.dll") - modntdll = windows.NewLazySystemDLL("ntdll.dll") - modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") - - procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") - procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") - procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") - procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW") - procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") - procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") - procEnumProcesses = modpsapi.NewProc("EnumProcesses") - procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") - procProcess32FirstW = modkernel32.NewProc("Process32FirstW") - procProcess32NextW = modkernel32.NewProc("Process32NextW") - procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") - procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") - procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") - procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") - procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") - procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") - procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") - procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") - procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") - procGetTickCount64 = modkernel32.NewProc("GetTickCount64") -) - -func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) { - r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) - length = uint32(r0) - if length == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(outImageFileName)), uintptr(size)) - length = uint32(r0) - if length == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) { - r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) { - r0, _, e1 := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) - dt = DriveType(r0) - if dt == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { - r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processID), 0) - handle = syscall.Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { - r0, _, e1 := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInformationClass), uintptr(unsafe.Pointer(systemInformation)), uintptr(systemInformationLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) - ntstatus = uint32(r0) - if ntstatus == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { - r0, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInformationClass), uintptr(unsafe.Pointer(processInformation)), uintptr(processInformationLength), uintptr(unsafe.Pointer(returnLength)), 0) - ntstatus = uint32(r0) - if ntstatus == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - return __LookupPrivilegeName(_p0, luid, buffer, size) -} - -func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - var _p1 *uint16 - _p1, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return __LookupPrivilegeValue(_p0, _p1, luid) -} - -func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { - var _p0 uint32 - if releaseAll { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) - success = r0 != 0 - if true { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(size), 0) - handle = syscall.Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(volumeName)), uintptr(size)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _FindVolumeClose(handle syscall.Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(handle), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(volumeName) - if err != nil { - return - } - return __GetVolumePathNamesForVolumeName(_p0, buffer, bufferSize, length) -} - -func __GetVolumePathNamesForVolumeName(volumeName *uint16, buffer *uint16, bufferSize uint32, length *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferSize), uintptr(unsafe.Pointer(length)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(handle), uintptr(baseAddress), uintptr(buffer), uintptr(size), uintptr(unsafe.Pointer(numRead)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func _GetTickCount64() (uptime uint64, err error) { - r0, _, e1 := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) - uptime = uint64(r0) - if uptime == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} diff --git a/cockroach/patches/github.com/knz/go-libedit/.gitignore b/cockroach/patches/github.com/knz/go-libedit/.gitignore deleted file mode 100644 index d2a06ef..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/.gitignore +++ /dev/null @@ -1,56 +0,0 @@ -# Prerequisites -*.d - -# Object files -*.o -*.ko -*.obj -*.elf - -# Linker output -*.ilk -*.map -*.exp - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -*.su -*.idb -*.pdb - -# Kernel Module Compile Results -*.mod* -*.cmd -.tmp_versions/ -modules.order -Module.symvers -Mkfile.old -dkms.conf - -# Generated Go code that may be injected by downstream dependencies -# (e.g., CockroachDB) into a vendored copy of this library. -zcgo_flags*.go diff --git a/cockroach/patches/github.com/knz/go-libedit/.travis.yml b/cockroach/patches/github.com/knz/go-libedit/.travis.yml deleted file mode 100644 index afd70cc..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -matrix: - include: - - os: osx - osx_image: xcode8.3 - - os: linux - dist: trusty diff --git a/cockroach/patches/github.com/knz/go-libedit/LICENSE b/cockroach/patches/github.com/knz/go-libedit/LICENSE deleted file mode 100644 index d9a10c0..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor 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, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/cockroach/patches/github.com/knz/go-libedit/README.md b/cockroach/patches/github.com/knz/go-libedit/README.md deleted file mode 100644 index f31e2eb..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# go-libedit - -Go wrapper around `libedit`, a replacement to GNU readline using the BSD license. - -[![travis](https://travis-ci.org/knz/go-libedit.svg?branch=master)](https://travis-ci.org/knz/go-libedit) - -How to use: - -- `go build` / `go install` -- see `test/example.go` for a demo. -- basic idea: call `Init()` once. Then call `SetLeftPrompt()` and - `GetLine()` as needed. Finally call `Close()`. - -## How to force using the system-wide libedit on GNU/Linux - -By default, the **go-libedit** package uses the bundled `libedit` -sources on GNU/Linux, so that `go get` works out of the box. - -To force the package to use a system-wide libedit instead, edit `unix/editline_unix.go` as follows: - -- remove the line containing `#cgo linux CFLAGS` -- change the line containing `#cgo linux CPPFLAGS` to read: `#cgo linux CPPFLAGS: -I/usr/include/editline -Ishim` -- change the line containing `#cgo linux LDFLAGS` to read: `#cgo linux LDFLAGS: -ledit` - -## macOS/OSX due to restrictions due to changes macOS Mojave - -macOS Mojave is shipped with a broken/restricted libedit where the -completion API is not published. Because it is not possible to -automatically detect macOS versions, **go-libedit** will use a reduced -autocompletion facility on all versions of macOS instead. - -This autocompletion facility lacks the following features from libedit: - -- it cannot autocomplete file and directory names. -- it does not display a list of possible completions. Only the fact - that more than 1 completion is available is signalled using - a terminal beep. - -## How to refresh the bundled libedit sources - -(Only needed when upgrading the bundled `libedit` to a newer version.) - -This procedure should be ran on a Debian/Ubuntu system. - -1. ensure that `/etc/apt/sources.list` contains source repositories, i.e. the `deb-src` lines are uncommented. Run `apt-get update` as necessary. -2. run: - - ``` - $ sudo apt-get install libbsd libbsd-dev libncurses-dev` - $ cd src - $ bash refresh.sh - ``` diff --git a/cockroach/patches/github.com/knz/go-libedit/common.go b/cockroach/patches/github.com/knz/go-libedit/common.go deleted file mode 100644 index 1ab0482..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/common.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -package libedit - -import ( - common "github.com/knz/go-libedit/common" -) - -type CompletionGenerator = common.CompletionGenerator - -var ErrInterrupted = common.ErrInterrupted -var ErrWidecharNotSupported = common.ErrWidecharNotSupported diff --git a/cockroach/patches/github.com/knz/go-libedit/common/editline.go b/cockroach/patches/github.com/knz/go-libedit/common/editline.go deleted file mode 100644 index 460bb13..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/common/editline.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -package libedit_common - -import "errors" - -type CompletionGenerator interface { - GetCompletions(word string) []string -} - -var ErrInterrupted = errors.New("interrupted") -var ErrWidecharNotSupported = errors.New("cannot enable wide character support") diff --git a/cockroach/patches/github.com/knz/go-libedit/editline_other.go b/cockroach/patches/github.com/knz/go-libedit/editline_other.go deleted file mode 100644 index febccd1..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/editline_other.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -// +build !darwin,!freebsd,!illumos,!linux,!openbsd,!netbsd,!dragonfly - -package libedit - -import ( - "os" - - edit "github.com/knz/go-libedit/other" -) - -type EditLine = edit.EditLine - -func Init(x string, w bool) (EditLine, error) { return edit.Init(x, w) } -func InitFiles(a string, w bool, stdin, stdout, stderr *os.File) (EditLine, error) { - return edit.InitFiles(a, w, stdin, stdout, stderr) -} diff --git a/cockroach/patches/github.com/knz/go-libedit/editline_unix.go b/cockroach/patches/github.com/knz/go-libedit/editline_unix.go deleted file mode 100644 index b0922cc..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/editline_unix.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -// +build darwin freebsd illumos linux openbsd netbsd dragonfly - -package libedit - -import ( - "os" - - edit "github.com/knz/go-libedit/unix" -) - -type EditLine = edit.EditLine - -func Init(x string, w bool) (EditLine, error) { return edit.Init(x, w) } -func InitFiles(a string, w bool, stdin, stdout, stderr *os.File) (EditLine, error) { - return edit.InitFiles(a, w, stdin, stdout, stderr) -} diff --git a/cockroach/patches/github.com/knz/go-libedit/other/editline_other.go b/cockroach/patches/github.com/knz/go-libedit/other/editline_other.go deleted file mode 100644 index 5c9b5ff..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/other/editline_other.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -package libedit_other - -import ( - "bufio" - "os" - - common "github.com/knz/go-libedit/common" -) - -type EditLine int -type CompletionGenerator = common.CompletionGenerator - -type state struct { - reader *bufio.Reader - promptLeft string - line string - stdin, stdout, stderr *os.File -} - -var editors []state - -func Init(x string, w bool) (EditLine, error) { - return InitFiles(x, w, os.Stdin, os.Stdout, os.Stderr) -} - -func InitFiles(_ string, _ bool, stdin, stdout, stderr *os.File) (EditLine, error) { - st := state{ - reader: bufio.NewReader(stdin), - stdin: stdin, stdout: stdout, stderr: stderr, - } - editors = append(editors, st) - return EditLine(len(editors) - 1), nil -} - -func (el EditLine) RebindControlKeys() {} -func (el EditLine) Close() {} -func (el EditLine) SaveHistory() error { return nil } -func (el EditLine) AddHistory(_ string) error { return nil } -func (el EditLine) LoadHistory(_ string) error { return nil } -func (el EditLine) SetAutoSaveHistory(_ string, _ bool) {} -func (el EditLine) UseHistory(_ int, _ bool) error { return nil } -func (el EditLine) SetCompleter(_ CompletionGenerator) {} -func (el EditLine) SetRightPrompt(_ string) {} - -func (el EditLine) Stdin() *os.File { - return editors[el].stdin -} - -func (el EditLine) Stdout() *os.File { - return editors[el].stdout -} - -func (el EditLine) Stderr() *os.File { - return editors[el].stderr -} - -func (el EditLine) SetLeftPrompt(l string) { - st := &editors[el] - st.promptLeft = l -} - -func (el EditLine) GetLineInfo() (string, int) { - st := &editors[el] - return st.line, len(st.line) -} - -func (el EditLine) GetLine() (string, error) { - st := &editors[el] - st.stdout.WriteString(st.promptLeft) - st.stdout.Sync() - line, err := st.reader.ReadString('\n') - if err != nil { - return "", err - } - st.line = line - return st.line, nil -} diff --git a/cockroach/patches/github.com/knz/go-libedit/test/example.go b/cockroach/patches/github.com/knz/go-libedit/test/example.go deleted file mode 100644 index 0eec3e7..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/test/example.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -package main - -import ( - "fmt" - "io" - "log" - "strings" - "time" - - libedit "github.com/knz/go-libedit" -) - -type example struct{} - -func (_ example) GetCompletions(word string) []string { - if strings.HasPrefix(word, "he") { - return []string{"hello!"} - } - return nil -} - -func main() { - // Open and immediately close a libedit instance to test that nonzero editor - // IDs are tracked correctly. - el, err := libedit.Init("example", true) - if err != nil { - log.Fatal(err) - } - el.Close() - - el, err = libedit.Init("example", true) - if err != nil { - log.Fatal(err) - } - defer el.Close() - - // RebindControlKeys ensures that Ctrl+C, Ctrl+Z, Ctrl+R and Tab are - // properly bound even if the user's .editrc has used bind -e or - // bind -v to load a predefined keymap. - el.RebindControlKeys() - - el.UseHistory(-1, true) - el.LoadHistory("hist") - el.SetAutoSaveHistory("hist", true) - el.SetCompleter(example{}) - el.SetLeftPrompt("hello> ") - el.SetRightPrompt("(-:") - for { - s, err := el.GetLine() - if err != nil { - if err == io.EOF { - break - } - if err == libedit.ErrInterrupted { - fmt.Printf("interrupted! (%q)\n", s) - continue - } - log.Fatal(err) - } - fmt.Printf("echo %q\n", s) - time.Sleep(2 * time.Second) - fmt.Println("ok") - if err := el.AddHistory(s); err != nil { - log.Fatal(err) - } - } - fmt.Println("goodbye!") -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/c_editline.c b/cockroach/patches/github.com/knz/go-libedit/unix/c_editline.c deleted file mode 100644 index e03ac18..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/c_editline.c +++ /dev/null @@ -1,506 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "c_editline.h" - -char *go_libedit_emptycstring = (char*)""; -const char* go_libedit_mode_read = "r"; -const char* go_libedit_mode_write = "w"; -const char* go_libedit_mode_append = "a"; -const char* go_libedit_locale1 = "en_US.UTF-8"; -const char* go_libedit_locale2 = "C.UTF-8"; - -void go_libedit_set_string_array(char **ar, int p, char *s) { - ar[p] = s; -} - -struct clientdata { - int id; - int bracketed_paste; -}; - -struct clientdata* go_libedit_get_clientdata(EditLine *el) { - struct clientdata* cd; - el_get(el, EL_CLIENTDATA, &cd); - return cd; -} - -int go_libedit_set_clientdata(EditLine *el, struct clientdata cd) { - struct clientdata* pcd = malloc(sizeof(struct clientdata)); - if (pcd == NULL) { - return -1; - } - *pcd = cd; - return el_set(el, EL_CLIENTDATA, pcd); -} - -/************* terminals ************/ - -const char term_bp_off[] = "\033[?2004l"; -const char term_bp_on[] = "\033[?2004h"; -const char term_bp_start[] = "\033[200~"; -const wchar_t term_bp_end[] = L"\033[201~"; - -int go_libedit_term_supports_bracketed_paste(EditLine* el) { - // terminfo does not track support for bracketed paste, so we manually - // whitelist known-good TERM values: - // - // - "screen*" matches tmux without italics support and screen. - // - "xterm*" matches Terminal.app, iTerm2, GNOME terminal, and probably - // others. - // - "tmux*" matches tmux with italics support. - // - "ansi*" matches a generic ANSI-compatible terminal. - // - "st*" matches suckless's "simple terminal". - // - // Modern versions of all the programs listed above support bracketed paste; - // older versions harmlessly ignore the control codes. - char* term = getenv("TERM"); - if (!term) - return 0; - return strncmp(term, "screen", 6) == 0 - || strncmp(term, "xterm", 5) == 0 - || strncmp(term, "tmux", 4) == 0 - || strncmp(term, "ansi", 4) == 0 - || strncmp(term, "st", 2) == 0; -} - -static unsigned char _el_bracketed_paste(EditLine *el, int ch) { - size_t endsz = (sizeof(term_bp_end) / sizeof(term_bp_end[0]))- 1; - wchar_t* buf = NULL; - size_t bufsz = 0; - size_t i = 0; - do { - if (i >= bufsz) { - // Out of space. Reallocate. - bufsz = (bufsz == 0 ? 1024 : bufsz * 2); - wchar_t* newbuf = realloc(buf, bufsz * sizeof(buf[0])); - if (newbuf == NULL) { - free(buf); - return CC_ERROR; - } else { - buf = newbuf; - } - } - // Read one character. - if (el_wgetc(el, &buf[i++]) == -1) { - free(buf); - return CC_EOF; - } - // Continue until the buffer ends with term_bp_end. - } while (i < endsz || wcsncmp(&buf[i-endsz], term_bp_end, endsz) != 0); - buf[i-endsz] = L'\0'; - if (i > endsz && el_winsertstr(el, buf) == -1) { - FILE *ferr; - el_get(el, EL_GETFP, 2, &ferr); - fputs("\nerror: pasted text too large for buffer\n", ferr); - free(buf); - return CC_REDISPLAY; - } - free(buf); - return CC_REFRESH; -} - - -/************** prompts **************/ - -static char *go_libedit_lprompt_str; -static char *go_libedit_rprompt_str; - -static char* go_libedit_lprompt(EditLine *el) { - return go_libedit_lprompt_str ? go_libedit_lprompt_str : "?"; -} - -static char* go_libedit_rprompt(EditLine *el) { - return go_libedit_rprompt_str ? go_libedit_rprompt_str : ""; -} - - -/********** initialization ***********/ - -static unsigned char _el_rl_complete(EditLine *, int); - -static volatile int g_interrupted; -static unsigned char _el_rl_intr(EditLine * e, int c) { - g_interrupted = 1; - return CC_NEWLINE; -} - -static unsigned char _el_rl_tstp(EditLine * e, int c) { - kill(0, SIGTSTP); - return CC_REDISPLAY; -} - - -void go_libedit_rebind_ctrls(EditLine *e) { - // Handle Ctrl+C gracefully. - el_set(e, EL_ADDFN, "rl_interrupt", - "ReadLine compatible interrupt function", - _el_rl_intr); - el_set(e, EL_BIND, "^C", "rl_interrupt", NULL); - - // Handle Ctrl+Z gracefully. - el_set(e, EL_ADDFN, "rl_tstp", - "ReadLine compatible suspend function", - _el_rl_tstp); - el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); - - // Word completion - this has to go after loading the default - // mappings. - el_set(e, EL_ADDFN, "rl_complete", - "ReadLine compatible completion function", - _el_rl_complete); - el_set(e, EL_BIND, "^I", "rl_complete", NULL); - - // Readline history search. People are used to this. - el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL); -} - -EditLine* go_libedit_init(int id, char *appName, void** el_signal, - FILE* fin, FILE* fout, FILE *ferr) { - // Prepare signal handling. - (*el_signal) = 0; - - // Do we really want to edit? - int editmode = 1; - struct termios t; - if (tcgetattr(fileno(fin), &t) != -1 && (t.c_lflag & ECHO) == 0) - editmode = 0; - - // Create the editor. - - // We need to mark here in the terminal config that Ctrl+C doesn't - // do anything, so that el_init() captures and saves that - // information. It will be used every time el_gets() starts, - // when reset the terminal to "known settings". - EditLine *e = el_init(appName, fin, fout, ferr); - - if (!e) { - return NULL; - } - - struct clientdata cd = { - .id = id, - .bracketed_paste = go_libedit_term_supports_bracketed_paste(e), - }; - if (go_libedit_set_clientdata(e, cd) != 0) - return NULL; - - if (!editmode) - el_set(e, EL_EDITMODE, 0); - - // Set up the prompt functions. Unfortunately we cannot use a real - // callback into Go because Go doesn't like being called from an - // alternate signal stack. - el_set(e, EL_PROMPT, go_libedit_lprompt); - el_set(e, EL_RPROMPT, go_libedit_rprompt); - - // Load the emacs keybindings by default. We need - // to do that before the defaults are overridden below. - el_set(e, EL_EDITOR, "emacs"); - - go_libedit_rebind_ctrls(e); - - // Home/End keys. - el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL); - el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL); - el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL); - el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL); - el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL); - el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL); - - // Delete/Insert keys. - el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL); - el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL); - - // Ctrl-left-arrow and Ctrl-right-arrow for word moving. - el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL); - el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL); - el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL); - el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL); - el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL); - el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); - - // Bracketed paste. - if (cd.bracketed_paste) { - el_set(e, EL_ADDFN, "ed-bracketed-paste", - "Begin bracketed paste", - _el_bracketed_paste); - el_set(e, EL_BIND, term_bp_start, "ed-bracketed-paste", NULL); - } - - // Read the settings from the configuration file. - el_source(e, NULL); - - return e; -} - -/************** history **************/ - -History* go_libedit_setup_history(EditLine *el, int maxEntries, int dedup) { - if (!el) { - errno = EINVAL; - return NULL; - } - - History *h = history_init(); - if (!h) - return NULL; - - HistEvent ev; - history(h, &ev, H_SETSIZE, maxEntries); - history(h, &ev, H_SETUNIQUE, dedup); - - el_set(el, EL_HIST, history, h); - return h; -} - -static int readwrite_history(History *h, int op, char *filename) { - if (!h || !filename) { - errno = EINVAL; - return -1; - } - errno = 0; - HistEvent ev; - int res; - if ((res = history(h, &ev, op, filename)) == -1) { - if (!errno) - errno = EINVAL; - return -1; - } - return res; -} - -int go_libedit_read_history(History *h, char *filename) { - return readwrite_history(h, H_LOAD, filename); -} - -int go_libedit_write_history(History *h, char *filename) { - return readwrite_history(h, H_SAVE, filename); -} - -int go_libedit_add_history(History *h, char *line) { - return readwrite_history(h, H_ENTER, line); -} - - -/************* completion ************/ - -// We can't use rl_complete directly because that uses the readline -// emulation's own EditLine instance, and here we want to use our -// own. So basically re-implement on top of editline's internal -// fn_complete function. - -// Except that the folk at OSX/Darwin have decided that fn_complete -// should not be exported so we can't use any of that on that platform. - -#if !defined(__APPLE__) || !defined(__MACH__) -int fn_complete(EditLine *el, - char *(*complet_func)(const char *, int), - char **(*attempted_completion_function)(const char *, int, int), - const wchar_t *word_break, const wchar_t *special_prefixes, - const char *(*app_func)(const char *), size_t query_items, - int *completion_type, int *over, int *point, int *end, - const wchar_t *(*find_word_start_func)(const wchar_t *, const wchar_t *), - wchar_t *(*dequoting_func)(const wchar_t *), - char *(*quoting_func)(const char *)); -#else -#include "stub_fn_complete.i" -#endif - -static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{("; - - -// In an unfortunate turn of circumstances, editline's fn_complete -// API does not pass the EditLine instance nor the clientdata field -// to the attempted_completion_function, yet we really want this. -// So we'll pass it as a hidden argument via a global variable. -// This effectively makes the entire library thread-unsafe. :'-( - -static struct clientdata* global_instance; - -static char **wrap_autocomplete(const char *word, int unused1, int unused2) { - return go_libedit_getcompletions(global_instance->id, (char*)word); -} - -static const char *_rl_completion_append_character_function(const char *_) { - static const char *sp = " "; - return sp; -} - -static unsigned char _el_rl_complete(EditLine *el, int ch) { - int avoid_filename_completion = 1; - - // Urgh... - global_instance = go_libedit_get_clientdata(el); - - return (unsigned char)fn_complete( - el, - NULL /* complet_func */, - wrap_autocomplete /* attempted_completion_function */, - break_chars /* word_break */, - NULL /* special_prefixes */, - _rl_completion_append_character_function /* app_func */, - 100 /* query_items */, - NULL /* completion_type */, - &avoid_filename_completion /* over */, - NULL /* point */, - NULL /* end */, - NULL /* find_word_start_func */, - NULL /* dequoting_func */, - NULL /* quoting_func */ - ); -} - - -/*************** el_gets *************/ - -static EditLine* volatile g_el; -static volatile int g_fdout; - -static void winch_handler(int signo) { - // Tell libedit about the window size change. - el_resize(g_el); - - // Now we want to redraw the current line, however libedit at this - // point expects the cursor to be at the beginning of the - // line. Make it so. - write(g_fdout, "\r", 1); - - // Ready to refresh. Do it. - el_set(g_el, EL_REFRESH); -} - -static void cont_handler(int signo) { - // This can happen when the process comes back to - // the foreground, after being suspended and - // perhaps after a shell has reset the terminal. - // - // So refresh the input stream's termios. - // We don't really need to reset intr here, just - // to call SETTY -d so that the editor's termios - // get re-loaded. - el_set(g_el, EL_SETTY, "-d", "intr=", NULL); - - // Then re-load the terminal settings (size etc). - el_set(g_el, EL_PREP_TERM, 1); - // And redraw the current input line. - el_set(g_el, EL_REFRESH); -} - -void *go_libedit_gets(EditLine *el, char *lprompt, char *rprompt, - void *p_sigcfg, int *count, int *interrupted, int widechar) { - void *ret = NULL; - int saveerr = 0; - - // We need global references to the libedit object and output file descriptor - // for use in the signal handlers. - g_el = el; - FILE *fout; - el_get(el, EL_GETFP, 1, &fout); - g_fdout = fileno(fout); - - // Save and clear Go's signal handlers, set up our own for SIGCONT and SIGWINCH. - struct sigaction osa[2]; - struct sigaction nsa; - - memset(osa, 0, sizeof(osa)); - if (-1 == sigaction(SIGCONT, 0, &osa[0])) - return 0; - if (-1 == sigaction(SIGWINCH, 0, &osa[1])) - return 0; - - memset(&nsa, 0, sizeof(nsa)); - nsa.sa_flags = SA_RESTART|SA_ONSTACK; - - // Use sigaction() here not __sigaction(). On Darwin this ensures - // that the standard libc trampoline is used for our (C) handler. - nsa.sa_handler = cont_handler; - sigaction(SIGCONT, &nsa, 0); - nsa.sa_handler = winch_handler; - sigaction(SIGWINCH, &nsa, 0); - - // Disable terminal translation of ^C and ^Z to SIGINT and SIGTSTP. - el_set(el, EL_SETTY, "-d", "intr=", NULL); - el_set(el, EL_SETTY, "-d", "susp=", NULL); - el_set(el, EL_SETTY, "-x", "intr=", NULL); - el_set(el, EL_SETTY, "-x", "susp=", NULL); - el_set(el, EL_SETTY, "-q", "intr=", NULL); - el_set(el, EL_SETTY, "-q", "susp=", NULL); - el_reset(el); - - // Request bracketed paste mode if supported by the terminal. - struct clientdata* cd = go_libedit_get_clientdata(el); - if (cd->bracketed_paste) - fputs(term_bp_on, fout); - - // Install the prompts. - go_libedit_lprompt_str = lprompt; - go_libedit_rprompt_str = rprompt; - - // Read the line. - g_interrupted = 0; - if (widechar) { - ret = (void *)el_wgets(el, count); - } else { - ret = (void *)el_gets(el, count); - } - // Save errno so we have something meaningful to return below. - saveerr = errno; - if (g_interrupted != 0) { - saveerr = EINTR; - *interrupted = 1; - ret = NULL; - } - - go_libedit_lprompt_str = NULL; - go_libedit_rprompt_str = NULL; - - // Restore Go's signal handlers. - sigaction(SIGCONT, &osa[0], 0); - sigaction(SIGWINCH, &osa[1], 0); - - // Turn off bracketed paste mode if we turned it on. - if (cd->bracketed_paste) - fputs(term_bp_off, fout); - - // If libedit got interrupted it may not have restored the - // terminal settings properly. Restore them. - el_set(el, EL_SETTY, "-d", "intr=^C", NULL); - el_set(el, EL_SETTY, "-d", "susp=^Z", NULL); - el_set(el, EL_SETTY, "-x", "intr=^C", NULL); - el_set(el, EL_SETTY, "-x", "susp=^Z", NULL); - el_set(el, EL_SETTY, "-q", "intr=^C", NULL); - el_set(el, EL_SETTY, "-q", "susp=^Z", NULL); - - // Restore errno. - errno = saveerr; - return ret; -} - -void go_libedit_close(EditLine *el, void *p_sigcfg) { - el_end(el); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/c_editline.h b/cockroach/patches/github.com/knz/go-libedit/unix/c_editline.h deleted file mode 100644 index 6da4ae5..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/c_editline.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -#ifndef GO_LIBEDIT_H -#define GO_LIBEDIT_H - -#include -#include - -typedef char* pchar; - -EditLine* go_libedit_init(int id, char *appName, void **sigcfg, - FILE* fin, FILE* fout, FILE *ferr); -void go_libedit_close(EditLine *el, void *sigcfg); -void go_libedit_rebind_ctrls(EditLine *el); - -extern char *go_libedit_emptycstring; -extern const char* go_libedit_mode_read; -extern const char* go_libedit_mode_write; -extern const char* go_libedit_mode_append; -extern const char *go_libedit_locale1; -extern const char *go_libedit_locale2; - -struct clientdata* go_libedit_get_clientdata(EditLine *el); -int go_libedit_set_clientdata(EditLine *el, struct clientdata cd); -void go_libedit_set_string_array(char **ar, int p, char *s); - -void *go_libedit_gets(EditLine *el, char *lprompt, char *rprompt, - void *sigcfg, int *count, int *interrupted, int wc); - -History* go_libedit_setup_history(EditLine *el, int maxEntries, int dedup); -int go_libedit_read_history(History *h, char *filename); -int go_libedit_write_history(History *h, char *filename); -int go_libedit_add_history(History *h, char *line); - -// Go-generated via //export -char *go_libedit_prompt_left(EditLine *el); -char *go_libedit_prompt_right(EditLine *el); -char **go_libedit_getcompletions(int instance, char *word); - - -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/editline_unix.go b/cockroach/patches/github.com/knz/go-libedit/unix/editline_unix.go deleted file mode 100644 index 2000e2c..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/editline_unix.go +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright 2017 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -package libedit_unix - -import ( - "errors" - "fmt" - "io" - "os" - "syscall" - "unsafe" - - common "github.com/knz/go-libedit/common" -) - -// #cgo openbsd netbsd illumos freebsd dragonfly darwin LDFLAGS: -ledit -// #cgo openbsd netbsd illumos freebsd dragonfly darwin CPPFLAGS: -Ishim -// #cgo linux LDFLAGS: -lncurses -// #cgo linux CFLAGS: -Wno-unused-result -Wno-pointer-sign -// #cgo linux CPPFLAGS: -Isrc -Isrc/c-libedit -Isrc/c-libedit/editline -Isrc/c-libedit/linux-build -D_GNU_SOURCE -// -// #include -// #include -// #include -// #include -// #include -// -// #include -// #include "c_editline.h" -import "C" - -type EditLine int -type CompletionGenerator = common.CompletionGenerator - -type state struct { - el *C.EditLine - sigcfg unsafe.Pointer - h *C.History - cIn, cOut, cErr *C.FILE - inf, outf, errf *os.File - cPromptLeft *C.char - cPromptRight *C.char - completer CompletionGenerator - histFile *C.char - autoSaveHistory bool - wideChars int -} - -var editors []state - -var errUnknown = errors.New("unknown error") - -func Init(appName string, wideChars bool) (EditLine, error) { - return InitFiles(appName, wideChars, os.Stdin, os.Stdout, os.Stderr) -} - -func InitFiles(appName string, wideChars bool, inf, outf, errf *os.File) (e EditLine, err error) { - if err := setWideChars(wideChars); err != nil { - return -1, err - } - var inFile, outFile, errFile *C.FILE - defer func() { - if err == nil { - return - } - if inFile != nil { - C.fclose(inFile) - } - if outFile != nil { - C.fclose(outFile) - } - if errFile != nil { - C.fclose(errFile) - } - }() - - inFile, err = C.fdopen(C.dup(C.int(inf.Fd())), C.go_libedit_mode_read) - if err != nil { - return -1, fmt.Errorf("fdopen(inf): %v", err) - } - outFile, err = C.fdopen(C.dup(C.int(outf.Fd())), C.go_libedit_mode_write) - if err != nil { - return -1, fmt.Errorf("fdopen(outf): %v", err) - } - errFile, err = C.fdopen(C.dup(C.int(errf.Fd())), C.go_libedit_mode_write) - if err != nil { - return -1, fmt.Errorf("fdopen(errf): %v", err) - } - cAppName := C.CString(appName) - defer C.free(unsafe.Pointer(cAppName)) - var sigcfg unsafe.Pointer - id := C.int(len(editors)) - el, err := C.go_libedit_init(id, cAppName, &sigcfg, inFile, outFile, errFile) - // If the settings file did not exist, ignore the error. - if err == syscall.ENOENT { - err = nil - } - if el == nil || err != nil { - if err == nil { - err = errUnknown - } - return -1, fmt.Errorf("el_init: %v", err) - } - - wc := 0 - if wideChars { - wc = 1 - } - st := state{ - el: el, - sigcfg: sigcfg, - inf: inf, outf: outf, errf: errf, - cIn: inFile, cOut: outFile, cErr: errFile, - wideChars: wc, - } - editors = append(editors, st) - return EditLine(len(editors) - 1), nil -} - -func setWideChars(set bool) error { - if set { - // We need to set the locale to something UTF-8 to enable wide char support. - l := C.setlocale(C.LC_CTYPE, C.go_libedit_locale1) - if l == nil { - l = C.setlocale(C.LC_CTYPE, C.go_libedit_locale2) - } - if l == nil { - return common.ErrWidecharNotSupported - } - } - return nil -} - -func (el EditLine) RebindControlKeys() { - st := &editors[el] - C.go_libedit_rebind_ctrls(st.el) -} - -func (el EditLine) Close() { - st := &editors[el] - if st.el == nil { - // Already closed. - return - } - C.go_libedit_close(st.el, st.sigcfg) - if st.h != nil { - C.history_end(st.h) - } - if st.cPromptLeft != nil { - C.free(unsafe.Pointer(st.cPromptLeft)) - } - if st.cPromptRight != nil { - C.free(unsafe.Pointer(st.cPromptRight)) - } - if st.histFile != nil { - C.free(unsafe.Pointer(st.histFile)) - } - C.fclose(st.cIn) - C.fclose(st.cOut) - C.fclose(st.cErr) - *st = state{} -} - -var errNoHistory = errors.New("history not configured") -var errNoFileConfigured = errors.New("no savefile configured") - -func (el EditLine) SaveHistory() error { - st := &editors[el] - if st.h == nil { - return errNoHistory - } - if st.histFile == nil { - return errNoFileConfigured - } - _, err := C.go_libedit_write_history(st.h, st.histFile) - if err != nil { - return fmt.Errorf("write_history: %v", err) - } - return nil -} - -func (el EditLine) AddHistory(line string) error { - st := &editors[el] - if st.h == nil { - return errNoHistory - } - - cLine := C.CString(line) - defer C.free(unsafe.Pointer(cLine)) - - _, err := C.go_libedit_add_history(st.h, cLine) - if err != nil { - return fmt.Errorf("add_history: %v", err) - } - - if st.autoSaveHistory && st.histFile != nil { - _, err := C.go_libedit_write_history(st.h, st.histFile) - if err != nil { - return fmt.Errorf("write_history: %v", err) - } - } - return nil -} - -func (el EditLine) LoadHistory(file string) error { - st := &editors[el] - if st.h == nil { - return errNoHistory - } - - histFile := C.CString(file) - defer C.free(unsafe.Pointer(histFile)) - _, err := C.go_libedit_read_history(st.h, histFile) - if err != nil && err != syscall.ENOENT { - return fmt.Errorf("read_history: %v", err) - } - return nil -} - -func (el EditLine) SetAutoSaveHistory(file string, autoSave bool) { - st := &editors[el] - if st.h == nil { - return - } - var newHistFile *C.char - if file != "" { - newHistFile = C.CString(file) - } - if st.histFile != nil { - C.free(unsafe.Pointer(st.histFile)) - st.histFile = nil - } - st.histFile = newHistFile - st.autoSaveHistory = autoSave -} - -func (el EditLine) UseHistory(maxEntries int, dedup bool) error { - st := &editors[el] - - cDedup := 0 - if dedup { - cDedup = 1 - } - - cMaxEntries := C.int(maxEntries) - if maxEntries < 0 { - cMaxEntries = C.INT_MAX - } - - h, err := C.go_libedit_setup_history(st.el, cMaxEntries, C.int(cDedup)) - if err != nil { - return fmt.Errorf("init_history: %v", err) - } - if st.h != nil { - C.history_end(st.h) - } - st.h = h - return nil -} - -var errUnknownError = errors.New("unknown error") - -func (el EditLine) GetLine() (string, error) { - st := &editors[el] - - var count C.int - var interrupted C.int - s, err := C.go_libedit_gets(st.el, st.cPromptLeft, st.cPromptRight, - st.sigcfg, &count, &interrupted, C.int(st.wideChars)) - if interrupted > 0 { - // Reveal the partial line. - line, _ := el.GetLineInfo() - C.el_reset(st.el) - return line, common.ErrInterrupted - } - if count == -1 { - if err != nil { - return "", err - } - return "", errUnknownError - } - if s == nil { - return "", io.EOF - } - return convertRunes(st.wideChars != 0, s, count), nil -} - -func convertRunes(wideChars bool, s unsafe.Pointer, count C.int) string { - if wideChars { - var buf [C.MB_LEN_MAX]C.char - sbuf := make([]byte, 0, int(count)) - for i := 0; i < int(count); i++ { - wc := *(*C.wchar_t)(unsafe.Pointer(uintptr(unsafe.Pointer(s)) + uintptr(i)*C.sizeof_wchar_t)) - sz := C.wctomb(&buf[0], wc) - for j := 0; j < int(sz); j++ { - sbuf = append(sbuf, byte(buf[j])) - } - } - return string(sbuf) - } else { - cs := (*C.char)(s) - return C.GoStringN(cs, count) - } -} - -func (el EditLine) Stdin() *os.File { - return editors[el].inf -} - -func (el EditLine) Stdout() *os.File { - return editors[el].outf -} - -func (el EditLine) Stderr() *os.File { - return editors[el].errf -} - -func (el EditLine) SetCompleter(gen CompletionGenerator) { - editors[el].completer = gen -} - -func (el EditLine) SetLeftPrompt(prompt string) { - st := &editors[el] - if st.cPromptLeft != nil { - C.free(unsafe.Pointer(st.cPromptLeft)) - } - st.cPromptLeft = C.CString(prompt) -} - -func (el EditLine) SetRightPrompt(prompt string) { - st := &editors[el] - if st.cPromptRight != nil { - C.free(unsafe.Pointer(st.cPromptRight)) - } - st.cPromptRight = C.CString(prompt) -} - -func (el EditLine) GetLineInfo() (string, int) { - st := &editors[el] - var cursor int - var count C.int - var buf unsafe.Pointer - if st.wideChars != 0 { - li := C.el_wline(st.el) - buf = unsafe.Pointer(li.buffer) - count = C.int(uintptr(unsafe.Pointer(li.lastchar))-uintptr(buf)) / C.sizeof_wchar_t - cursor = int(uintptr(unsafe.Pointer(li.cursor))-uintptr(buf)) / C.sizeof_wchar_t - } else { - li := C.el_line(st.el) - buf = unsafe.Pointer(li.buffer) - count = C.int(uintptr(unsafe.Pointer(li.lastchar)) - uintptr(buf)) - cursor = int(uintptr(unsafe.Pointer(li.cursor)) - uintptr(buf)) - } - return convertRunes(st.wideChars != 0, buf, count), cursor -} - -//export go_libedit_getcompletions -func go_libedit_getcompletions(cI C.int, cWord *C.char) **C.char { - if int(cI) < 0 || int(cI) >= len(editors) { - return nil - } - st := &editors[int(cI)] - if st.completer == nil { - return nil - } - - word := C.GoString(cWord) - matches := st.completer.GetCompletions(word) - if len(matches) == 0 { - return nil - } - - array := (**C.char)(C.malloc(C.size_t(C.sizeof_pchar * (len(matches) + 1)))) - for i, m := range matches { - C.go_libedit_set_string_array(array, C.int(i), C.CString(m)) - } - C.go_libedit_set_string_array(array, C.int(len(matches)), nil) - return array -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-chared.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-chared.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-chared.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-chartype.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-chartype.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-chartype.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-common.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-common.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-common.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-el.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-el.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-el.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-eln.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-eln.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-eln.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-emacs.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-emacs.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-emacs.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-filecomplete.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-filecomplete.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-filecomplete.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-hist.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-hist.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-hist.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-history.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-history.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-history.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-historyn.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-historyn.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-historyn.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-keymacro.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-keymacro.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-keymacro.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-map.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-map.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-map.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-parse.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-parse.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-parse.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-prompt.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-prompt.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-prompt.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-read.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-read.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-read.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-readline.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-readline.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-readline.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-refresh.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-refresh.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-refresh.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-search.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-search.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-search.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-sig.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-sig.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-sig.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-strlcat.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-strlcat.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-strlcat.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-strlcpy.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-strlcpy.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-strlcpy.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-terminal.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-terminal.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-terminal.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tokenizer.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tokenizer.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tokenizer.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tokenizern.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tokenizern.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tokenizern.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tty.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tty.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-tty.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-unvis.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-unvis.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-unvis.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-vi.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-vi.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-vi.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-vis.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-vis.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-vis.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-wcsdup.c b/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-wcsdup.c deleted file mode 100644 index dd53569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/shim/libedit-wcsdup.c +++ /dev/null @@ -1 +0,0 @@ -// Nothing to see here. diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chared.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chared.c deleted file mode 100644 index 9d46ba6..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chared.c +++ /dev/null @@ -1,753 +0,0 @@ -/* $NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * chared.c: Character editor utilities - */ -#include -#include -#include - -#include "el.h" -#include "common.h" -#include "fcns.h" - -/* value to leave unused in line buffer */ -#define EL_LEAVE 2 - -/* cv_undo(): - * Handle state for the vi undo command - */ -libedit_private void -cv_undo(EditLine *el) -{ - c_undo_t *vu = &el->el_chared.c_undo; - c_redo_t *r = &el->el_chared.c_redo; - size_t size; - - /* Save entire line for undo */ - size = (size_t)(el->el_line.lastchar - el->el_line.buffer); - vu->len = (ssize_t)size; - vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer); - (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf)); - - /* save command info for redo */ - r->count = el->el_state.doingarg ? el->el_state.argument : 0; - r->action = el->el_chared.c_vcmd.action; - r->pos = r->buf; - r->cmd = el->el_state.thiscmd; - r->ch = el->el_state.thisch; -} - -/* cv_yank(): - * Save yank/delete data for paste - */ -libedit_private void -cv_yank(EditLine *el, const wchar_t *ptr, int size) -{ - c_kill_t *k = &el->el_chared.c_kill; - - (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf)); - k->last = k->buf + size; -} - - -/* c_insert(): - * Insert num characters - */ -libedit_private void -c_insert(EditLine *el, int num) -{ - wchar_t *cp; - - if (el->el_line.lastchar + num >= el->el_line.limit) { - if (!ch_enlargebufs(el, (size_t)num)) - return; /* can't go past end of buffer */ - } - - if (el->el_line.cursor < el->el_line.lastchar) { - /* if I must move chars */ - for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--) - cp[num] = *cp; - } - el->el_line.lastchar += num; -} - - -/* c_delafter(): - * Delete num characters after the cursor - */ -libedit_private void -c_delafter(EditLine *el, int num) -{ - - if (el->el_line.cursor + num > el->el_line.lastchar) - num = (int)(el->el_line.lastchar - el->el_line.cursor); - - if (el->el_map.current != el->el_map.emacs) { - cv_undo(el); - cv_yank(el, el->el_line.cursor, num); - } - - if (num > 0) { - wchar_t *cp; - - for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) - *cp = cp[num]; - - el->el_line.lastchar -= num; - } -} - - -/* c_delafter1(): - * Delete the character after the cursor, do not yank - */ -libedit_private void -c_delafter1(EditLine *el) -{ - wchar_t *cp; - - for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) - *cp = cp[1]; - - el->el_line.lastchar--; -} - - -/* c_delbefore(): - * Delete num characters before the cursor - */ -libedit_private void -c_delbefore(EditLine *el, int num) -{ - - if (el->el_line.cursor - num < el->el_line.buffer) - num = (int)(el->el_line.cursor - el->el_line.buffer); - - if (el->el_map.current != el->el_map.emacs) { - cv_undo(el); - cv_yank(el, el->el_line.cursor - num, num); - } - - if (num > 0) { - wchar_t *cp; - - for (cp = el->el_line.cursor - num; - cp <= el->el_line.lastchar; - cp++) - *cp = cp[num]; - - el->el_line.lastchar -= num; - } -} - - -/* c_delbefore1(): - * Delete the character before the cursor, do not yank - */ -libedit_private void -c_delbefore1(EditLine *el) -{ - wchar_t *cp; - - for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++) - *cp = cp[1]; - - el->el_line.lastchar--; -} - - -/* ce__isword(): - * Return if p is part of a word according to emacs - */ -libedit_private int -ce__isword(wint_t p) -{ - return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL; -} - - -/* cv__isword(): - * Return if p is part of a word according to vi - */ -libedit_private int -cv__isword(wint_t p) -{ - if (iswalnum(p) || p == L'_') - return 1; - if (iswgraph(p)) - return 2; - return 0; -} - - -/* cv__isWord(): - * Return if p is part of a big word according to vi - */ -libedit_private int -cv__isWord(wint_t p) -{ - return !iswspace(p); -} - - -/* c__prev_word(): - * Find the previous word - */ -libedit_private wchar_t * -c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t)) -{ - p--; - - while (n--) { - while ((p >= low) && !(*wtest)(*p)) - p--; - while ((p >= low) && (*wtest)(*p)) - p--; - } - - /* cp now points to one character before the word */ - p++; - if (p < low) - p = low; - /* cp now points where we want it */ - return p; -} - - -/* c__next_word(): - * Find the next word - */ -libedit_private wchar_t * -c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t)) -{ - while (n--) { - while ((p < high) && !(*wtest)(*p)) - p++; - while ((p < high) && (*wtest)(*p)) - p++; - } - if (p > high) - p = high; - /* p now points where we want it */ - return p; -} - -/* cv_next_word(): - * Find the next word vi style - */ -libedit_private wchar_t * -cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n, - int (*wtest)(wint_t)) -{ - int test; - - while (n--) { - test = (*wtest)(*p); - while ((p < high) && (*wtest)(*p) == test) - p++; - /* - * vi historically deletes with cw only the word preserving the - * trailing whitespace! This is not what 'w' does.. - */ - if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT)) - while ((p < high) && iswspace(*p)) - p++; - } - - /* p now points where we want it */ - if (p > high) - return high; - else - return p; -} - - -/* cv_prev_word(): - * Find the previous word vi style - */ -libedit_private wchar_t * -cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t)) -{ - int test; - - p--; - while (n--) { - while ((p > low) && iswspace(*p)) - p--; - test = (*wtest)(*p); - while ((p >= low) && (*wtest)(*p) == test) - p--; - } - p++; - - /* p now points where we want it */ - if (p < low) - return low; - else - return p; -} - - -/* cv_delfini(): - * Finish vi delete action - */ -libedit_private void -cv_delfini(EditLine *el) -{ - int size; - int action = el->el_chared.c_vcmd.action; - - if (action & INSERT) - el->el_map.current = el->el_map.key; - - if (el->el_chared.c_vcmd.pos == 0) - /* sanity */ - return; - - size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos); - if (size == 0) - size = 1; - el->el_line.cursor = el->el_chared.c_vcmd.pos; - if (action & YANK) { - if (size > 0) - cv_yank(el, el->el_line.cursor, size); - else - cv_yank(el, el->el_line.cursor + size, -size); - } else { - if (size > 0) { - c_delafter(el, size); - re_refresh_cursor(el); - } else { - c_delbefore(el, -size); - el->el_line.cursor += size; - } - } - el->el_chared.c_vcmd.action = NOP; -} - - -/* cv__endword(): - * Go to the end of this word according to vi - */ -libedit_private wchar_t * -cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t)) -{ - int test; - - p++; - - while (n--) { - while ((p < high) && iswspace(*p)) - p++; - - test = (*wtest)(*p); - while ((p < high) && (*wtest)(*p) == test) - p++; - } - p--; - return p; -} - -/* ch_init(): - * Initialize the character editor - */ -libedit_private int -ch_init(EditLine *el) -{ - el->el_line.buffer = el_malloc(EL_BUFSIZ * - sizeof(*el->el_line.buffer)); - if (el->el_line.buffer == NULL) - return -1; - - (void) memset(el->el_line.buffer, 0, EL_BUFSIZ * - sizeof(*el->el_line.buffer)); - el->el_line.cursor = el->el_line.buffer; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE]; - - el->el_chared.c_undo.buf = el_malloc(EL_BUFSIZ * - sizeof(*el->el_chared.c_undo.buf)); - if (el->el_chared.c_undo.buf == NULL) - return -1; - (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ * - sizeof(*el->el_chared.c_undo.buf)); - el->el_chared.c_undo.len = -1; - el->el_chared.c_undo.cursor = 0; - el->el_chared.c_redo.buf = el_malloc(EL_BUFSIZ * - sizeof(*el->el_chared.c_redo.buf)); - if (el->el_chared.c_redo.buf == NULL) - return -1; - el->el_chared.c_redo.pos = el->el_chared.c_redo.buf; - el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ; - el->el_chared.c_redo.cmd = ED_UNASSIGNED; - - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_vcmd.pos = el->el_line.buffer; - - el->el_chared.c_kill.buf = el_malloc(EL_BUFSIZ * - sizeof(*el->el_chared.c_kill.buf)); - if (el->el_chared.c_kill.buf == NULL) - return -1; - (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ * - sizeof(*el->el_chared.c_kill.buf)); - el->el_chared.c_kill.mark = el->el_line.buffer; - el->el_chared.c_kill.last = el->el_chared.c_kill.buf; - el->el_chared.c_resizefun = NULL; - el->el_chared.c_resizearg = NULL; - el->el_chared.c_aliasfun = NULL; - el->el_chared.c_aliasarg = NULL; - - el->el_map.current = el->el_map.key; - - el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ - el->el_state.doingarg = 0; - el->el_state.metanext = 0; - el->el_state.argument = 1; - el->el_state.lastcmd = ED_UNASSIGNED; - - return 0; -} - -/* ch_reset(): - * Reset the character editor - */ -libedit_private void -ch_reset(EditLine *el) -{ - el->el_line.cursor = el->el_line.buffer; - el->el_line.lastchar = el->el_line.buffer; - - el->el_chared.c_undo.len = -1; - el->el_chared.c_undo.cursor = 0; - - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_vcmd.pos = el->el_line.buffer; - - el->el_chared.c_kill.mark = el->el_line.buffer; - - el->el_map.current = el->el_map.key; - - el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ - el->el_state.doingarg = 0; - el->el_state.metanext = 0; - el->el_state.argument = 1; - el->el_state.lastcmd = ED_UNASSIGNED; - - el->el_history.eventno = 0; -} - -/* ch_enlargebufs(): - * Enlarge line buffer to be able to hold twice as much characters. - * Returns 1 if successful, 0 if not. - */ -libedit_private int -ch_enlargebufs(EditLine *el, size_t addlen) -{ - size_t sz, newsz; - wchar_t *newbuffer, *oldbuf, *oldkbuf; - - sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE); - newsz = sz * 2; - /* - * If newly required length is longer than current buffer, we need - * to make the buffer big enough to hold both old and new stuff. - */ - if (addlen > sz) { - while(newsz - sz < addlen) - newsz *= 2; - } - - /* - * Reallocate line buffer. - */ - newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer)); - if (!newbuffer) - return 0; - - /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); - - oldbuf = el->el_line.buffer; - - el->el_line.buffer = newbuffer; - el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf); - el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf); - /* don't set new size until all buffers are enlarged */ - el->el_line.limit = &newbuffer[sz - EL_LEAVE]; - - /* - * Reallocate kill buffer. - */ - newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz * - sizeof(*newbuffer)); - if (!newbuffer) - return 0; - - /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); - - oldkbuf = el->el_chared.c_kill.buf; - - el->el_chared.c_kill.buf = newbuffer; - el->el_chared.c_kill.last = newbuffer + - (el->el_chared.c_kill.last - oldkbuf); - el->el_chared.c_kill.mark = el->el_line.buffer + - (el->el_chared.c_kill.mark - oldbuf); - - /* - * Reallocate undo buffer. - */ - newbuffer = el_realloc(el->el_chared.c_undo.buf, - newsz * sizeof(*newbuffer)); - if (!newbuffer) - return 0; - - /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); - el->el_chared.c_undo.buf = newbuffer; - - newbuffer = el_realloc(el->el_chared.c_redo.buf, - newsz * sizeof(*newbuffer)); - if (!newbuffer) - return 0; - el->el_chared.c_redo.pos = newbuffer + - (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf); - el->el_chared.c_redo.lim = newbuffer + - (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf); - el->el_chared.c_redo.buf = newbuffer; - - if (!hist_enlargebuf(el, sz, newsz)) - return 0; - - /* Safe to set enlarged buffer size */ - el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE]; - if (el->el_chared.c_resizefun) - (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg); - return 1; -} - -/* ch_end(): - * Free the data structures used by the editor - */ -libedit_private void -ch_end(EditLine *el) -{ - el_free(el->el_line.buffer); - el->el_line.buffer = NULL; - el->el_line.limit = NULL; - el_free(el->el_chared.c_undo.buf); - el->el_chared.c_undo.buf = NULL; - el_free(el->el_chared.c_redo.buf); - el->el_chared.c_redo.buf = NULL; - el->el_chared.c_redo.pos = NULL; - el->el_chared.c_redo.lim = NULL; - el->el_chared.c_redo.cmd = ED_UNASSIGNED; - el_free(el->el_chared.c_kill.buf); - el->el_chared.c_kill.buf = NULL; - ch_reset(el); -} - - -/* el_insertstr(): - * Insert string at cursorI - */ -int -el_winsertstr(EditLine *el, const wchar_t *s) -{ - size_t len; - - if (s == NULL || (len = wcslen(s)) == 0) - return -1; - if (el->el_line.lastchar + len >= el->el_line.limit) { - if (!ch_enlargebufs(el, len)) - return -1; - } - - c_insert(el, (int)len); - while (*s) - *el->el_line.cursor++ = *s++; - return 0; -} - - -/* el_deletestr(): - * Delete num characters before the cursor - */ -void -el_deletestr(EditLine *el, int n) -{ - if (n <= 0) - return; - - if (el->el_line.cursor < &el->el_line.buffer[n]) - return; - - c_delbefore(el, n); /* delete before dot */ - el->el_line.cursor -= n; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; -} - -/* el_cursor(): - * Move the cursor to the left or the right of the current position - */ -int -el_cursor(EditLine *el, int n) -{ - if (n == 0) - goto out; - - el->el_line.cursor += n; - - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; -out: - return (int)(el->el_line.cursor - el->el_line.buffer); -} - -/* c_gets(): - * Get a string - */ -libedit_private int -c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt) -{ - ssize_t len; - wchar_t *cp = el->el_line.buffer, ch; - - if (prompt) { - len = (ssize_t)wcslen(prompt); - (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp)); - cp += len; - } - len = 0; - - for (;;) { - el->el_line.cursor = cp; - *cp = ' '; - el->el_line.lastchar = cp + 1; - re_refresh(el); - - if (el_wgetc(el, &ch) != 1) { - ed_end_of_file(el, 0); - len = -1; - break; - } - - switch (ch) { - - case L'\b': /* Delete and backspace */ - case 0177: - if (len == 0) { - len = -1; - break; - } - len--; - cp--; - continue; - - case 0033: /* ESC */ - case L'\r': /* Newline */ - case L'\n': - buf[len] = ch; - break; - - default: - if (len >= (ssize_t)(EL_BUFSIZ - 16)) - terminal_beep(el); - else { - buf[len++] = ch; - *cp++ = ch; - } - continue; - } - break; - } - - el->el_line.buffer[0] = '\0'; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - return (int)len; -} - - -/* c_hpos(): - * Return the current horizontal position of the cursor - */ -libedit_private int -c_hpos(EditLine *el) -{ - wchar_t *ptr; - - /* - * Find how many characters till the beginning of this line. - */ - if (el->el_line.cursor == el->el_line.buffer) - return 0; - else { - for (ptr = el->el_line.cursor - 1; - ptr >= el->el_line.buffer && *ptr != '\n'; - ptr--) - continue; - return (int)(el->el_line.cursor - ptr - 1); - } -} - -libedit_private int -ch_resizefun(EditLine *el, el_zfunc_t f, void *a) -{ - el->el_chared.c_resizefun = f; - el->el_chared.c_resizearg = a; - return 0; -} - -libedit_private int -ch_aliasfun(EditLine *el, el_afunc_t f, void *a) -{ - el->el_chared.c_aliasfun = f; - el->el_chared.c_aliasarg = a; - return 0; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chared.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chared.h deleted file mode 100644 index 39f7d51..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chared.h +++ /dev/null @@ -1,155 +0,0 @@ -/* $NetBSD: chared.h,v 1.30 2016/05/22 19:44:26 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)chared.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.chared.h: Character editor interface - */ -#ifndef _h_el_chared -#define _h_el_chared - -/* - * This is an issue of basic "vi" look-and-feel. Defining VI_MOVE works - * like real vi: i.e. the transition from command<->insert modes moves - * the cursor. - * - * On the other hand we really don't want to move the cursor, because - * all the editing commands don't include the character under the cursor. - * Probably the best fix is to make all the editing commands aware of - * this fact. - */ -#define VI_MOVE - -/* - * Undo information for vi - no undo in emacs (yet) - */ -typedef struct c_undo_t { - ssize_t len; /* length of saved line */ - int cursor; /* position of saved cursor */ - wchar_t *buf; /* full saved text */ -} c_undo_t; - -/* redo for vi */ -typedef struct c_redo_t { - wchar_t *buf; /* redo insert key sequence */ - wchar_t *pos; - wchar_t *lim; - el_action_t cmd; /* command to redo */ - wchar_t ch; /* char that invoked it */ - int count; - int action; /* from cv_action() */ -} c_redo_t; - -/* - * Current action information for vi - */ -typedef struct c_vcmd_t { - int action; - wchar_t *pos; -} c_vcmd_t; - -/* - * Kill buffer for emacs - */ -typedef struct c_kill_t { - wchar_t *buf; - wchar_t *last; - wchar_t *mark; -} c_kill_t; - -typedef void (*el_zfunc_t)(EditLine *, void *); -typedef const char *(*el_afunc_t)(void *, const char *); - -/* - * Note that we use both data structures because the user can bind - * commands from both editors! - */ -typedef struct el_chared_t { - c_undo_t c_undo; - c_kill_t c_kill; - c_redo_t c_redo; - c_vcmd_t c_vcmd; - el_zfunc_t c_resizefun; - el_afunc_t c_aliasfun; - void * c_resizearg; - void * c_aliasarg; -} el_chared_t; - - -#define STRQQ "\"\"" - -#define isglob(a) (strchr("*[]?", (a)) != NULL) - -#define NOP 0x00 -#define DELETE 0x01 -#define INSERT 0x02 -#define YANK 0x04 - -#define CHAR_FWD (+1) -#define CHAR_BACK (-1) - -#define MODE_INSERT 0 -#define MODE_REPLACE 1 -#define MODE_REPLACE_1 2 - - -libedit_private int cv__isword(wint_t); -libedit_private int cv__isWord(wint_t); -libedit_private void cv_delfini(EditLine *); -libedit_private wchar_t *cv__endword(wchar_t *, wchar_t *, int, int (*)(wint_t)); -libedit_private int ce__isword(wint_t); -libedit_private void cv_undo(EditLine *); -libedit_private void cv_yank(EditLine *, const wchar_t *, int); -libedit_private wchar_t *cv_next_word(EditLine*, wchar_t *, wchar_t *, int, - int (*)(wint_t)); -libedit_private wchar_t *cv_prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t)); -libedit_private wchar_t *c__next_word(wchar_t *, wchar_t *, int, int (*)(wint_t)); -libedit_private wchar_t *c__prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t)); -libedit_private void c_insert(EditLine *, int); -libedit_private void c_delbefore(EditLine *, int); -libedit_private void c_delbefore1(EditLine *); -libedit_private void c_delafter(EditLine *, int); -libedit_private void c_delafter1(EditLine *); -libedit_private int c_gets(EditLine *, wchar_t *, const wchar_t *); -libedit_private int c_hpos(EditLine *); - -libedit_private int ch_init(EditLine *); -libedit_private void ch_reset(EditLine *); -libedit_private int ch_resizefun(EditLine *, el_zfunc_t, void *); -libedit_private int ch_aliasfun(EditLine *, el_afunc_t, void *); -libedit_private int ch_enlargebufs(EditLine *, size_t); -libedit_private void ch_end(EditLine *); - -#endif /* _h_el_chared */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chartype.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chartype.c deleted file mode 100644 index 9288e6b..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chartype.c +++ /dev/null @@ -1,341 +0,0 @@ -/* $NetBSD: chartype.c,v 1.31 2017/01/09 02:54:18 christos Exp $ */ - -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* - * chartype.c: character classification and meta information - */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: chartype.c,v 1.31 2017/01/09 02:54:18 christos Exp $"); -#endif /* not lint && not SCCSID */ - -#include -#include -#include - -#include "el.h" - -#define CT_BUFSIZ ((size_t)1024) - -static int ct_conv_cbuff_resize(ct_buffer_t *, size_t); -static int ct_conv_wbuff_resize(ct_buffer_t *, size_t); - -static int -ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize) -{ - void *p; - - if (csize <= conv->csize) - return 0; - - conv->csize = csize; - - p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff)); - if (p == NULL) { - conv->csize = 0; - el_free(conv->cbuff); - conv->cbuff = NULL; - return -1; - } - conv->cbuff = p; - return 0; -} - -static int -ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize) -{ - void *p; - - if (wsize <= conv->wsize) - return 0; - - conv->wsize = wsize; - - p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff)); - if (p == NULL) { - conv->wsize = 0; - el_free(conv->wbuff); - conv->wbuff = NULL; - return -1; - } - conv->wbuff = p; - return 0; -} - - -char * -ct_encode_string(const wchar_t *s, ct_buffer_t *conv) -{ - char *dst; - ssize_t used; - - if (!s) - return NULL; - - dst = conv->cbuff; - for (;;) { - used = (ssize_t)(dst - conv->cbuff); - if ((conv->csize - (size_t)used) < 5) { - if (ct_conv_cbuff_resize(conv, - conv->csize + CT_BUFSIZ) == -1) - return NULL; - dst = conv->cbuff + used; - } - if (!*s) - break; - used = ct_encode_char(dst, (size_t)5, *s); - if (used == -1) /* failed to encode, need more buffer space */ - abort(); - ++s; - dst += used; - } - *dst = '\0'; - return conv->cbuff; -} - -wchar_t * -ct_decode_string(const char *s, ct_buffer_t *conv) -{ - size_t len; - - if (!s) - return NULL; - - len = mbstowcs(NULL, s, (size_t)0); - if (len == (size_t)-1) - return NULL; - - if (conv->wsize < ++len) - if (ct_conv_wbuff_resize(conv, len + CT_BUFSIZ) == -1) - return NULL; - - mbstowcs(conv->wbuff, s, conv->wsize); - return conv->wbuff; -} - - -libedit_private wchar_t ** -ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv) -{ - size_t bufspace; - int i; - wchar_t *p; - wchar_t **wargv; - ssize_t bytes; - - /* Make sure we have enough space in the conversion buffer to store all - * the argv strings. */ - for (i = 0, bufspace = 0; i < argc; ++i) - bufspace += argv[i] ? strlen(argv[i]) + 1 : 0; - if (conv->wsize < ++bufspace) - if (ct_conv_wbuff_resize(conv, bufspace + CT_BUFSIZ) == -1) - return NULL; - - wargv = el_malloc((size_t)(argc + 1) * sizeof(*wargv)); - - for (i = 0, p = conv->wbuff; i < argc; ++i) { - if (!argv[i]) { /* don't pass null pointers to mbstowcs */ - wargv[i] = NULL; - continue; - } else { - wargv[i] = p; - bytes = (ssize_t)mbstowcs(p, argv[i], bufspace); - } - if (bytes == -1) { - el_free(wargv); - return NULL; - } else - bytes++; /* include '\0' in the count */ - bufspace -= (size_t)bytes; - p += bytes; - } - wargv[i] = NULL; - - return wargv; -} - - -libedit_private size_t -ct_enc_width(wchar_t c) -{ - /* UTF-8 encoding specific values */ - if (c < 0x80) - return 1; - else if (c < 0x0800) - return 2; - else if (c < 0x10000) - return 3; - else if (c < 0x110000) - return 4; - else - return 0; /* not a valid codepoint */ -} - -libedit_private ssize_t -ct_encode_char(char *dst, size_t len, wchar_t c) -{ - ssize_t l = 0; - if (len < ct_enc_width(c)) - return -1; - l = wctomb(dst, c); - - if (l < 0) { - wctomb(NULL, L'\0'); - l = 0; - } - return l; -} - -libedit_private const wchar_t * -ct_visual_string(const wchar_t *s, ct_buffer_t *conv) -{ - wchar_t *dst; - ssize_t used; - - if (!s) - return NULL; - - if (ct_conv_wbuff_resize(conv, CT_BUFSIZ) == -1) - return NULL; - - used = 0; - dst = conv->wbuff; - while (*s) { - used = ct_visual_char(dst, - conv->wsize - (size_t)(dst - conv->wbuff), *s); - if (used != -1) { - ++s; - dst += used; - continue; - } - - /* failed to encode, need more buffer space */ - used = dst - conv->wbuff; - if (ct_conv_wbuff_resize(conv, conv->wsize + CT_BUFSIZ) == -1) - return NULL; - dst = conv->wbuff + used; - } - - if (dst >= (conv->wbuff + conv->wsize)) { /* sigh */ - used = dst - conv->wbuff; - if (ct_conv_wbuff_resize(conv, conv->wsize + CT_BUFSIZ) == -1) - return NULL; - dst = conv->wbuff + used; - } - - *dst = L'\0'; - return conv->wbuff; -} - - - -libedit_private int -ct_visual_width(wchar_t c) -{ - int t = ct_chr_class(c); - switch (t) { - case CHTYPE_ASCIICTL: - return 2; /* ^@ ^? etc. */ - case CHTYPE_TAB: - return 1; /* Hmm, this really need to be handled outside! */ - case CHTYPE_NL: - return 0; /* Should this be 1 instead? */ - case CHTYPE_PRINT: - return wcwidth(c); - case CHTYPE_NONPRINT: - if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */ - return 8; /* \U+12345 */ - else - return 7; /* \U+1234 */ - default: - return 0; /* should not happen */ - } -} - - -libedit_private ssize_t -ct_visual_char(wchar_t *dst, size_t len, wchar_t c) -{ - int t = ct_chr_class(c); - switch (t) { - case CHTYPE_TAB: - case CHTYPE_NL: - case CHTYPE_ASCIICTL: - if (len < 2) - return -1; /* insufficient space */ - *dst++ = '^'; - if (c == '\177') - *dst = '?'; /* DEL -> ^? */ - else - *dst = c | 0100; /* uncontrolify it */ - return 2; - case CHTYPE_PRINT: - if (len < 1) - return -1; /* insufficient space */ - *dst = c; - return 1; - case CHTYPE_NONPRINT: - /* we only use single-width glyphs for display, - * so this is right */ - if ((ssize_t)len < ct_visual_width(c)) - return -1; /* insufficient space */ - *dst++ = '\\'; - *dst++ = 'U'; - *dst++ = '+'; -#define tohexdigit(v) "0123456789ABCDEF"[v] - if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */ - *dst++ = tohexdigit(((unsigned int) c >> 16) & 0xf); - *dst++ = tohexdigit(((unsigned int) c >> 12) & 0xf); - *dst++ = tohexdigit(((unsigned int) c >> 8) & 0xf); - *dst++ = tohexdigit(((unsigned int) c >> 4) & 0xf); - *dst = tohexdigit(((unsigned int) c ) & 0xf); - return c > 0xffff ? 8 : 7; - /*FALLTHROUGH*/ - /* these two should be handled outside this function */ - default: /* we should never hit the default */ - return 0; - } -} - - - - -libedit_private int -ct_chr_class(wchar_t c) -{ - if (c == '\t') - return CHTYPE_TAB; - else if (c == '\n') - return CHTYPE_NL; - else if (c < 0x100 && iswcntrl(c)) - return CHTYPE_ASCIICTL; - else if (iswprint(c)) - return CHTYPE_PRINT; - else - return CHTYPE_NONPRINT; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chartype.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chartype.h deleted file mode 100644 index 7f4b8d9..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/chartype.h +++ /dev/null @@ -1,114 +0,0 @@ -/* $NetBSD: chartype.h,v 1.34 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#ifndef _h_chartype_f -#define _h_chartype_f - -/* Ideally we should also test the value of the define to see if it - * supports non-BMP code points without requiring UTF-16, but nothing - * seems to actually advertise this properly, despite Unicode 3.1 having - * been around since 2001... */ -#if !defined(__NetBSD__) && !defined(__sun) && !(defined(__APPLE__) && defined(__MACH__)) && !defined(__OpenBSD__) && !defined(__FreeBSD__) -#ifndef __STDC_ISO_10646__ -/* In many places it is assumed that the first 127 code points are ASCII - * compatible, so ensure wchar_t indeed does ISO 10646 and not some other - * funky encoding that could break us in weird and wonderful ways. */ - #error wchar_t must store ISO 10646 characters -#endif -#endif - -/* Oh for a with char32_t and __STDC_UTF_32__ in it... - * ref: ISO/IEC DTR 19769 - */ -#if WCHAR_MAX < INT32_MAX -#warning Build environment does not support non-BMP characters -#endif - -/* - * Conversion buffer - */ -typedef struct ct_buffer_t { - char *cbuff; - size_t csize; - wchar_t *wbuff; - size_t wsize; -} ct_buffer_t; - -/* Encode a wide-character string and return the UTF-8 encoded result. */ -char *ct_encode_string(const wchar_t *, ct_buffer_t *); - -/* Decode a (multi)?byte string and return the wide-character string result. */ -wchar_t *ct_decode_string(const char *, ct_buffer_t *); - -/* Decode a (multi)?byte argv string array. - * The pointer returned must be free()d when done. */ -libedit_private wchar_t **ct_decode_argv(int, const char *[], ct_buffer_t *); - -/* Encode a character into the destination buffer, provided there is sufficient - * buffer space available. Returns the number of bytes used up (zero if the - * character cannot be encoded, -1 if there was not enough space available). */ -libedit_private ssize_t ct_encode_char(char *, size_t, wchar_t); -libedit_private size_t ct_enc_width(wchar_t); - -/* The maximum buffer size to hold the most unwieldy visual representation, - * in this case \U+nnnnn. */ -#define VISUAL_WIDTH_MAX ((size_t)8) - -/* The terminal is thought of in terms of X columns by Y lines. In the cases - * where a wide character takes up more than one column, the adjacent - * occupied column entries will contain this faux character. */ -#define MB_FILL_CHAR ((wchar_t)-1) - -/* Visual width of character c, taking into account ^? , \0177 and \U+nnnnn - * style visual expansions. */ -libedit_private int ct_visual_width(wchar_t); - -/* Turn the given character into the appropriate visual format, matching - * the width given by ct_visual_width(). Returns the number of characters used - * up, or -1 if insufficient space. Buffer length is in count of wchar_t's. */ -libedit_private ssize_t ct_visual_char(wchar_t *, size_t, wchar_t); - -/* Convert the given string into visual format, using the ct_visual_char() - * function. Uses a static buffer, so not threadsafe. */ -libedit_private const wchar_t *ct_visual_string(const wchar_t *, ct_buffer_t *); - - -/* printable character, use ct_visual_width() to find out display width */ -#define CHTYPE_PRINT ( 0) -/* control character found inside the ASCII portion of the charset */ -#define CHTYPE_ASCIICTL (-1) -/* a \t */ -#define CHTYPE_TAB (-2) -/* a \n */ -#define CHTYPE_NL (-3) -/* non-printable character */ -#define CHTYPE_NONPRINT (-4) -/* classification of character c, as one of the above defines */ -libedit_private int ct_chr_class(wchar_t c); - -#endif /* _chartype_f */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/common.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/common.c deleted file mode 100644 index 2708605..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/common.c +++ /dev/null @@ -1,835 +0,0 @@ -/* $NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * common.c: Common Editor functions - */ -#include -#include - -#include "el.h" -#include "common.h" -#include "fcns.h" -#include "parse.h" -#include "vi.h" - -/* ed_end_of_file(): - * Indicate end of file - * [^D] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - re_goto_bottom(el); - *el->el_line.lastchar = '\0'; - return CC_EOF; -} - - -/* ed_insert(): - * Add character to the line - * Insert a character [bound to all insert keys] - */ -libedit_private el_action_t -ed_insert(EditLine *el, wint_t c) -{ - int count = el->el_state.argument; - - if (c == '\0') - return CC_ERROR; - - if (el->el_line.lastchar + el->el_state.argument >= - el->el_line.limit) { - /* end of buffer space, try to allocate more */ - if (!ch_enlargebufs(el, (size_t) count)) - return CC_ERROR; /* error allocating more */ - } - - if (count == 1) { - if (el->el_state.inputmode == MODE_INSERT - || el->el_line.cursor >= el->el_line.lastchar) - c_insert(el, 1); - - *el->el_line.cursor++ = c; - re_fastaddc(el); /* fast refresh for one char. */ - } else { - if (el->el_state.inputmode != MODE_REPLACE_1) - c_insert(el, el->el_state.argument); - - while (count-- && el->el_line.cursor < el->el_line.lastchar) - *el->el_line.cursor++ = c; - re_refresh(el); - } - - if (el->el_state.inputmode == MODE_REPLACE_1) - return vi_command_mode(el, 0); - - return CC_NORM; -} - - -/* ed_delete_prev_word(): - * Delete from beginning of current word to cursor - * [M-^?] [^W] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *cp, *p, *kp; - - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - - cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, - el->el_state.argument, ce__isword); - - for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++) - *kp++ = *p; - el->el_chared.c_kill.last = kp; - - c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */ - el->el_line.cursor = cp; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; /* bounds check */ - return CC_REFRESH; -} - - -/* ed_delete_next_char(): - * Delete character under cursor - * [^D] [x] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ -#ifdef DEBUG_EDIT -#define EL el->el_line - (void) fprintf(el->el_errfile, - "\nD(b: %p(%ls) c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n", - EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, - EL.lastchar, EL.limit, EL.limit); -#endif - if (el->el_line.cursor == el->el_line.lastchar) { - /* if I'm at the end */ - if (el->el_map.type == MAP_VI) { - if (el->el_line.cursor == el->el_line.buffer) { - /* if I'm also at the beginning */ -#ifdef KSHVI - return CC_ERROR; -#else - /* then do an EOF */ - terminal_writec(el, c); - return CC_EOF; -#endif - } else { -#ifdef KSHVI - el->el_line.cursor--; -#else - return CC_ERROR; -#endif - } - } else - return CC_ERROR; - } - c_delafter(el, el->el_state.argument); /* delete after dot */ - if (el->el_map.type == MAP_VI && - el->el_line.cursor >= el->el_line.lastchar && - el->el_line.cursor > el->el_line.buffer) - /* bounds check */ - el->el_line.cursor = el->el_line.lastchar - 1; - return CC_REFRESH; -} - - -/* ed_kill_line(): - * Cut to the end of line - * [^K] [^K] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *kp, *cp; - - cp = el->el_line.cursor; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.lastchar) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - /* zap! -- delete to end */ - el->el_line.lastchar = el->el_line.cursor; - return CC_REFRESH; -} - - -/* ed_move_to_end(): - * Move cursor to the end of line - * [^E] [^E] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_line.cursor = el->el_line.lastchar; - if (el->el_map.type == MAP_VI) { - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } -#ifdef VI_MOVE - el->el_line.cursor--; -#endif - } - return CC_CURSOR; -} - - -/* ed_move_to_beg(): - * Move cursor to the beginning of line - * [^A] [^A] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_line.cursor = el->el_line.buffer; - - if (el->el_map.type == MAP_VI) { - /* We want FIRST non space character */ - while (iswspace(*el->el_line.cursor)) - el->el_line.cursor++; - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - } - return CC_CURSOR; -} - - -/* ed_transpose_chars(): - * Exchange the character to the left of the cursor with the one under it - * [^T] [^T] - */ -libedit_private el_action_t -ed_transpose_chars(EditLine *el, wint_t c) -{ - - if (el->el_line.cursor < el->el_line.lastchar) { - if (el->el_line.lastchar <= &el->el_line.buffer[1]) - return CC_ERROR; - else - el->el_line.cursor++; - } - if (el->el_line.cursor > &el->el_line.buffer[1]) { - /* must have at least two chars entered */ - c = el->el_line.cursor[-2]; - el->el_line.cursor[-2] = el->el_line.cursor[-1]; - el->el_line.cursor[-1] = c; - return CC_REFRESH; - } else - return CC_ERROR; -} - - -/* ed_next_char(): - * Move to the right one character - * [^F] [^F] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_next_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *lim = el->el_line.lastchar; - - if (el->el_line.cursor >= lim || - (el->el_line.cursor == lim - 1 && - el->el_map.type == MAP_VI && - el->el_chared.c_vcmd.action == NOP)) - return CC_ERROR; - - el->el_line.cursor += el->el_state.argument; - if (el->el_line.cursor > lim) - el->el_line.cursor = lim; - - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* ed_prev_word(): - * Move to the beginning of the current word - * [M-b] [b] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - - el->el_line.cursor = c__prev_word(el->el_line.cursor, - el->el_line.buffer, - el->el_state.argument, - ce__isword); - - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* ed_prev_char(): - * Move to the left one character - * [^B] [^B] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor > el->el_line.buffer) { - el->el_line.cursor -= el->el_state.argument; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; - - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; - } else - return CC_ERROR; -} - - -/* ed_quoted_insert(): - * Add the next character typed verbatim - * [^V] [^V] - */ -libedit_private el_action_t -ed_quoted_insert(EditLine *el, wint_t c) -{ - int num; - - tty_quotemode(el); - num = el_wgetc(el, &c); - tty_noquotemode(el); - if (num == 1) - return ed_insert(el, c); - else - return ed_end_of_file(el, 0); -} - - -/* ed_digit(): - * Adds to argument or enters a digit - */ -libedit_private el_action_t -ed_digit(EditLine *el, wint_t c) -{ - - if (!iswdigit(c)) - return CC_ERROR; - - if (el->el_state.doingarg) { - /* if doing an arg, add this in... */ - if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT) - el->el_state.argument = c - '0'; - else { - if (el->el_state.argument > 1000000) - return CC_ERROR; - el->el_state.argument = - (el->el_state.argument * 10) + (c - '0'); - } - return CC_ARGHACK; - } - - return ed_insert(el, c); -} - - -/* ed_argument_digit(): - * Digit that starts argument - * For ESC-n - */ -libedit_private el_action_t -ed_argument_digit(EditLine *el, wint_t c) -{ - - if (!iswdigit(c)) - return CC_ERROR; - - if (el->el_state.doingarg) { - if (el->el_state.argument > 1000000) - return CC_ERROR; - el->el_state.argument = (el->el_state.argument * 10) + - (c - '0'); - } else { /* else starting an argument */ - el->el_state.argument = c - '0'; - el->el_state.doingarg = 1; - } - return CC_ARGHACK; -} - - -/* ed_unassigned(): - * Indicates unbound character - * Bound to keys that are not assigned - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_unassigned(EditLine *el __attribute__((__unused__)), - wint_t c __attribute__((__unused__))) -{ - - return CC_ERROR; -} - - -/* ed_ignore(): - * Input characters that have no effect - * [^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_ignore(EditLine *el __attribute__((__unused__)), - wint_t c __attribute__((__unused__))) -{ - - return CC_NORM; -} - - -/* ed_newline(): - * Execute command - * [^J] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_newline(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - re_goto_bottom(el); - *el->el_line.lastchar++ = '\n'; - *el->el_line.lastchar = '\0'; - return CC_NEWLINE; -} - - -/* ed_delete_prev_char(): - * Delete the character to the left of the cursor - * [^?] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor <= el->el_line.buffer) - return CC_ERROR; - - c_delbefore(el, el->el_state.argument); - el->el_line.cursor -= el->el_state.argument; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; - return CC_REFRESH; -} - - -/* ed_clear_screen(): - * Clear screen leaving current line at the top - * [^L] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - terminal_clear_screen(el); /* clear the whole real screen */ - re_clear_display(el); /* reset everything */ - return CC_REFRESH; -} - - -/* ed_redisplay(): - * Redisplay everything - * ^R - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_redisplay(EditLine *el __attribute__((__unused__)), - wint_t c __attribute__((__unused__))) -{ - - return CC_REDISPLAY; -} - - -/* ed_start_over(): - * Erase current line and start from scratch - * [^G] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_start_over(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - ch_reset(el); - return CC_REFRESH; -} - - -/* ed_sequence_lead_in(): - * First character in a bound sequence - * Placeholder for external keys - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), - wint_t c __attribute__((__unused__))) -{ - - return CC_NORM; -} - - -/* ed_prev_history(): - * Move to the previous history line - * [^P] [k] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__))) -{ - char beep = 0; - int sv_event = el->el_history.eventno; - - el->el_chared.c_undo.len = -1; - *el->el_line.lastchar = '\0'; /* just in case */ - - if (el->el_history.eventno == 0) { /* save the current buffer - * away */ - (void) wcsncpy(el->el_history.buf, el->el_line.buffer, - EL_BUFSIZ); - el->el_history.last = el->el_history.buf + - (el->el_line.lastchar - el->el_line.buffer); - } - el->el_history.eventno += el->el_state.argument; - - if (hist_get(el) == CC_ERROR) { - if (el->el_map.type == MAP_VI) { - el->el_history.eventno = sv_event; - } - beep = 1; - /* el->el_history.eventno was fixed by first call */ - (void) hist_get(el); - } - if (beep) - return CC_REFRESH_BEEP; - return CC_REFRESH; -} - - -/* ed_next_history(): - * Move to the next history line - * [^N] [j] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_next_history(EditLine *el, wint_t c __attribute__((__unused__))) -{ - el_action_t beep = CC_REFRESH, rval; - - el->el_chared.c_undo.len = -1; - *el->el_line.lastchar = '\0'; /* just in case */ - - el->el_history.eventno -= el->el_state.argument; - - if (el->el_history.eventno < 0) { - el->el_history.eventno = 0; - beep = CC_REFRESH_BEEP; - } - rval = hist_get(el); - if (rval == CC_REFRESH) - return beep; - return rval; - -} - - -/* ed_search_prev_history(): - * Search previous in history for a line matching the current - * next search history [M-P] [K] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__))) -{ - const wchar_t *hp; - int h; - int found = 0; - - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_undo.len = -1; - *el->el_line.lastchar = '\0'; /* just in case */ - if (el->el_history.eventno < 0) { -#ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, - "e_prev_search_hist(): eventno < 0;\n"); -#endif - el->el_history.eventno = 0; - return CC_ERROR; - } - if (el->el_history.eventno == 0) { - (void) wcsncpy(el->el_history.buf, el->el_line.buffer, - EL_BUFSIZ); - el->el_history.last = el->el_history.buf + - (el->el_line.lastchar - el->el_line.buffer); - } - if (el->el_history.ref == NULL) - return CC_ERROR; - - hp = HIST_FIRST(el); - if (hp == NULL) - return CC_ERROR; - - c_setpat(el); /* Set search pattern !! */ - - for (h = 1; h <= el->el_history.eventno; h++) - hp = HIST_NEXT(el); - - while (hp != NULL) { -#ifdef SDEBUG - (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); -#endif - if ((wcsncmp(hp, el->el_line.buffer, (size_t) - (el->el_line.lastchar - el->el_line.buffer)) || - hp[el->el_line.lastchar - el->el_line.buffer]) && - c_hmatch(el, hp)) { - found = 1; - break; - } - h++; - hp = HIST_NEXT(el); - } - - if (!found) { -#ifdef SDEBUG - (void) fprintf(el->el_errfile, "not found\n"); -#endif - return CC_ERROR; - } - el->el_history.eventno = h; - - return hist_get(el); -} - - -/* ed_search_next_history(): - * Search next in history for a line matching the current - * [M-N] [J] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__))) -{ - const wchar_t *hp; - int h; - int found = 0; - - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_undo.len = -1; - *el->el_line.lastchar = '\0'; /* just in case */ - - if (el->el_history.eventno == 0) - return CC_ERROR; - - if (el->el_history.ref == NULL) - return CC_ERROR; - - hp = HIST_FIRST(el); - if (hp == NULL) - return CC_ERROR; - - c_setpat(el); /* Set search pattern !! */ - - for (h = 1; h < el->el_history.eventno && hp; h++) { -#ifdef SDEBUG - (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); -#endif - if ((wcsncmp(hp, el->el_line.buffer, (size_t) - (el->el_line.lastchar - el->el_line.buffer)) || - hp[el->el_line.lastchar - el->el_line.buffer]) && - c_hmatch(el, hp)) - found = h; - hp = HIST_NEXT(el); - } - - if (!found) { /* is it the current history number? */ - if (!c_hmatch(el, el->el_history.buf)) { -#ifdef SDEBUG - (void) fprintf(el->el_errfile, "not found\n"); -#endif - return CC_ERROR; - } - } - el->el_history.eventno = found; - - return hist_get(el); -} - - -/* ed_prev_line(): - * Move up one line - * Could be [k] [^p] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *ptr; - int nchars = c_hpos(el); - - /* - * Move to the line requested - */ - if (*(ptr = el->el_line.cursor) == '\n') - ptr--; - - for (; ptr >= el->el_line.buffer; ptr--) - if (*ptr == '\n' && --el->el_state.argument <= 0) - break; - - if (el->el_state.argument > 0) - return CC_ERROR; - - /* - * Move to the beginning of the line - */ - for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--) - continue; - - /* - * Move to the character requested - */ - for (ptr++; - nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; - ptr++) - continue; - - el->el_line.cursor = ptr; - return CC_CURSOR; -} - - -/* ed_next_line(): - * Move down one line - * Could be [j] [^n] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_next_line(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *ptr; - int nchars = c_hpos(el); - - /* - * Move to the line requested - */ - for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++) - if (*ptr == '\n' && --el->el_state.argument <= 0) - break; - - if (el->el_state.argument > 0) - return CC_ERROR; - - /* - * Move to the character requested - */ - for (ptr++; - nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; - ptr++) - continue; - - el->el_line.cursor = ptr; - return CC_CURSOR; -} - - -/* ed_command(): - * Editline extended command - * [M-X] [:] - */ -libedit_private el_action_t -/*ARGSUSED*/ -ed_command(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t tmpbuf[EL_BUFSIZ]; - int tmplen; - - tmplen = c_gets(el, tmpbuf, L"\n: "); - terminal__putc(el, '\n'); - - if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) - terminal_beep(el); - - el->el_map.current = el->el_map.key; - re_clear_display(el); - return CC_REFRESH; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/editline/readline.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/editline/readline.h deleted file mode 100644 index 777a4c6..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/editline/readline.h +++ /dev/null @@ -1,227 +0,0 @@ -/* $NetBSD: readline.h,v 1.41 2016/10/28 18:32:35 christos Exp $ */ - -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ -#ifndef _READLINE_H_ -#define _READLINE_H_ - -#include -#include - -/* list of readline stuff supported by editline library's readline wrapper */ - -/* typedefs */ -typedef int Function(const char *, int); -typedef void VFunction(void); -typedef void rl_vcpfunc_t(char *); -typedef char **rl_completion_func_t(const char *, int, int); -typedef char *rl_compentry_func_t(const char *, int); -typedef int rl_command_func_t(int, int); - -/* only supports length */ -typedef struct { - int length; -} HISTORY_STATE; - -typedef void *histdata_t; - -typedef struct _hist_entry { - const char *line; - histdata_t data; -} HIST_ENTRY; - -typedef struct _keymap_entry { - char type; -#define ISFUNC 0 -#define ISKMAP 1 -#define ISMACR 2 - Function *function; -} KEYMAP_ENTRY; - -#define KEYMAP_SIZE 256 - -typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE]; -typedef KEYMAP_ENTRY *Keymap; - -#define control_character_threshold 0x20 -#define control_character_bit 0x40 - -#ifndef CTRL -#include -#if !defined(__sun) && !defined(__hpux) && !defined(_AIX) -#include -#endif -#ifndef CTRL -#define CTRL(c) ((c) & 037) -#endif -#endif -#ifndef UNCTRL -#define UNCTRL(c) (((c) - 'a' + 'A')|control_character_bit) -#endif - -#define RUBOUT 0x7f -#define ABORT_CHAR CTRL('G') -#define RL_READLINE_VERSION 0x0402 -#define RL_PROMPT_START_IGNORE '\1' -#define RL_PROMPT_END_IGNORE '\2' - -/* global variables used by readline enabled applications */ -#ifdef __cplusplus -extern "C" { -#endif -extern const char *rl_library_version; -extern int rl_readline_version; -extern char *rl_readline_name; -extern FILE *rl_instream; -extern FILE *rl_outstream; -extern char *rl_line_buffer; -extern int rl_point, rl_end; -extern int history_base, history_length; -extern int max_input_history; -extern char *rl_basic_word_break_characters; -extern char *rl_completer_word_break_characters; -extern char *rl_completer_quote_characters; -extern rl_compentry_func_t *rl_completion_entry_function; -extern char *(*rl_completion_word_break_hook)(void); -extern rl_completion_func_t *rl_attempted_completion_function; -extern int rl_attempted_completion_over; -extern int rl_completion_type; -extern int rl_completion_query_items; -extern char *rl_special_prefixes; -extern int rl_completion_append_character; -extern int rl_inhibit_completion; -extern Function *rl_pre_input_hook; -extern Function *rl_startup_hook; -extern char *rl_terminal_name; -extern int rl_already_prompted; -extern char *rl_prompt; -extern int rl_done; -/* - * The following is not implemented - */ -extern int rl_catch_signals; -extern int rl_catch_sigwinch; -extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, - emacs_meta_keymap, - emacs_ctlx_keymap; -extern int rl_filename_completion_desired; -extern int rl_ignore_completion_duplicates; -extern int (*rl_getc_function)(FILE *); -extern VFunction *rl_redisplay_function; -extern VFunction *rl_completion_display_matches_hook; -extern VFunction *rl_prep_term_function; -extern VFunction *rl_deprep_term_function; -extern int readline_echoing_p; -extern int _rl_print_completions_horizontally; - -/* supported functions */ -char *readline(const char *); -int rl_initialize(void); - -void using_history(void); -int add_history(const char *); -void clear_history(void); -void stifle_history(int); -int unstifle_history(void); -int history_is_stifled(void); -int where_history(void); -HIST_ENTRY *current_history(void); -HIST_ENTRY *history_get(int); -HIST_ENTRY *remove_history(int); -HIST_ENTRY *replace_history_entry(int, const char *, histdata_t); -int history_total_bytes(void); -int history_set_pos(int); -HIST_ENTRY *previous_history(void); -HIST_ENTRY *next_history(void); -HIST_ENTRY **history_list(void); -int history_search(const char *, int); -int history_search_prefix(const char *, int); -int history_search_pos(const char *, int, int); -int read_history(const char *); -int write_history(const char *); -int history_truncate_file (const char *, int); -int history_expand(char *, char **); -char **history_tokenize(const char *); -const char *get_history_event(const char *, int *, int); -char *history_arg_extract(int, int, const char *); - -char *tilde_expand(char *); -char *filename_completion_function(const char *, int); -char *username_completion_function(const char *, int); -int rl_complete(int, int); -int rl_read_key(void); -char **completion_matches(const char *, rl_compentry_func_t *); -void rl_display_match_list(char **, int, int); - -int rl_insert(int, int); -int rl_insert_text(const char *); -void rl_reset_terminal(const char *); -int rl_bind_key(int, rl_command_func_t *); -int rl_newline(int, int); -void rl_callback_read_char(void); -void rl_callback_handler_install(const char *, rl_vcpfunc_t *); -void rl_callback_handler_remove(void); -void rl_redisplay(void); -int rl_get_previous_history(int, int); -void rl_prep_terminal(int); -void rl_deprep_terminal(void); -int rl_read_init_file(const char *); -int rl_parse_and_bind(const char *); -int rl_variable_bind(const char *, const char *); -void rl_stuff_char(int); -int rl_add_defun(const char *, rl_command_func_t *, int); -HISTORY_STATE *history_get_history_state(void); -void rl_get_screen_size(int *, int *); -void rl_set_screen_size(int, int); -char *rl_filename_completion_function (const char *, int); -int _rl_abort_internal(void); -int _rl_qsort_string_compare(char **, char **); -char **rl_completion_matches(const char *, rl_compentry_func_t *); -void rl_forced_update_display(void); -int rl_set_prompt(const char *); -int rl_on_new_line(void); - -/* - * The following are not implemented - */ -int rl_kill_text(int, int); -Keymap rl_get_keymap(void); -void rl_set_keymap(Keymap); -Keymap rl_make_bare_keymap(void); -int rl_generic_bind(int, const char *, const char *, Keymap); -int rl_bind_key_in_map(int, rl_command_func_t *, Keymap); -void rl_cleanup_after_signal(void); -void rl_free_line_state(void); -int rl_set_keyboard_input_timeout(int); - -#ifdef __cplusplus -} -#endif - -#endif /* _READLINE_H_ */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/el.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/el.c deleted file mode 100644 index 605be70..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/el.c +++ /dev/null @@ -1,664 +0,0 @@ -/* $NetBSD: el.c,v 1.92 2016/05/22 19:44:26 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; -#else -__RCSID("$NetBSD: el.c,v 1.92 2016/05/22 19:44:26 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -#ifndef MAXPATHLEN -#define MAXPATHLEN 4096 -#endif - -/* - * el.c: EditLine interface functions - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "el.h" -#include "parse.h" -#include "read.h" - -#ifndef HAVE_SECURE_GETENV -# ifdef HAVE___SECURE_GETENV -# define secure_getenv __secure_getenv -# define HAVE_SECURE_GETENV 1 -# else -# include -# ifndef HAVE_ISSETUGID -# undef issetugid -# define issetugid() (getuid() != geteuid() || getgid() != getegid()) -# endif -# endif -#endif - -#if !defined(HAVE_SECURE_GETENV) && defined(__GLIBC__) -# if __GLIBC__ >= 2 -# if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 17) -# define secure_getenv __secure_getenv -# endif -# define HAVE_SECURE_GETENV 1 -# endif -#endif - -#ifndef HAVE_SECURE_GETENV -char *secure_getenv(char const *name) -{ - if (issetugid()) - return 0; - return getenv(name); -} -#endif - -/* el_init(): - * Initialize editline and set default parameters. - */ -EditLine * -el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) -{ - return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout), - fileno(ferr)); -} - -EditLine * -el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr, - int fdin, int fdout, int fderr) -{ - EditLine *el = el_malloc(sizeof(*el)); - - if (el == NULL) - return NULL; - - memset(el, 0, sizeof(EditLine)); - - el->el_infile = fin; - el->el_outfile = fout; - el->el_errfile = ferr; - - el->el_infd = fdin; - el->el_outfd = fdout; - el->el_errfd = fderr; - - el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch)); - if (el->el_prog == NULL) { - el_free(el); - return NULL; - } - - /* - * Initialize all the modules. Order is important!!! - */ - el->el_flags = 0; - if (setlocale(LC_CTYPE, NULL) != NULL){ - if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) - el->el_flags |= CHARSET_IS_UTF8; - } - - if (terminal_init(el) == -1) { - el_free(el->el_prog); - el_free(el); - return NULL; - } - (void) keymacro_init(el); - (void) map_init(el); - if (tty_init(el) == -1) - el->el_flags |= NO_TTY; - (void) ch_init(el); - (void) search_init(el); - (void) hist_init(el); - (void) prompt_init(el); - (void) sig_init(el); - if (read_init(el) == -1) { - el_end(el); - return NULL; - } - return el; -} - - -/* el_end(): - * Clean up. - */ -void -el_end(EditLine *el) -{ - - if (el == NULL) - return; - - el_reset(el); - - terminal_end(el); - keymacro_end(el); - map_end(el); - if (!(el->el_flags & NO_TTY)) - tty_end(el); - ch_end(el); - read_end(el->el_read); - search_end(el); - hist_end(el); - prompt_end(el); - sig_end(el); - - el_free(el->el_prog); - el_free(el->el_visual.cbuff); - el_free(el->el_visual.wbuff); - el_free(el->el_scratch.cbuff); - el_free(el->el_scratch.wbuff); - el_free(el->el_lgcyconv.cbuff); - el_free(el->el_lgcyconv.wbuff); - el_free(el); -} - - -/* el_reset(): - * Reset the tty and the parser - */ -void -el_reset(EditLine *el) -{ - - tty_cookedmode(el); - ch_reset(el); /* XXX: Do we want that? */ -} - - -/* el_set(): - * set the editline parameters - */ -int -el_wset(EditLine *el, int op, ...) -{ - va_list ap; - int rv = 0; - - if (el == NULL) - return -1; - va_start(ap, op); - - switch (op) { - case EL_PROMPT: - case EL_RPROMPT: { - el_pfunc_t p = va_arg(ap, el_pfunc_t); - - rv = prompt_set(el, p, 0, op, 1); - break; - } - - case EL_RESIZE: { - el_zfunc_t p = va_arg(ap, el_zfunc_t); - void *arg = va_arg(ap, void *); - rv = ch_resizefun(el, p, arg); - break; - } - - case EL_ALIAS_TEXT: { - el_afunc_t p = va_arg(ap, el_afunc_t); - void *arg = va_arg(ap, void *); - rv = ch_aliasfun(el, p, arg); - break; - } - - case EL_PROMPT_ESC: - case EL_RPROMPT_ESC: { - el_pfunc_t p = va_arg(ap, el_pfunc_t); - int c = va_arg(ap, int); - - rv = prompt_set(el, p, (wchar_t)c, op, 1); - break; - } - - case EL_TERMINAL: - rv = terminal_set(el, va_arg(ap, char *)); - break; - - case EL_EDITOR: - rv = map_set_editor(el, va_arg(ap, wchar_t *)); - break; - - case EL_SIGNAL: - if (va_arg(ap, int)) - el->el_flags |= HANDLE_SIGNALS; - else - el->el_flags &= ~HANDLE_SIGNALS; - break; - - case EL_BIND: - case EL_TELLTC: - case EL_SETTC: - case EL_ECHOTC: - case EL_SETTY: - { - const wchar_t *argv[20]; - int i; - - for (i = 1; i < (int)__arraycount(argv); i++) - if ((argv[i] = va_arg(ap, wchar_t *)) == NULL) - break; - - switch (op) { - case EL_BIND: - argv[0] = L"bind"; - rv = map_bind(el, i, argv); - break; - - case EL_TELLTC: - argv[0] = L"telltc"; - rv = terminal_telltc(el, i, argv); - break; - - case EL_SETTC: - argv[0] = L"settc"; - rv = terminal_settc(el, i, argv); - break; - - case EL_ECHOTC: - argv[0] = L"echotc"; - rv = terminal_echotc(el, i, argv); - break; - - case EL_SETTY: - argv[0] = L"setty"; - rv = tty_stty(el, i, argv); - break; - - default: - rv = -1; - EL_ABORT((el->el_errfile, "Bad op %d\n", op)); - break; - } - break; - } - - case EL_ADDFN: - { - wchar_t *name = va_arg(ap, wchar_t *); - wchar_t *help = va_arg(ap, wchar_t *); - el_func_t func = va_arg(ap, el_func_t); - - rv = map_addfunc(el, name, help, func); - break; - } - - case EL_HIST: - { - hist_fun_t func = va_arg(ap, hist_fun_t); - void *ptr = va_arg(ap, void *); - - rv = hist_set(el, func, ptr); - if (!(el->el_flags & CHARSET_IS_UTF8)) - el->el_flags &= ~NARROW_HISTORY; - break; - } - - case EL_EDITMODE: - if (va_arg(ap, int)) - el->el_flags &= ~EDIT_DISABLED; - else - el->el_flags |= EDIT_DISABLED; - rv = 0; - break; - - case EL_GETCFN: - { - el_rfunc_t rc = va_arg(ap, el_rfunc_t); - rv = el_read_setfn(el->el_read, rc); - break; - } - - case EL_CLIENTDATA: - el->el_data = va_arg(ap, void *); - break; - - case EL_UNBUFFERED: - rv = va_arg(ap, int); - if (rv && !(el->el_flags & UNBUFFERED)) { - el->el_flags |= UNBUFFERED; - read_prepare(el); - } else if (!rv && (el->el_flags & UNBUFFERED)) { - el->el_flags &= ~UNBUFFERED; - read_finish(el); - } - rv = 0; - break; - - case EL_PREP_TERM: - rv = va_arg(ap, int); - if (rv) - (void) tty_rawmode(el); - else - (void) tty_cookedmode(el); - rv = 0; - break; - - case EL_SETFP: - { - FILE *fp; - int what; - - what = va_arg(ap, int); - fp = va_arg(ap, FILE *); - - rv = 0; - switch (what) { - case 0: - el->el_infile = fp; - el->el_infd = fileno(fp); - break; - case 1: - el->el_outfile = fp; - el->el_outfd = fileno(fp); - break; - case 2: - el->el_errfile = fp; - el->el_errfd = fileno(fp); - break; - default: - rv = -1; - break; - } - break; - } - - case EL_REFRESH: - re_clear_display(el); - re_refresh(el); - terminal__flush(el); - break; - - default: - rv = -1; - break; - } - - va_end(ap); - return rv; -} - - -/* el_get(): - * retrieve the editline parameters - */ -int -el_wget(EditLine *el, int op, ...) -{ - va_list ap; - int rv; - - if (el == NULL) - return -1; - - va_start(ap, op); - - switch (op) { - case EL_PROMPT: - case EL_RPROMPT: { - el_pfunc_t *p = va_arg(ap, el_pfunc_t *); - rv = prompt_get(el, p, 0, op); - break; - } - case EL_PROMPT_ESC: - case EL_RPROMPT_ESC: { - el_pfunc_t *p = va_arg(ap, el_pfunc_t *); - wchar_t *c = va_arg(ap, wchar_t *); - - rv = prompt_get(el, p, c, op); - break; - } - - case EL_EDITOR: - rv = map_get_editor(el, va_arg(ap, const wchar_t **)); - break; - - case EL_SIGNAL: - *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS); - rv = 0; - break; - - case EL_EDITMODE: - *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED); - rv = 0; - break; - - case EL_TERMINAL: - terminal_get(el, va_arg(ap, const char **)); - rv = 0; - break; - - case EL_GETTC: - { - static char name[] = "gettc"; - char *argv[20]; - int i; - - for (i = 1; i < (int)__arraycount(argv); i++) - if ((argv[i] = va_arg(ap, char *)) == NULL) - break; - - argv[0] = name; - rv = terminal_gettc(el, i, argv); - break; - } - - case EL_GETCFN: - *va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read); - rv = 0; - break; - - case EL_CLIENTDATA: - *va_arg(ap, void **) = el->el_data; - rv = 0; - break; - - case EL_UNBUFFERED: - *va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0; - rv = 0; - break; - - case EL_GETFP: - { - int what; - FILE **fpp; - - what = va_arg(ap, int); - fpp = va_arg(ap, FILE **); - rv = 0; - switch (what) { - case 0: - *fpp = el->el_infile; - break; - case 1: - *fpp = el->el_outfile; - break; - case 2: - *fpp = el->el_errfile; - break; - default: - rv = -1; - break; - } - break; - } - default: - rv = -1; - break; - } - va_end(ap); - - return rv; -} - - -/* el_line(): - * Return editing info - */ -const LineInfoW * -el_wline(EditLine *el) -{ - - return (const LineInfoW *)(void *)&el->el_line; -} - - -/* el_source(): - * Source a file - */ -int -el_source(EditLine *el, const char *fname) -{ - FILE *fp; - size_t len; - ssize_t slen; - char *ptr; - char *path = NULL; - const wchar_t *dptr; - int error = 0; - - fp = NULL; - if (fname == NULL) { - static const char elpath[] = "/.editrc"; - size_t plen = sizeof(elpath); - - if ((ptr = secure_getenv("HOME")) == NULL) - return -1; - plen += strlen(ptr); - if ((path = el_malloc(plen * sizeof(*path))) == NULL) - return -1; - (void)snprintf(path, plen, "%s%s", ptr, elpath); - fname = path; - } - if (fp == NULL) - fp = fopen(fname, "r"); - if (fp == NULL) { - el_free(path); - return -1; - } - - ptr = NULL; - len = 0; - while ((slen = getline(&ptr, &len, fp)) != -1) { - if (*ptr == '\n') - continue; /* Empty line. */ - if (slen > 0 && ptr[--slen] == '\n') - ptr[slen] = '\0'; - - dptr = ct_decode_string(ptr, &el->el_scratch); - if (!dptr) - continue; - /* loop until first non-space char or EOL */ - while (*dptr != '\0' && iswspace(*dptr)) - dptr++; - if (*dptr == '#') - continue; /* ignore, this is a comment line */ - if ((error = parse_line(el, dptr)) == -1) - break; - } - free(ptr); - - el_free(path); - (void) fclose(fp); - return error; -} - - -/* el_resize(): - * Called from program when terminal is resized - */ -void -el_resize(EditLine *el) -{ - int lins, cols; - sigset_t oset, nset; - - (void) sigemptyset(&nset); - (void) sigaddset(&nset, SIGWINCH); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - - /* get the correct window size */ - if (terminal_get_size(el, &lins, &cols)) - terminal_change_size(el, lins, cols); - - (void) sigprocmask(SIG_SETMASK, &oset, NULL); -} - - -/* el_beep(): - * Called from the program to beep - */ -void -el_beep(EditLine *el) -{ - - terminal_beep(el); -} - - -/* el_editmode() - * Set the state of EDIT_DISABLED from the `edit' command. - */ -libedit_private int -/*ARGSUSED*/ -el_editmode(EditLine *el, int argc, const wchar_t **argv) -{ - const wchar_t *how; - - if (argv == NULL || argc != 2 || argv[1] == NULL) - return -1; - - how = argv[1]; - if (wcscmp(how, L"on") == 0) { - el->el_flags &= ~EDIT_DISABLED; - tty_rawmode(el); - } else if (wcscmp(how, L"off") == 0) { - tty_cookedmode(el); - el->el_flags |= EDIT_DISABLED; - } - else { - (void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n", - how); - return -1; - } - return 0; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/el.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/el.h deleted file mode 100644 index c281bc0..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/el.h +++ /dev/null @@ -1,153 +0,0 @@ -/* $NetBSD: el.h,v 1.41 2016/05/24 15:00:45 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)el.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.h: Internal structures. - */ -#ifndef _h_el -#define _h_el -/* - * Local defaults - */ -#define KSHVI -#define VIDEFAULT -#define ANCHOR - -#include "histedit.h" -#include "chartype.h" - -#define EL_BUFSIZ ((size_t)1024) /* Maximum line size */ - -#define HANDLE_SIGNALS 0x01 -#define NO_TTY 0x02 -#define EDIT_DISABLED 0x04 -#define UNBUFFERED 0x08 -#define CHARSET_IS_UTF8 0x10 -#define NARROW_HISTORY 0x40 - -typedef unsigned char el_action_t; /* Index to command array */ - -typedef struct coord_t { /* Position on the screen */ - int h; - int v; -} coord_t; - -typedef struct el_line_t { - wchar_t *buffer; /* Input line */ - wchar_t *cursor; /* Cursor position */ - wchar_t *lastchar; /* Last character */ - const wchar_t *limit; /* Max position */ -} el_line_t; - -/* - * Editor state - */ -typedef struct el_state_t { - int inputmode; /* What mode are we in? */ - int doingarg; /* Are we getting an argument? */ - int argument; /* Numeric argument */ - int metanext; /* Is the next char a meta char */ - el_action_t lastcmd; /* Previous command */ - el_action_t thiscmd; /* this command */ - wchar_t thisch; /* char that generated it */ -} el_state_t; - -/* - * Until we come up with something better... - */ -#define el_malloc(a) malloc(a) -#define el_realloc(a,b) realloc(a, b) -#define el_free(a) free(a) - -#include "tty.h" -#include "prompt.h" -#include "keymacro.h" -#include "terminal.h" -#include "refresh.h" -#include "chared.h" -#include "search.h" -#include "hist.h" -#include "map.h" -#include "sig.h" - -struct el_read_t; - -struct editline { - wchar_t *el_prog; /* the program name */ - FILE *el_infile; /* Stdio stuff */ - FILE *el_outfile; /* Stdio stuff */ - FILE *el_errfile; /* Stdio stuff */ - int el_infd; /* Input file descriptor */ - int el_outfd; /* Output file descriptor */ - int el_errfd; /* Error file descriptor */ - int el_flags; /* Various flags. */ - coord_t el_cursor; /* Cursor location */ - wchar_t **el_display; /* Real screen image = what is there */ - wchar_t **el_vdisplay; /* Virtual screen image = what we see */ - void *el_data; /* Client data */ - el_line_t el_line; /* The current line information */ - el_state_t el_state; /* Current editor state */ - el_terminal_t el_terminal; /* Terminal dependent stuff */ - el_tty_t el_tty; /* Tty dependent stuff */ - el_refresh_t el_refresh; /* Refresh stuff */ - el_prompt_t el_prompt; /* Prompt stuff */ - el_prompt_t el_rprompt; /* Prompt stuff */ - el_chared_t el_chared; /* Characted editor stuff */ - el_map_t el_map; /* Key mapping stuff */ - el_keymacro_t el_keymacro; /* Key binding stuff */ - el_history_t el_history; /* History stuff */ - el_search_t el_search; /* Search stuff */ - el_signal_t el_signal; /* Signal handling stuff */ - struct el_read_t *el_read; /* Character reading stuff */ - ct_buffer_t el_visual; /* Buffer for displayable str */ - ct_buffer_t el_scratch; /* Scratch conversion buffer */ - ct_buffer_t el_lgcyconv; /* Buffer for legacy wrappers */ - LineInfo el_lgcylinfo; /* Legacy LineInfo buffer */ -}; - -libedit_private int el_editmode(EditLine *, int, const wchar_t **); - -#ifdef DEBUG -#define EL_ABORT(a) do { \ - fprintf(el->el_errfile, "%s, %d: ", \ - __FILE__, __LINE__); \ - fprintf a; \ - abort(); \ - } while( /*CONSTCOND*/0); -#else -#define EL_ABORT(a) abort() -#endif -#endif /* _h_el */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/eln.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/eln.c deleted file mode 100644 index aa0a5b5..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/eln.c +++ /dev/null @@ -1,388 +0,0 @@ -/* $NetBSD: eln.c,v 1.34 2016/05/09 21:37:34 christos Exp $ */ - -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: eln.c,v 1.34 2016/05/09 21:37:34 christos Exp $"); -#endif /* not lint && not SCCSID */ - -#include -#include -#include -#include - -#include "el.h" - -int -el_getc(EditLine *el, char *cp) -{ - int num_read; - wchar_t wc = 0; - - num_read = el_wgetc(el, &wc); - *cp = '\0'; - if (num_read <= 0) - return num_read; - num_read = wctob(wc); - if (num_read == EOF) { - errno = ERANGE; - return -1; - } else { - *cp = (char)num_read; - return 1; - } -} - - -void -el_push(EditLine *el, const char *str) -{ - /* Using multibyte->wide string decoding works fine under single-byte - * character sets too, and Does The Right Thing. */ - el_wpush(el, ct_decode_string(str, &el->el_lgcyconv)); -} - - -const char * -el_gets(EditLine *el, int *nread) -{ - const wchar_t *tmp; - - tmp = el_wgets(el, nread); - if (tmp != NULL) { - int i; - size_t nwread = 0; - - for (i = 0; i < *nread; i++) - nwread += ct_enc_width(tmp[i]); - *nread = (int)nwread; - } - return ct_encode_string(tmp, &el->el_lgcyconv); -} - - -int -el_parse(EditLine *el, int argc, const char *argv[]) -{ - int ret; - const wchar_t **wargv; - - wargv = (void *)ct_decode_argv(argc, argv, &el->el_lgcyconv); - if (!wargv) - return -1; - ret = el_wparse(el, argc, wargv); - el_free(wargv); - - return ret; -} - - -int -el_set(EditLine *el, int op, ...) -{ - va_list ap; - int ret; - - if (!el) - return -1; - va_start(ap, op); - - switch (op) { - case EL_PROMPT: /* el_pfunc_t */ - case EL_RPROMPT: { - el_pfunc_t p = va_arg(ap, el_pfunc_t); - ret = prompt_set(el, p, 0, op, 0); - break; - } - - case EL_RESIZE: { - el_zfunc_t p = va_arg(ap, el_zfunc_t); - void *arg = va_arg(ap, void *); - ret = ch_resizefun(el, p, arg); - break; - } - - case EL_ALIAS_TEXT: { - el_afunc_t p = va_arg(ap, el_afunc_t); - void *arg = va_arg(ap, void *); - ret = ch_aliasfun(el, p, arg); - break; - } - - case EL_PROMPT_ESC: - case EL_RPROMPT_ESC: { - el_pfunc_t p = va_arg(ap, el_pfunc_t); - int c = va_arg(ap, int); - - ret = prompt_set(el, p, c, op, 0); - break; - } - - case EL_TERMINAL: /* const char * */ - ret = el_wset(el, op, va_arg(ap, char *)); - break; - - case EL_EDITOR: /* const wchar_t * */ - ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *), - &el->el_lgcyconv)); - break; - - case EL_SIGNAL: /* int */ - case EL_EDITMODE: - case EL_UNBUFFERED: - case EL_PREP_TERM: - ret = el_wset(el, op, va_arg(ap, int)); - break; - - case EL_BIND: /* const char * list -> const wchar_t * list */ - case EL_TELLTC: - case EL_SETTC: - case EL_ECHOTC: - case EL_SETTY: { - const char *argv[20]; - int i; - const wchar_t **wargv; - for (i = 1; i < (int)__arraycount(argv) - 1; ++i) - if ((argv[i] = va_arg(ap, const char *)) == NULL) - break; - argv[0] = argv[i] = NULL; - wargv = (void *)ct_decode_argv(i + 1, argv, &el->el_lgcyconv); - if (!wargv) { - ret = -1; - goto out; - } - /* - * AFAIK we can't portably pass through our new wargv to - * el_wset(), so we have to reimplement the body of - * el_wset() for these ops. - */ - switch (op) { - case EL_BIND: - wargv[0] = L"bind"; - ret = map_bind(el, i, wargv); - break; - case EL_TELLTC: - wargv[0] = L"telltc"; - ret = terminal_telltc(el, i, wargv); - break; - case EL_SETTC: - wargv[0] = L"settc"; - ret = terminal_settc(el, i, wargv); - break; - case EL_ECHOTC: - wargv[0] = L"echotc"; - ret = terminal_echotc(el, i, wargv); - break; - case EL_SETTY: - wargv[0] = L"setty"; - ret = tty_stty(el, i, wargv); - break; - default: - ret = -1; - } - el_free(wargv); - break; - } - - /* XXX: do we need to change el_func_t too? */ - case EL_ADDFN: { /* const char *, const char *, el_func_t */ - const char *args[2]; - el_func_t func; - wchar_t **wargv; - - args[0] = va_arg(ap, const char *); - args[1] = va_arg(ap, const char *); - func = va_arg(ap, el_func_t); - - wargv = ct_decode_argv(2, args, &el->el_lgcyconv); - if (!wargv) { - ret = -1; - goto out; - } - /* XXX: The two strdup's leak */ - ret = map_addfunc(el, wcsdup(wargv[0]), wcsdup(wargv[1]), - func); - el_free(wargv); - break; - } - case EL_HIST: { /* hist_fun_t, const char * */ - hist_fun_t fun = va_arg(ap, hist_fun_t); - void *ptr = va_arg(ap, void *); - ret = hist_set(el, fun, ptr); - el->el_flags |= NARROW_HISTORY; - break; - } - - case EL_GETCFN: /* el_rfunc_t */ - ret = el_wset(el, op, va_arg(ap, el_rfunc_t)); - break; - - case EL_CLIENTDATA: /* void * */ - ret = el_wset(el, op, va_arg(ap, void *)); - break; - - case EL_SETFP: { /* int, FILE * */ - int what = va_arg(ap, int); - FILE *fp = va_arg(ap, FILE *); - ret = el_wset(el, op, what, fp); - break; - } - - case EL_REFRESH: - re_clear_display(el); - re_refresh(el); - terminal__flush(el); - ret = 0; - break; - - default: - ret = -1; - break; - } - -out: - va_end(ap); - return ret; -} - - -int -el_get(EditLine *el, int op, ...) -{ - va_list ap; - int ret; - - if (!el) - return -1; - - va_start(ap, op); - - switch (op) { - case EL_PROMPT: /* el_pfunc_t * */ - case EL_RPROMPT: { - el_pfunc_t *p = va_arg(ap, el_pfunc_t *); - ret = prompt_get(el, p, 0, op); - break; - } - - case EL_PROMPT_ESC: /* el_pfunc_t *, char **/ - case EL_RPROMPT_ESC: { - el_pfunc_t *p = va_arg(ap, el_pfunc_t *); - char *c = va_arg(ap, char *); - wchar_t wc = 0; - ret = prompt_get(el, p, &wc, op); - *c = (char)wc; - break; - } - - case EL_EDITOR: { - const char **p = va_arg(ap, const char **); - const wchar_t *pw; - ret = el_wget(el, op, &pw); - *p = ct_encode_string(pw, &el->el_lgcyconv); - if (!el->el_lgcyconv.csize) - ret = -1; - break; - } - - case EL_TERMINAL: /* const char ** */ - ret = el_wget(el, op, va_arg(ap, const char **)); - break; - - case EL_SIGNAL: /* int * */ - case EL_EDITMODE: - case EL_UNBUFFERED: - case EL_PREP_TERM: - ret = el_wget(el, op, va_arg(ap, int *)); - break; - - case EL_GETTC: { - char *argv[20]; - static char gettc[] = "gettc"; - int i; - for (i = 1; i < (int)__arraycount(argv); ++i) - if ((argv[i] = va_arg(ap, char *)) == NULL) - break; - argv[0] = gettc; - ret = terminal_gettc(el, i, argv); - break; - } - - case EL_GETCFN: /* el_rfunc_t */ - ret = el_wget(el, op, va_arg(ap, el_rfunc_t *)); - break; - - case EL_CLIENTDATA: /* void ** */ - ret = el_wget(el, op, va_arg(ap, void **)); - break; - - case EL_GETFP: { /* int, FILE ** */ - int what = va_arg(ap, int); - FILE **fpp = va_arg(ap, FILE **); - ret = el_wget(el, op, what, fpp); - break; - } - - default: - ret = -1; - break; - } - - va_end(ap); - return ret; -} - - -const LineInfo * -el_line(EditLine *el) -{ - const LineInfoW *winfo = el_wline(el); - LineInfo *info = &el->el_lgcylinfo; - size_t offset; - const wchar_t *p; - - info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv); - - offset = 0; - for (p = winfo->buffer; p < winfo->cursor; p++) - offset += ct_enc_width(*p); - info->cursor = info->buffer + offset; - - offset = 0; - for (p = winfo->buffer; p < winfo->lastchar; p++) - offset += ct_enc_width(*p); - info->lastchar = info->buffer + offset; - - return info; -} - - -int -el_insertstr(EditLine *el, const char *str) -{ - return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv)); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/emacs.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/emacs.c deleted file mode 100644 index 0636c28..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/emacs.c +++ /dev/null @@ -1,512 +0,0 @@ -/* $NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * emacs.c: Emacs functions - */ -#include - -#include "el.h" -#include "emacs.h" -#include "fcns.h" - -/* em_delete_or_list(): - * Delete character under cursor or list completions if at end of line - * [^D] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_delete_or_list(EditLine *el, wint_t c) -{ - - if (el->el_line.cursor == el->el_line.lastchar) { - /* if I'm at the end */ - if (el->el_line.cursor == el->el_line.buffer) { - /* and the beginning */ - terminal_writec(el, c); /* then do an EOF */ - return CC_EOF; - } else { - /* - * Here we could list completions, but it is an - * error right now - */ - terminal_beep(el); - return CC_ERROR; - } - } else { - if (el->el_state.doingarg) - c_delafter(el, el->el_state.argument); - else - c_delafter1(el); - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - /* bounds check */ - return CC_REFRESH; - } -} - - -/* em_delete_next_word(): - * Cut from cursor to end of current word - * [M-d] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *cp, *p, *kp; - - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - - cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); - - for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++) - /* save the text */ - *kp++ = *p; - el->el_chared.c_kill.last = kp; - - c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */ - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - /* bounds check */ - return CC_REFRESH; -} - - -/* em_yank(): - * Paste cut buffer at cursor position - * [^Y] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_yank(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *kp, *cp; - - if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) - return CC_NORM; - - if (el->el_line.lastchar + - (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= - el->el_line.limit) - return CC_ERROR; - - el->el_chared.c_kill.mark = el->el_line.cursor; - cp = el->el_line.cursor; - - /* open the space, */ - c_insert(el, - (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf)); - /* copy the chars */ - for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++) - *cp++ = *kp; - - /* if an arg, cursor at beginning else cursor at end */ - if (el->el_state.argument == 1) - el->el_line.cursor = cp; - - return CC_REFRESH; -} - - -/* em_kill_line(): - * Cut the entire line and save in cut buffer - * [^U] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_kill_line(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *kp, *cp; - - cp = el->el_line.buffer; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.lastchar) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - /* zap! -- delete all of it */ - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - return CC_REFRESH; -} - - -/* em_kill_region(): - * Cut area between mark and cursor and save in cut buffer - * [^W] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_kill_region(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *kp, *cp; - - if (!el->el_chared.c_kill.mark) - return CC_ERROR; - - if (el->el_chared.c_kill.mark > el->el_line.cursor) { - cp = el->el_line.cursor; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_chared.c_kill.mark) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - c_delafter(el, (int)(cp - el->el_line.cursor)); - } else { /* mark is before cursor */ - cp = el->el_chared.c_kill.mark; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.cursor) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark)); - el->el_line.cursor = el->el_chared.c_kill.mark; - } - return CC_REFRESH; -} - - -/* em_copy_region(): - * Copy area between mark and cursor to cut buffer - * [M-W] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_copy_region(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *kp, *cp; - - if (!el->el_chared.c_kill.mark) - return CC_ERROR; - - if (el->el_chared.c_kill.mark > el->el_line.cursor) { - cp = el->el_line.cursor; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_chared.c_kill.mark) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - } else { - cp = el->el_chared.c_kill.mark; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.cursor) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - } - return CC_NORM; -} - - -/* em_gosmacs_transpose(): - * Exchange the two characters before the cursor - * Gosling emacs transpose chars [^T] - */ -libedit_private el_action_t -em_gosmacs_transpose(EditLine *el, wint_t c) -{ - - if (el->el_line.cursor > &el->el_line.buffer[1]) { - /* must have at least two chars entered */ - c = el->el_line.cursor[-2]; - el->el_line.cursor[-2] = el->el_line.cursor[-1]; - el->el_line.cursor[-1] = c; - return CC_REFRESH; - } else - return CC_ERROR; -} - - -/* em_next_word(): - * Move next to end of current word - * [M-f] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_next_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - - el->el_line.cursor = c__next_word(el->el_line.cursor, - el->el_line.lastchar, - el->el_state.argument, - ce__isword); - - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* em_upper_case(): - * Uppercase the characters from cursor to end of current word - * [M-u] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_upper_case(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *cp, *ep; - - ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); - - for (cp = el->el_line.cursor; cp < ep; cp++) - if (iswlower(*cp)) - *cp = towupper(*cp); - - el->el_line.cursor = ep; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - return CC_REFRESH; -} - - -/* em_capitol_case(): - * Capitalize the characters from cursor to end of current word - * [M-c] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *cp, *ep; - - ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); - - for (cp = el->el_line.cursor; cp < ep; cp++) { - if (iswalpha(*cp)) { - if (iswlower(*cp)) - *cp = towupper(*cp); - cp++; - break; - } - } - for (; cp < ep; cp++) - if (iswupper(*cp)) - *cp = towlower(*cp); - - el->el_line.cursor = ep; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - return CC_REFRESH; -} - - -/* em_lower_case(): - * Lowercase the characters from cursor to end of current word - * [M-l] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_lower_case(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *cp, *ep; - - ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); - - for (cp = el->el_line.cursor; cp < ep; cp++) - if (iswupper(*cp)) - *cp = towlower(*cp); - - el->el_line.cursor = ep; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - return CC_REFRESH; -} - - -/* em_set_mark(): - * Set the mark at cursor - * [^@] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_set_mark(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_chared.c_kill.mark = el->el_line.cursor; - return CC_NORM; -} - - -/* em_exchange_mark(): - * Exchange the cursor and mark - * [^X^X] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *cp; - - cp = el->el_line.cursor; - el->el_line.cursor = el->el_chared.c_kill.mark; - el->el_chared.c_kill.mark = cp; - return CC_CURSOR; -} - - -/* em_universal_argument(): - * Universal argument (argument times 4) - * [^U] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__))) -{ /* multiply current argument by 4 */ - - if (el->el_state.argument > 1000000) - return CC_ERROR; - el->el_state.doingarg = 1; - el->el_state.argument *= 4; - return CC_ARGHACK; -} - - -/* em_meta_next(): - * Add 8th bit to next character typed - * [] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_meta_next(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_state.metanext = 1; - return CC_ARGHACK; -} - - -/* em_toggle_overwrite(): - * Switch from insert to overwrite mode or vice versa - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ? - MODE_REPLACE : MODE_INSERT; - return CC_NORM; -} - - -/* em_copy_prev_word(): - * Copy current word to cursor - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *cp, *oldc, *dp; - - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - - oldc = el->el_line.cursor; - /* does a bounds check */ - cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, - el->el_state.argument, ce__isword); - - c_insert(el, (int)(oldc - cp)); - for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++) - *dp++ = *cp; - - el->el_line.cursor = dp;/* put cursor at end */ - - return CC_REFRESH; -} - - -/* em_inc_search_next(): - * Emacs incremental next search - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_search.patlen = 0; - return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY); -} - - -/* em_inc_search_prev(): - * Emacs incremental reverse search - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_search.patlen = 0; - return ce_inc_search(el, ED_SEARCH_PREV_HISTORY); -} - - -/* em_delete_prev_char(): - * Delete the character to the left of the cursor - * [^?] - */ -libedit_private el_action_t -/*ARGSUSED*/ -em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor <= el->el_line.buffer) - return CC_ERROR; - - if (el->el_state.doingarg) - c_delbefore(el, el->el_state.argument); - else - c_delbefore1(el); - el->el_line.cursor -= el->el_state.argument; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; - return CC_REFRESH; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/filecomplete.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/filecomplete.c deleted file mode 100644 index e81f616..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/filecomplete.c +++ /dev/null @@ -1,572 +0,0 @@ -/* $NetBSD: filecomplete.c,v 1.44 2016/10/31 17:46:32 abhinav Exp $ */ - -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#include "config.h" - -#if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: filecomplete.c,v 1.44 2016/10/31 17:46:32 abhinav Exp $"); -#endif /* not lint && not SCCSID */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "el.h" -#include "filecomplete.h" - -static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{("; - -/********************************/ -/* completion functions */ - -/* - * does tilde expansion of strings of type ``~user/foo'' - * if ``user'' isn't valid user name or ``txt'' doesn't start - * w/ '~', returns pointer to strdup()ed copy of ``txt'' - * - * it's the caller's responsibility to free() the returned string - */ -char * -fn_tilde_expand(const char *txt) -{ -#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) - struct passwd pwres; - char pwbuf[1024]; -#endif - struct passwd *pass; - char *temp; - size_t len = 0; - - if (txt[0] != '~') - return strdup(txt); - - temp = strchr(txt + 1, '/'); - if (temp == NULL) { - temp = strdup(txt + 1); - if (temp == NULL) - return NULL; - } else { - /* text until string after slash */ - len = (size_t)(temp - txt + 1); - temp = el_malloc(len * sizeof(*temp)); - if (temp == NULL) - return NULL; - (void)strncpy(temp, txt + 1, len - 2); - temp[len - 2] = '\0'; - } - if (temp[0] == 0) { -#ifdef HAVE_GETPW_R_POSIX - if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), - &pass) != 0) - pass = NULL; -#elif HAVE_GETPW_R_DRAFT - pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf)); -#else - pass = getpwuid(getuid()); -#endif - } else { -#ifdef HAVE_GETPW_R_POSIX - if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0) - pass = NULL; -#elif HAVE_GETPW_R_DRAFT - pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf)); -#else - pass = getpwnam(temp); -#endif - } - el_free(temp); /* value no more needed */ - if (pass == NULL) - return strdup(txt); - - /* update pointer txt to point at string immedially following */ - /* first slash */ - txt += len; - - len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1; - temp = el_malloc(len * sizeof(*temp)); - if (temp == NULL) - return NULL; - (void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt); - - return temp; -} - - -/* - * return first found file name starting by the ``text'' or NULL if no - * such file can be found - * value of ``state'' is ignored - * - * it's the caller's responsibility to free the returned string - */ -char * -fn_filename_completion_function(const char *text, int state) -{ - static DIR *dir = NULL; - static char *filename = NULL, *dirname = NULL, *dirpath = NULL; - static size_t filename_len = 0; - struct dirent *entry; - char *temp; - size_t len; - - if (state == 0 || dir == NULL) { - temp = strrchr(text, '/'); - if (temp) { - char *nptr; - temp++; - nptr = el_realloc(filename, (strlen(temp) + 1) * - sizeof(*nptr)); - if (nptr == NULL) { - el_free(filename); - filename = NULL; - return NULL; - } - filename = nptr; - (void)strcpy(filename, temp); - len = (size_t)(temp - text); /* including last slash */ - - nptr = el_realloc(dirname, (len + 1) * - sizeof(*nptr)); - if (nptr == NULL) { - el_free(dirname); - dirname = NULL; - return NULL; - } - dirname = nptr; - (void)strncpy(dirname, text, len); - dirname[len] = '\0'; - } else { - el_free(filename); - if (*text == 0) - filename = NULL; - else { - filename = strdup(text); - if (filename == NULL) - return NULL; - } - el_free(dirname); - dirname = NULL; - } - - if (dir != NULL) { - (void)closedir(dir); - dir = NULL; - } - - /* support for ``~user'' syntax */ - - el_free(dirpath); - dirpath = NULL; - if (dirname == NULL) { - if ((dirname = strdup("")) == NULL) - return NULL; - dirpath = strdup("./"); - } else if (*dirname == '~') - dirpath = fn_tilde_expand(dirname); - else - dirpath = strdup(dirname); - - if (dirpath == NULL) - return NULL; - - dir = opendir(dirpath); - if (!dir) - return NULL; /* cannot open the directory */ - - /* will be used in cycle */ - filename_len = filename ? strlen(filename) : 0; - } - - /* find the match */ - while ((entry = readdir(dir)) != NULL) { - /* skip . and .. */ - if (entry->d_name[0] == '.' && (!entry->d_name[1] - || (entry->d_name[1] == '.' && !entry->d_name[2]))) - continue; - if (filename_len == 0) - break; - /* otherwise, get first entry where first */ - /* filename_len characters are equal */ - if (entry->d_name[0] == filename[0] - /* Some dirents have d_namlen, but it is not portable. */ - && strlen(entry->d_name) >= filename_len - && strncmp(entry->d_name, filename, - filename_len) == 0) - break; - } - - if (entry) { /* match found */ - - /* Some dirents have d_namlen, but it is not portable. */ - len = strlen(entry->d_name); - - len = strlen(dirname) + len + 1; - temp = el_malloc(len * sizeof(*temp)); - if (temp == NULL) - return NULL; - (void)snprintf(temp, len, "%s%s", dirname, entry->d_name); - } else { - (void)closedir(dir); - dir = NULL; - temp = NULL; - } - - return temp; -} - - -static const char * -append_char_function(const char *name) -{ - struct stat stbuf; - char *expname = *name == '~' ? fn_tilde_expand(name) : NULL; - const char *rs = " "; - - if (stat(expname ? expname : name, &stbuf) == -1) - goto out; - if (S_ISDIR(stbuf.st_mode)) - rs = "/"; -out: - if (expname) - el_free(expname); - return rs; -} -/* - * returns list of completions for text given - * non-static for readline. - */ -char ** completion_matches(const char *, char *(*)(const char *, int)); -char ** -completion_matches(const char *text, char *(*genfunc)(const char *, int)) -{ - char **match_list = NULL, *retstr, *prevstr; - size_t match_list_len, max_equal, which, i; - size_t matches; - - matches = 0; - match_list_len = 1; - while ((retstr = (*genfunc) (text, (int)matches)) != NULL) { - /* allow for list terminator here */ - if (matches + 3 >= match_list_len) { - char **nmatch_list; - while (matches + 3 >= match_list_len) - match_list_len <<= 1; - nmatch_list = el_realloc(match_list, - match_list_len * sizeof(*nmatch_list)); - if (nmatch_list == NULL) { - el_free(match_list); - return NULL; - } - match_list = nmatch_list; - - } - match_list[++matches] = retstr; - } - - if (!match_list) - return NULL; /* nothing found */ - - /* find least denominator and insert it to match_list[0] */ - which = 2; - prevstr = match_list[1]; - max_equal = strlen(prevstr); - for (; which <= matches; which++) { - for (i = 0; i < max_equal && - prevstr[i] == match_list[which][i]; i++) - continue; - max_equal = i; - } - - retstr = el_malloc((max_equal + 1) * sizeof(*retstr)); - if (retstr == NULL) { - el_free(match_list); - return NULL; - } - (void)strncpy(retstr, match_list[1], max_equal); - retstr[max_equal] = '\0'; - match_list[0] = retstr; - - /* add NULL as last pointer to the array */ - match_list[matches + 1] = NULL; - - return match_list; -} - -/* - * Sort function for qsort(). Just wrapper around strcasecmp(). - */ -static int -_fn_qsort_string_compare(const void *i1, const void *i2) -{ - const char *s1 = ((const char * const *)i1)[0]; - const char *s2 = ((const char * const *)i2)[0]; - - return strcasecmp(s1, s2); -} - -/* - * Display list of strings in columnar format on readline's output stream. - * 'matches' is list of strings, 'num' is number of strings in 'matches', - * 'width' is maximum length of string in 'matches'. - * - * matches[0] is not one of the match strings, but it is counted in - * num, so the strings are matches[1] *through* matches[num-1]. - */ -void -fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width) -{ - size_t line, lines, col, cols, thisguy; - int screenwidth = el->el_terminal.t_size.h; - - /* Ignore matches[0]. Avoid 1-based array logic below. */ - matches++; - num--; - - /* - * Find out how many entries can be put on one line; count - * with one space between strings the same way it's printed. - */ - cols = (size_t)screenwidth / (width + 1); - if (cols == 0) - cols = 1; - - /* how many lines of output, rounded up */ - lines = (num + cols - 1) / cols; - - /* Sort the items. */ - qsort(matches, num, sizeof(char *), _fn_qsort_string_compare); - - /* - * On the ith line print elements i, i+lines, i+lines*2, etc. - */ - for (line = 0; line < lines; line++) { - for (col = 0; col < cols; col++) { - thisguy = line + col * lines; - if (thisguy >= num) - break; - (void)fprintf(el->el_outfile, "%s%-*s", - col == 0 ? "" : " ", (int)width, matches[thisguy]); - } - (void)fprintf(el->el_outfile, "\n"); - } -} - -/* - * Complete the word at or before point, - * 'what_to_do' says what to do with the completion. - * \t means do standard completion. - * `?' means list the possible completions. - * `*' means insert all of the possible completions. - * `!' means to do standard completion, and list all possible completions if - * there is more than one. - * - * Note: '*' support is not implemented - * '!' could never be invoked - */ -int -fn_complete(EditLine *el, - char *(*complet_func)(const char *, int), - char **(*attempted_completion_function)(const char *, int, int), - const wchar_t *word_break, const wchar_t *special_prefixes, - const char *(*app_func)(const char *), size_t query_items, - int *completion_type, int *over, int *point, int *end, - const wchar_t *(*bsd_unused0)(const wchar_t *, const wchar_t *), - wchar_t *(*bsd_unused1)(const wchar_t *), - char *(*bsd_unused2)(const char *) - ) -{ - const LineInfoW *li; - wchar_t *temp; - char **matches; - const wchar_t *ctemp; - size_t len; - int what_to_do = '\t'; - int retval = CC_NORM; - - if (el->el_state.lastcmd == el->el_state.thiscmd) - what_to_do = '?'; - - /* readline's rl_complete() has to be told what we did... */ - if (completion_type != NULL) - *completion_type = what_to_do; - - if (!complet_func) - complet_func = fn_filename_completion_function; - if (!app_func) - app_func = append_char_function; - - /* We now look backwards for the start of a filename/variable word */ - li = el_wline(el); - ctemp = li->cursor; - while (ctemp > li->buffer - && !wcschr(word_break, ctemp[-1]) - && (!special_prefixes || !wcschr(special_prefixes, ctemp[-1]) ) ) - ctemp--; - - len = (size_t)(li->cursor - ctemp); - temp = el_malloc((len + 1) * sizeof(*temp)); - (void)wcsncpy(temp, ctemp, len); - temp[len] = '\0'; - - /* these can be used by function called in completion_matches() */ - /* or (*attempted_completion_function)() */ - if (point != NULL) - *point = (int)(li->cursor - li->buffer); - if (end != NULL) - *end = (int)(li->lastchar - li->buffer); - - if (attempted_completion_function) { - int cur_off = (int)(li->cursor - li->buffer); - matches = (*attempted_completion_function)( - ct_encode_string(temp, &el->el_scratch), - cur_off - (int)len, cur_off); - } else - matches = NULL; - if (!attempted_completion_function || - (over != NULL && !*over && !matches)) - matches = completion_matches( - ct_encode_string(temp, &el->el_scratch), complet_func); - - if (over != NULL) - *over = 0; - - if (matches) { - int i; - size_t matches_num, maxlen, match_len, match_display=1; - - retval = CC_REFRESH; - /* - * Only replace the completed string with common part of - * possible matches if there is possible completion. - */ - if (matches[0][0] != '\0') { - el_deletestr(el, (int) len); - el_winsertstr(el, - ct_decode_string(matches[0], &el->el_scratch)); - } - - - if (matches[2] == NULL && - (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) { - /* - * We found exact match. Add a space after - * it, unless we do filename completion and the - * object is a directory. - */ - el_winsertstr(el, - ct_decode_string((*app_func)(matches[0]), - &el->el_scratch)); - } else if (what_to_do == '!' || what_to_do == '?') { - /* - * More than one match and requested to list possible - * matches. - */ - - for(i = 1, maxlen = 0; matches[i]; i++) { - match_len = strlen(matches[i]); - if (match_len > maxlen) - maxlen = match_len; - } - /* matches[1] through matches[i-1] are available */ - matches_num = (size_t)(i - 1); - - /* newline to get on next line from command line */ - (void)fprintf(el->el_outfile, "\n"); - - /* - * If there are too many items, ask user for display - * confirmation. - */ - if (matches_num > query_items) { - (void)fprintf(el->el_outfile, - "Display all %zu possibilities? (y or n) ", - matches_num); - (void)fflush(el->el_outfile); - if (getc(stdin) != 'y') - match_display = 0; - (void)fprintf(el->el_outfile, "\n"); - } - - if (match_display) { - /* - * Interface of this function requires the - * strings be matches[1..num-1] for compat. - * We have matches_num strings not counting - * the prefix in matches[0], so we need to - * add 1 to matches_num for the call. - */ - fn_display_match_list(el, matches, - matches_num+1, maxlen); - } - retval = CC_REDISPLAY; - } else if (matches[0][0]) { - /* - * There was some common match, but the name was - * not complete enough. Next tab will print possible - * completions. - */ - el_beep(el); - } else { - /* lcd is not a valid object - further specification */ - /* is needed */ - el_beep(el); - retval = CC_NORM; - } - - /* free elements of array and the array itself */ - for (i = 0; matches[i]; i++) - el_free(matches[i]); - el_free(matches); - matches = NULL; - } - el_free(temp); - return retval; -} - -/* - * el-compatible wrapper around rl_complete; needed for key binding - */ -/* ARGSUSED */ -unsigned char -_el_fn_complete(EditLine *el, int ch __attribute__((__unused__))) -{ - return (unsigned char)fn_complete(el, NULL, NULL, - break_chars, NULL, NULL, (size_t)100, - NULL, NULL, NULL, NULL, NULL, NULL, NULL); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/filecomplete.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/filecomplete.h deleted file mode 100644 index fc1ca97..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/filecomplete.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: filecomplete.h,v 1.10 2016/04/11 00:50:13 christos Exp $ */ - -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ -#ifndef _FILECOMPLETE_H_ -#define _FILECOMPLETE_H_ - -int fn_complete(EditLine *, - char *(*)(const char *, int), - char **(*)(const char *, int, int), - const wchar_t *, const wchar_t *, const char *(*)(const char *), size_t, - int *, int *, int *, int *, - const wchar_t *(*)(const wchar_t *, const wchar_t *), - wchar_t *(*)(const wchar_t *), - char *(*)(const char *) - ); - -void fn_display_match_list(EditLine *, char **, size_t, size_t); -char *fn_tilde_expand(const char *); -char *fn_filename_completion_function(const char *, int); - -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/hist.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/hist.c deleted file mode 100644 index 3c9db7d..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/hist.c +++ /dev/null @@ -1,252 +0,0 @@ -/* $NetBSD: hist.c,v 1.32 2017/03/05 19:23:58 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: hist.c,v 1.32 2017/03/05 19:23:58 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * hist.c: History access functions - */ -#include -#include -#include - -#include "el.h" - -/* hist_init(): - * Initialization function. - */ -libedit_private int -hist_init(EditLine *el) -{ - - el->el_history.fun = NULL; - el->el_history.ref = NULL; - el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf)); - el->el_history.sz = EL_BUFSIZ; - if (el->el_history.buf == NULL) - return -1; - el->el_history.last = el->el_history.buf; - return 0; -} - - -/* hist_end(): - * clean up history; - */ -libedit_private void -hist_end(EditLine *el) -{ - - el_free(el->el_history.buf); - el->el_history.buf = NULL; -} - - -/* hist_set(): - * Set new history interface - */ -libedit_private int -hist_set(EditLine *el, hist_fun_t fun, void *ptr) -{ - - el->el_history.ref = ptr; - el->el_history.fun = fun; - return 0; -} - - -/* hist_get(): - * Get a history line and update it in the buffer. - * eventno tells us the event to get. - */ -libedit_private el_action_t -hist_get(EditLine *el) -{ - const wchar_t *hp; - int h; - size_t blen, hlen; - - if (el->el_history.eventno == 0) { /* if really the current line */ - (void) wcsncpy(el->el_line.buffer, el->el_history.buf, - el->el_history.sz); - el->el_line.lastchar = el->el_line.buffer + - (el->el_history.last - el->el_history.buf); - -#ifdef KSHVI - if (el->el_map.type == MAP_VI) - el->el_line.cursor = el->el_line.buffer; - else -#endif /* KSHVI */ - el->el_line.cursor = el->el_line.lastchar; - - return CC_REFRESH; - } - if (el->el_history.ref == NULL) - return CC_ERROR; - - hp = HIST_FIRST(el); - - if (hp == NULL) - return CC_ERROR; - - for (h = 1; h < el->el_history.eventno; h++) - if ((hp = HIST_NEXT(el)) == NULL) - goto out; - - hlen = wcslen(hp) + 1; - blen = (size_t)(el->el_line.limit - el->el_line.buffer); - if (hlen > blen && !ch_enlargebufs(el, hlen)) - goto out; - - memcpy(el->el_line.buffer, hp, hlen * sizeof(*hp)); - el->el_line.lastchar = el->el_line.buffer + hlen - 1; - - if (el->el_line.lastchar > el->el_line.buffer - && el->el_line.lastchar[-1] == '\n') - el->el_line.lastchar--; - if (el->el_line.lastchar > el->el_line.buffer - && el->el_line.lastchar[-1] == ' ') - el->el_line.lastchar--; -#ifdef KSHVI - if (el->el_map.type == MAP_VI) - el->el_line.cursor = el->el_line.buffer; - else -#endif /* KSHVI */ - el->el_line.cursor = el->el_line.lastchar; - - return CC_REFRESH; -out: - el->el_history.eventno = h; - return CC_ERROR; - -} - - -/* hist_command() - * process a history command - */ -libedit_private int -hist_command(EditLine *el, int argc, const wchar_t **argv) -{ - const wchar_t *str; - int num; - HistEventW ev; - - if (el->el_history.ref == NULL) - return -1; - - if (argc == 1 || wcscmp(argv[1], L"list") == 0) { - size_t maxlen = 0; - char *buf = NULL; - int hno = 1; - /* List history entries */ - - for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) { - char *ptr = - ct_encode_string(str, &el->el_scratch); - size_t len = strlen(ptr); - if (len > 0 && ptr[len - 1] == '\n') - ptr[--len] = '\0'; - len = len * 4 + 1; - if (len >= maxlen) { - maxlen = len + 1024; - char *nbuf = el_realloc(buf, maxlen); - if (nbuf == NULL) { - el_free(buf); - return -1; - } - buf = nbuf; - } - strvis(buf, ptr, VIS_NL); - (void) fprintf(el->el_outfile, "%d\t%s\n", - hno++, buf); - } - el_free(buf); - return 0; - } - - if (argc != 3) - return -1; - - num = (int)wcstol(argv[2], NULL, 0); - - if (wcscmp(argv[1], L"size") == 0) - return history_w(el->el_history.ref, &ev, H_SETSIZE, num); - - if (wcscmp(argv[1], L"unique") == 0) - return history_w(el->el_history.ref, &ev, H_SETUNIQUE, num); - - return -1; -} - -/* hist_enlargebuf() - * Enlarge history buffer to specified value. Called from el_enlargebufs(). - * Return 0 for failure, 1 for success. - */ -libedit_private int -/*ARGSUSED*/ -hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) -{ - wchar_t *newbuf; - - newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf)); - if (!newbuf) - return 0; - - (void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf)); - - el->el_history.last = newbuf + - (el->el_history.last - el->el_history.buf); - el->el_history.buf = newbuf; - el->el_history.sz = newsz; - - return 1; -} - -libedit_private wchar_t * -hist_convert(EditLine *el, int fn, void *arg) -{ - HistEventW ev; - if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1) - return NULL; - return ct_decode_string((const char *)(const void *)ev.str, - &el->el_scratch); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/hist.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/hist.h deleted file mode 100644 index c58c5bf..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/hist.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: hist.h,v 1.22 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)hist.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.hist.c: History functions - */ -#ifndef _h_el_hist -#define _h_el_hist - -typedef int (*hist_fun_t)(void *, HistEventW *, int, ...); - -typedef struct el_history_t { - wchar_t *buf; /* The history buffer */ - size_t sz; /* Size of history buffer */ - wchar_t *last; /* The last character */ - int eventno; /* Event we are looking for */ - void *ref; /* Argument for history fcns */ - hist_fun_t fun; /* Event access */ - HistEventW ev; /* Event cookie */ -} el_history_t; - -#define HIST_FUN_INTERNAL(el, fn, arg) \ - ((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \ - fn, arg)) == -1) ? NULL : (el)->el_history.ev.str) -#define HIST_FUN(el, fn, arg) \ - (((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \ - HIST_FUN_INTERNAL(el, fn, arg)) - -#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL) -#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) -#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL) -#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL) -#define HIST_SET(el, num) HIST_FUN(el, H_SET, num) -#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) -#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname) -#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP fp) - -libedit_private int hist_init(EditLine *); -libedit_private void hist_end(EditLine *); -libedit_private el_action_t hist_get(EditLine *); -libedit_private int hist_set(EditLine *, hist_fun_t, void *); -libedit_private int hist_command(EditLine *, int, const wchar_t **); -libedit_private int hist_enlargebuf(EditLine *, size_t, size_t); -libedit_private wchar_t *hist_convert(EditLine *, int, void *); - -#endif /* _h_el_hist */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/histedit.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/histedit.h deleted file mode 100644 index 9ea7189..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/histedit.h +++ /dev/null @@ -1,313 +0,0 @@ -/* $NetBSD: histedit.h,v 1.56 2016/04/19 19:50:53 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)histedit.h 8.2 (Berkeley) 1/3/94 - */ - -/* - * histedit.h: Line editor and history interface. - */ -#ifndef _HISTEDIT_H_ -#define _HISTEDIT_H_ - -#define LIBEDIT_MAJOR 2 -#define LIBEDIT_MINOR 11 - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * ==== Editing ==== - */ - -typedef struct editline EditLine; - -/* - * For user-defined function interface - */ -typedef struct lineinfo { - const char *buffer; - const char *cursor; - const char *lastchar; -} LineInfo; - -/* - * EditLine editor function return codes. - * For user-defined function interface - */ -#define CC_NORM 0 -#define CC_NEWLINE 1 -#define CC_EOF 2 -#define CC_ARGHACK 3 -#define CC_REFRESH 4 -#define CC_CURSOR 5 -#define CC_ERROR 6 -#define CC_FATAL 7 -#define CC_REDISPLAY 8 -#define CC_REFRESH_BEEP 9 - -/* - * Initialization, cleanup, and resetting - */ -EditLine *el_init(const char *, FILE *, FILE *, FILE *); -EditLine *el_init_fd(const char *, FILE *, FILE *, FILE *, - int, int, int); -void el_end(EditLine *); -void el_reset(EditLine *); - -/* - * Get a line, a character or push a string back in the input queue - */ -const char *el_gets(EditLine *, int *); -int el_getc(EditLine *, char *); -void el_push(EditLine *, const char *); - -/* - * Beep! - */ -void el_beep(EditLine *); - -/* - * High level function internals control - * Parses argc, argv array and executes builtin editline commands - */ -int el_parse(EditLine *, int, const char **); - -/* - * Low level editline access functions - */ -int el_set(EditLine *, int, ...); -int el_get(EditLine *, int, ...); -unsigned char _el_fn_complete(EditLine *, int); - -/* - * el_set/el_get parameters - * - * When using el_wset/el_wget (as opposed to el_set/el_get): - * Char is wchar_t, otherwise it is char. - * prompt_func is el_wpfunc_t, otherwise it is el_pfunc_t . - - * Prompt function prototypes are: - * typedef char *(*el_pfunct_t) (EditLine *); - * typedef wchar_t *(*el_wpfunct_t) (EditLine *); - * - * For operations that support set or set/get, the argument types listed are for - * the "set" operation. For "get", each listed type must be a pointer. - * E.g. EL_EDITMODE takes an int when set, but an int* when get. - * - * Operations that only support "get" have the correct argument types listed. - */ -#define EL_PROMPT 0 /* , prompt_func); set/get */ -#define EL_TERMINAL 1 /* , const char *); set/get */ -#define EL_EDITOR 2 /* , const Char *); set/get */ -#define EL_SIGNAL 3 /* , int); set/get */ -#define EL_BIND 4 /* , const Char *, ..., NULL); set */ -#define EL_TELLTC 5 /* , const Char *, ..., NULL); set */ -#define EL_SETTC 6 /* , const Char *, ..., NULL); set */ -#define EL_ECHOTC 7 /* , const Char *, ..., NULL); set */ -#define EL_SETTY 8 /* , const Char *, ..., NULL); set */ -#define EL_ADDFN 9 /* , const Char *, const Char, set */ - /* el_func_t); */ -#define EL_HIST 10 /* , hist_fun_t, const void *); set */ -#define EL_EDITMODE 11 /* , int); set/get */ -#define EL_RPROMPT 12 /* , prompt_func); set/get */ -#define EL_GETCFN 13 /* , el_rfunc_t); set/get */ -#define EL_CLIENTDATA 14 /* , void *); set/get */ -#define EL_UNBUFFERED 15 /* , int); set/get */ -#define EL_PREP_TERM 16 /* , int); set */ -#define EL_GETTC 17 /* , const Char *, ..., NULL); get */ -#define EL_GETFP 18 /* , int, FILE **); get */ -#define EL_SETFP 19 /* , int, FILE *); set */ -#define EL_REFRESH 20 /* , void); set */ -#define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */ -#define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */ -#define EL_RESIZE 23 /* , el_zfunc_t, void *); set */ -#define EL_ALIAS_TEXT 24 /* , el_afunc_t, void *); set */ - -#define EL_BUILTIN_GETCFN (NULL) - -/* - * Source named file or $PWD/.editrc or $HOME/.editrc - */ -int el_source(EditLine *, const char *); - -/* - * Must be called when the terminal changes size; If EL_SIGNAL - * is set this is done automatically otherwise it is the responsibility - * of the application - */ -void el_resize(EditLine *); - -/* - * User-defined function interface. - */ -const LineInfo *el_line(EditLine *); -int el_insertstr(EditLine *, const char *); -void el_deletestr(EditLine *, int); - - -/* - * ==== History ==== - */ - -typedef struct history History; - -typedef struct HistEvent { - int num; - const char *str; -} HistEvent; - -/* - * History access functions. - */ -History * history_init(void); -void history_end(History *); - -int history(History *, HistEvent *, int, ...); - -#define H_FUNC 0 /* , UTSL */ -#define H_SETSIZE 1 /* , const int); */ -#define H_GETSIZE 2 /* , void); */ -#define H_FIRST 3 /* , void); */ -#define H_LAST 4 /* , void); */ -#define H_PREV 5 /* , void); */ -#define H_NEXT 6 /* , void); */ -#define H_CURR 8 /* , const int); */ -#define H_SET 7 /* , int); */ -#define H_ADD 9 /* , const wchar_t *); */ -#define H_ENTER 10 /* , const wchar_t *); */ -#define H_APPEND 11 /* , const wchar_t *); */ -#define H_END 12 /* , void); */ -#define H_NEXT_STR 13 /* , const wchar_t *); */ -#define H_PREV_STR 14 /* , const wchar_t *); */ -#define H_NEXT_EVENT 15 /* , const int); */ -#define H_PREV_EVENT 16 /* , const int); */ -#define H_LOAD 17 /* , const char *); */ -#define H_SAVE 18 /* , const char *); */ -#define H_CLEAR 19 /* , void); */ -#define H_SETUNIQUE 20 /* , int); */ -#define H_GETUNIQUE 21 /* , void); */ -#define H_DEL 22 /* , int); */ -#define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */ -#define H_DELDATA 24 /* , int, histdata_t *);*/ -#define H_REPLACE 25 /* , const char *, histdata_t); */ -#define H_SAVE_FP 26 /* , FILE *); */ - - - -/* - * ==== Tokenization ==== - */ - -typedef struct tokenizer Tokenizer; - -/* - * String tokenization functions, using simplified sh(1) quoting rules - */ -Tokenizer *tok_init(const char *); -void tok_end(Tokenizer *); -void tok_reset(Tokenizer *); -int tok_line(Tokenizer *, const LineInfo *, - int *, const char ***, int *, int *); -int tok_str(Tokenizer *, const char *, - int *, const char ***); - -/* - * Begin Wide Character Support - */ -#include -#include - -/* - * ==== Editing ==== - */ -typedef struct lineinfow { - const wchar_t *buffer; - const wchar_t *cursor; - const wchar_t *lastchar; -} LineInfoW; - -typedef int (*el_rfunc_t)(EditLine *, wchar_t *); - -const wchar_t *el_wgets(EditLine *, int *); -int el_wgetc(EditLine *, wchar_t *); -void el_wpush(EditLine *, const wchar_t *); - -int el_wparse(EditLine *, int, const wchar_t **); - -int el_wset(EditLine *, int, ...); -int el_wget(EditLine *, int, ...); - -int el_cursor(EditLine *, int); -const LineInfoW *el_wline(EditLine *); -int el_winsertstr(EditLine *, const wchar_t *); -#define el_wdeletestr el_deletestr - -/* - * ==== History ==== - */ -typedef struct histeventW { - int num; - const wchar_t *str; -} HistEventW; - -typedef struct historyW HistoryW; - -HistoryW * history_winit(void); -void history_wend(HistoryW *); - -int history_w(HistoryW *, HistEventW *, int, ...); - -/* - * ==== Tokenization ==== - */ -typedef struct tokenizerW TokenizerW; - -/* Wide character tokenizer support */ -TokenizerW *tok_winit(const wchar_t *); -void tok_wend(TokenizerW *); -void tok_wreset(TokenizerW *); -int tok_wline(TokenizerW *, const LineInfoW *, - int *, const wchar_t ***, int *, int *); -int tok_wstr(TokenizerW *, const wchar_t *, - int *, const wchar_t ***); - -#ifdef __cplusplus -} -#endif - -#endif /* _HISTEDIT_H_ */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/history.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/history.c deleted file mode 100644 index 5cf7e7b..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/history.c +++ /dev/null @@ -1,1160 +0,0 @@ -/* $NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#ifndef NARROWCHAR -#include "config.h" -#endif - -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * hist.c: TYPE(History) access functions - */ -#include -#include -#include -#include -#include - -static const char hist_cookie[] = "_HiStOrY_V2_\n"; - -#include "histedit.h" - - -#ifdef NARROWCHAR - -#define Char char -#define FUN(prefix, rest) prefix ## _ ## rest -#define FUNW(type) type -#define TYPE(type) type -#define STR(x) x - -#define Strlen(s) strlen(s) -#define Strdup(s) strdup(s) -#define Strcmp(d, s) strcmp(d, s) -#define Strncmp(d, s, n) strncmp(d, s, n) -#define Strncpy(d, s, n) strncpy(d, s, n) -#define Strncat(d, s, n) strncat(d, s, n) -#define ct_decode_string(s, b) (s) -#define ct_encode_string(s, b) (s) - -#else -#include "chartype.h" - -#define Char wchar_t -#define FUN(prefix, rest) prefix ## _w ## rest -#define FUNW(type) type ## _w -#define TYPE(type) type ## W -#define STR(x) L ## x - -#define Strlen(s) wcslen(s) -#define Strdup(s) wcsdup(s) -#define Strcmp(d, s) wcscmp(d, s) -#define Strncmp(d, s, n) wcsncmp(d, s, n) -#define Strncpy(d, s, n) wcsncpy(d, s, n) -#define Strncat(d, s, n) wcsncat(d, s, n) - -#endif - - -typedef int (*history_gfun_t)(void *, TYPE(HistEvent) *); -typedef int (*history_efun_t)(void *, TYPE(HistEvent) *, const Char *); -typedef void (*history_vfun_t)(void *, TYPE(HistEvent) *); -typedef int (*history_sfun_t)(void *, TYPE(HistEvent) *, const int); - -struct TYPE(history) { - void *h_ref; /* Argument for history fcns */ - int h_ent; /* Last entry point for history */ - history_gfun_t h_first; /* Get the first element */ - history_gfun_t h_next; /* Get the next element */ - history_gfun_t h_last; /* Get the last element */ - history_gfun_t h_prev; /* Get the previous element */ - history_gfun_t h_curr; /* Get the current element */ - history_sfun_t h_set; /* Set the current element */ - history_sfun_t h_del; /* Set the given element */ - history_vfun_t h_clear; /* Clear the history list */ - history_efun_t h_enter; /* Add an element */ - history_efun_t h_add; /* Append to an element */ -}; - -#define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev) -#define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev) -#define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev) -#define HLAST(h, ev) (*(h)->h_last)((h)->h_ref, ev) -#define HCURR(h, ev) (*(h)->h_curr)((h)->h_ref, ev) -#define HSET(h, ev, n) (*(h)->h_set)((h)->h_ref, ev, n) -#define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev) -#define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str) -#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) -#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n) - -#define h_strdup(a) Strdup(a) -#define h_malloc(a) malloc(a) -#define h_realloc(a, b) realloc((a), (b)) -#define h_free(a) free(a) - -typedef struct { - int num; - Char *str; -} HistEventPrivate; - - -static int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int); -static int history_getsize(TYPE(History) *, TYPE(HistEvent) *); -static int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int); -static int history_getunique(TYPE(History) *, TYPE(HistEvent) *); -static int history_set_fun(TYPE(History) *, TYPE(History) *); -static int history_load(TYPE(History) *, const char *); -static int history_save(TYPE(History) *, const char *); -static int history_save_fp(TYPE(History) *, FILE *); -static int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int); -static int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int); -static int history_next_string(TYPE(History) *, TYPE(HistEvent) *, - const Char *); -static int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, - const Char *); - - -/***********************************************************************/ - -/* - * Builtin- history implementation - */ -typedef struct hentry_t { - TYPE(HistEvent) ev; /* What we return */ - void *data; /* data */ - struct hentry_t *next; /* Next entry */ - struct hentry_t *prev; /* Previous entry */ -} hentry_t; - -typedef struct history_t { - hentry_t list; /* Fake list header element */ - hentry_t *cursor; /* Current element in the list */ - int max; /* Maximum number of events */ - int cur; /* Current number of events */ - int eventid; /* For generation of unique event id */ - int flags; /* TYPE(History) flags */ -#define H_UNIQUE 1 /* Store only unique elements */ -} history_t; - -static int history_def_next(void *, TYPE(HistEvent) *); -static int history_def_first(void *, TYPE(HistEvent) *); -static int history_def_prev(void *, TYPE(HistEvent) *); -static int history_def_last(void *, TYPE(HistEvent) *); -static int history_def_curr(void *, TYPE(HistEvent) *); -static int history_def_set(void *, TYPE(HistEvent) *, const int); -static void history_def_clear(void *, TYPE(HistEvent) *); -static int history_def_enter(void *, TYPE(HistEvent) *, const Char *); -static int history_def_add(void *, TYPE(HistEvent) *, const Char *); -static int history_def_del(void *, TYPE(HistEvent) *, const int); - -static int history_def_init(void **, TYPE(HistEvent) *, int); -static int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *); -static void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *); - -static int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **); -static int history_set_nth(void *, TYPE(HistEvent) *, int); - -#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num)) -#define history_def_getsize(p) (((history_t *)p)->cur) -#define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0) -#define history_def_setunique(p, uni) \ - if (uni) \ - (((history_t *)p)->flags) |= H_UNIQUE; \ - else \ - (((history_t *)p)->flags) &= ~H_UNIQUE - -#define he_strerror(code) he_errlist[code] -#define he_seterrev(evp, code) {\ - evp->num = code;\ - evp->str = he_strerror(code);\ - } - -/* error messages */ -static const Char *const he_errlist[] = { - STR("OK"), - STR("unknown error"), - STR("malloc() failed"), - STR("first event not found"), - STR("last event not found"), - STR("empty list"), - STR("no next event"), - STR("no previous event"), - STR("current event is invalid"), - STR("event not found"), - STR("can't read history from file"), - STR("can't write history"), - STR("required parameter(s) not supplied"), - STR("history size negative"), - STR("function not allowed with other history-functions-set the default"), - STR("bad parameters") -}; -/* error codes */ -#define _HE_OK 0 -#define _HE_UNKNOWN 1 -#define _HE_MALLOC_FAILED 2 -#define _HE_FIRST_NOTFOUND 3 -#define _HE_LAST_NOTFOUND 4 -#define _HE_EMPTY_LIST 5 -#define _HE_END_REACHED 6 -#define _HE_START_REACHED 7 -#define _HE_CURR_INVALID 8 -#define _HE_NOT_FOUND 9 -#define _HE_HIST_READ 10 -#define _HE_HIST_WRITE 11 -#define _HE_PARAM_MISSING 12 -#define _HE_SIZE_NEGATIVE 13 -#define _HE_NOT_ALLOWED 14 -#define _HE_BAD_PARAM 15 - -/* history_def_first(): - * Default function to return the first event in the history. - */ -static int -history_def_first(void *p, TYPE(HistEvent) *ev) -{ - history_t *h = (history_t *) p; - - h->cursor = h->list.next; - if (h->cursor != &h->list) - *ev = h->cursor->ev; - else { - he_seterrev(ev, _HE_FIRST_NOTFOUND); - return -1; - } - - return 0; -} - - -/* history_def_last(): - * Default function to return the last event in the history. - */ -static int -history_def_last(void *p, TYPE(HistEvent) *ev) -{ - history_t *h = (history_t *) p; - - h->cursor = h->list.prev; - if (h->cursor != &h->list) - *ev = h->cursor->ev; - else { - he_seterrev(ev, _HE_LAST_NOTFOUND); - return -1; - } - - return 0; -} - - -/* history_def_next(): - * Default function to return the next event in the history. - */ -static int -history_def_next(void *p, TYPE(HistEvent) *ev) -{ - history_t *h = (history_t *) p; - - if (h->cursor == &h->list) { - he_seterrev(ev, _HE_EMPTY_LIST); - return -1; - } - - if (h->cursor->next == &h->list) { - he_seterrev(ev, _HE_END_REACHED); - return -1; - } - - h->cursor = h->cursor->next; - *ev = h->cursor->ev; - - return 0; -} - - -/* history_def_prev(): - * Default function to return the previous event in the history. - */ -static int -history_def_prev(void *p, TYPE(HistEvent) *ev) -{ - history_t *h = (history_t *) p; - - if (h->cursor == &h->list) { - he_seterrev(ev, - (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST); - return -1; - } - - if (h->cursor->prev == &h->list) { - he_seterrev(ev, _HE_START_REACHED); - return -1; - } - - h->cursor = h->cursor->prev; - *ev = h->cursor->ev; - - return 0; -} - - -/* history_def_curr(): - * Default function to return the current event in the history. - */ -static int -history_def_curr(void *p, TYPE(HistEvent) *ev) -{ - history_t *h = (history_t *) p; - - if (h->cursor != &h->list) - *ev = h->cursor->ev; - else { - he_seterrev(ev, - (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST); - return -1; - } - - return 0; -} - - -/* history_def_set(): - * Default function to set the current event in the history to the - * given one. - */ -static int -history_def_set(void *p, TYPE(HistEvent) *ev, const int n) -{ - history_t *h = (history_t *) p; - - if (h->cur == 0) { - he_seterrev(ev, _HE_EMPTY_LIST); - return -1; - } - if (h->cursor == &h->list || h->cursor->ev.num != n) { - for (h->cursor = h->list.next; h->cursor != &h->list; - h->cursor = h->cursor->next) - if (h->cursor->ev.num == n) - break; - } - if (h->cursor == &h->list) { - he_seterrev(ev, _HE_NOT_FOUND); - return -1; - } - return 0; -} - - -/* history_set_nth(): - * Default function to set the current event in the history to the - * n-th one. - */ -static int -history_set_nth(void *p, TYPE(HistEvent) *ev, int n) -{ - history_t *h = (history_t *) p; - - if (h->cur == 0) { - he_seterrev(ev, _HE_EMPTY_LIST); - return -1; - } - for (h->cursor = h->list.prev; h->cursor != &h->list; - h->cursor = h->cursor->prev) - if (n-- <= 0) - break; - if (h->cursor == &h->list) { - he_seterrev(ev, _HE_NOT_FOUND); - return -1; - } - return 0; -} - - -/* history_def_add(): - * Append string to element - */ -static int -history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str) -{ - history_t *h = (history_t *) p; - size_t len; - Char *s; - HistEventPrivate *evp = (void *)&h->cursor->ev; - - if (h->cursor == &h->list) - return history_def_enter(p, ev, str); - len = Strlen(evp->str) + Strlen(str) + 1; - s = h_malloc(len * sizeof(*s)); - if (s == NULL) { - he_seterrev(ev, _HE_MALLOC_FAILED); - return -1; - } - (void) Strncpy(s, h->cursor->ev.str, len); - s[len - 1] = '\0'; - (void) Strncat(s, str, len - Strlen(s) - 1); - h_free(evp->str); - evp->str = s; - *ev = h->cursor->ev; - return 0; -} - - -static int -history_deldata_nth(history_t *h, TYPE(HistEvent) *ev, - int num, void **data) -{ - if (history_set_nth(h, ev, num) != 0) - return -1; - /* magic value to skip delete (just set to n-th history) */ - if (data == (void **)-1) - return 0; - ev->str = Strdup(h->cursor->ev.str); - ev->num = h->cursor->ev.num; - if (data) - *data = h->cursor->data; - history_def_delete(h, ev, h->cursor); - return 0; -} - - -/* history_def_del(): - * Delete element hp of the h list - */ -/* ARGSUSED */ -static int -history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)), - const int num) -{ - history_t *h = (history_t *) p; - if (history_def_set(h, ev, num) != 0) - return -1; - ev->str = Strdup(h->cursor->ev.str); - ev->num = h->cursor->ev.num; - history_def_delete(h, ev, h->cursor); - return 0; -} - - -/* history_def_delete(): - * Delete element hp of the h list - */ -/* ARGSUSED */ -static void -history_def_delete(history_t *h, - TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp) -{ - HistEventPrivate *evp = (void *)&hp->ev; - if (hp == &h->list) - abort(); - if (h->cursor == hp) { - h->cursor = hp->prev; - if (h->cursor == &h->list) - h->cursor = hp->next; - } - hp->prev->next = hp->next; - hp->next->prev = hp->prev; - h_free(evp->str); - h_free(hp); - h->cur--; -} - - -/* history_def_insert(): - * Insert element with string str in the h list - */ -static int -history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str) -{ - hentry_t *c; - - c = h_malloc(sizeof(*c)); - if (c == NULL) - goto oomem; - if ((c->ev.str = h_strdup(str)) == NULL) { - h_free(c); - goto oomem; - } - c->data = NULL; - c->ev.num = ++h->eventid; - c->next = h->list.next; - c->prev = &h->list; - h->list.next->prev = c; - h->list.next = c; - h->cur++; - h->cursor = c; - - *ev = c->ev; - return 0; -oomem: - he_seterrev(ev, _HE_MALLOC_FAILED); - return -1; -} - - -/* history_def_enter(): - * Default function to enter an item in the history - */ -static int -history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str) -{ - history_t *h = (history_t *) p; - - if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list && - Strcmp(h->list.next->ev.str, str) == 0) - return 0; - - if (history_def_insert(h, ev, str) == -1) - return -1; /* error, keep error message */ - - /* - * Always keep at least one entry. - * This way we don't have to check for the empty list. - */ - while (h->cur > h->max && h->cur > 0) - history_def_delete(h, ev, h->list.prev); - - return 1; -} - - -/* history_def_init(): - * Default history initialization function - */ -/* ARGSUSED */ -static int -history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n) -{ - history_t *h = (history_t *) h_malloc(sizeof(*h)); - if (h == NULL) - return -1; - - if (n <= 0) - n = 0; - h->eventid = 0; - h->cur = 0; - h->max = n; - h->list.next = h->list.prev = &h->list; - h->list.ev.str = NULL; - h->list.ev.num = 0; - h->cursor = &h->list; - h->flags = 0; - *p = h; - return 0; -} - - -/* history_def_clear(): - * Default history cleanup function - */ -static void -history_def_clear(void *p, TYPE(HistEvent) *ev) -{ - history_t *h = (history_t *) p; - - while (h->list.prev != &h->list) - history_def_delete(h, ev, h->list.prev); - h->cursor = &h->list; - h->eventid = 0; - h->cur = 0; -} - - - - -/************************************************************************/ - -/* history_init(): - * Initialization function. - */ -TYPE(History) * -FUN(history,init)(void) -{ - TYPE(HistEvent) ev; - TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(*h)); - if (h == NULL) - return NULL; - - if (history_def_init(&h->h_ref, &ev, 0) == -1) { - h_free(h); - return NULL; - } - h->h_ent = -1; - h->h_next = history_def_next; - h->h_first = history_def_first; - h->h_last = history_def_last; - h->h_prev = history_def_prev; - h->h_curr = history_def_curr; - h->h_set = history_def_set; - h->h_clear = history_def_clear; - h->h_enter = history_def_enter; - h->h_add = history_def_add; - h->h_del = history_def_del; - - return h; -} - - -/* history_end(): - * clean up history; - */ -void -FUN(history,end)(TYPE(History) *h) -{ - TYPE(HistEvent) ev; - - if (h->h_next == history_def_next) - history_def_clear(h->h_ref, &ev); - h_free(h->h_ref); - h_free(h); -} - - - -/* history_setsize(): - * Set history number of events - */ -static int -history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num) -{ - - if (h->h_next != history_def_next) { - he_seterrev(ev, _HE_NOT_ALLOWED); - return -1; - } - if (num < 0) { - he_seterrev(ev, _HE_BAD_PARAM); - return -1; - } - history_def_setsize(h->h_ref, num); - return 0; -} - - -/* history_getsize(): - * Get number of events currently in history - */ -static int -history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev) -{ - if (h->h_next != history_def_next) { - he_seterrev(ev, _HE_NOT_ALLOWED); - return -1; - } - ev->num = history_def_getsize(h->h_ref); - if (ev->num < -1) { - he_seterrev(ev, _HE_SIZE_NEGATIVE); - return -1; - } - return 0; -} - - -/* history_setunique(): - * Set if adjacent equal events should not be entered in history. - */ -static int -history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni) -{ - - if (h->h_next != history_def_next) { - he_seterrev(ev, _HE_NOT_ALLOWED); - return -1; - } - history_def_setunique(h->h_ref, uni); - return 0; -} - - -/* history_getunique(): - * Get if adjacent equal events should not be entered in history. - */ -static int -history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev) -{ - if (h->h_next != history_def_next) { - he_seterrev(ev, _HE_NOT_ALLOWED); - return -1; - } - ev->num = history_def_getunique(h->h_ref); - return 0; -} - - -/* history_set_fun(): - * Set history functions - */ -static int -history_set_fun(TYPE(History) *h, TYPE(History) *nh) -{ - TYPE(HistEvent) ev; - - if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || - nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || - nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || - nh->h_del == NULL || nh->h_ref == NULL) { - if (h->h_next != history_def_next) { - if (history_def_init(&h->h_ref, &ev, 0) == -1) - return -1; - h->h_first = history_def_first; - h->h_next = history_def_next; - h->h_last = history_def_last; - h->h_prev = history_def_prev; - h->h_curr = history_def_curr; - h->h_set = history_def_set; - h->h_clear = history_def_clear; - h->h_enter = history_def_enter; - h->h_add = history_def_add; - h->h_del = history_def_del; - } - return -1; - } - if (h->h_next == history_def_next) - history_def_clear(h->h_ref, &ev); - - h->h_ent = -1; - h->h_first = nh->h_first; - h->h_next = nh->h_next; - h->h_last = nh->h_last; - h->h_prev = nh->h_prev; - h->h_curr = nh->h_curr; - h->h_set = nh->h_set; - h->h_clear = nh->h_clear; - h->h_enter = nh->h_enter; - h->h_add = nh->h_add; - h->h_del = nh->h_del; - - return 0; -} - - -/* history_load(): - * TYPE(History) load function - */ -static int -history_load(TYPE(History) *h, const char *fname) -{ - FILE *fp; - char *line; - size_t llen; - ssize_t sz; - size_t max_size; - char *ptr; - int i = -1; - TYPE(HistEvent) ev; -#ifndef NARROWCHAR - static ct_buffer_t conv; -#endif - - if ((fp = fopen(fname, "r")) == NULL) - return i; - - line = NULL; - llen = 0; - if ((sz = getline(&line, &llen, fp)) == -1) - goto done; - - if (strncmp(line, hist_cookie, (size_t)sz) != 0) - goto done; - - ptr = h_malloc((max_size = 1024) * sizeof(*ptr)); - if (ptr == NULL) - goto done; - for (i = 0; (sz = getline(&line, &llen, fp)) != -1; i++) { - if (sz > 0 && line[sz - 1] == '\n') - line[--sz] = '\0'; - if (max_size < (size_t)sz) { - char *nptr; - max_size = ((size_t)sz + 1024) & (size_t)~1023; - nptr = h_realloc(ptr, max_size * sizeof(*ptr)); - if (nptr == NULL) { - i = -1; - goto oomem; - } - ptr = nptr; - } - (void) strunvis(ptr, line); - if (HENTER(h, &ev, ct_decode_string(ptr, &conv)) == -1) { - i = -1; - goto oomem; - } - } -oomem: - h_free(ptr); -done: - free(line); - (void) fclose(fp); - return i; -} - - -/* history_save_fp(): - * TYPE(History) save function - */ -static int -history_save_fp(TYPE(History) *h, FILE *fp) -{ - TYPE(HistEvent) ev; - int i = -1, retval; - size_t len, max_size; - char *ptr; - const char *str; -#ifndef NARROWCHAR - static ct_buffer_t conv; -#endif - - if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) - goto done; - if (fputs(hist_cookie, fp) == EOF) - goto done; - ptr = h_malloc((max_size = 1024) * sizeof(*ptr)); - if (ptr == NULL) - goto done; - for (i = 0, retval = HLAST(h, &ev); - retval != -1; - retval = HPREV(h, &ev), i++) { - str = ct_encode_string(ev.str, &conv); - len = strlen(str) * 4 + 1; - if (len > max_size) { - char *nptr; - max_size = (len + 1024) & (size_t)~1023; - nptr = h_realloc(ptr, max_size * sizeof(*ptr)); - if (nptr == NULL) { - i = -1; - goto oomem; - } - ptr = nptr; - } - (void) strvis(ptr, str, VIS_WHITE); - (void) fprintf(fp, "%s\n", ptr); - } -oomem: - h_free(ptr); -done: - return i; -} - - -/* history_save(): - * History save function - */ -static int -history_save(TYPE(History) *h, const char *fname) -{ - FILE *fp; - int i; - - if ((fp = fopen(fname, "w")) == NULL) - return -1; - - i = history_save_fp(h, fp); - - (void) fclose(fp); - return i; -} - - -/* history_prev_event(): - * Find the previous event, with number given - */ -static int -history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num) -{ - int retval; - - for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) - if (ev->num == num) - return 0; - - he_seterrev(ev, _HE_NOT_FOUND); - return -1; -} - - -static int -history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d) -{ - int retval; - - for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) - if (ev->num == num) { - if (d) - *d = ((history_t *)h->h_ref)->cursor->data; - return 0; - } - - he_seterrev(ev, _HE_NOT_FOUND); - return -1; -} - - -/* history_next_event(): - * Find the next event, with number given - */ -static int -history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num) -{ - int retval; - - for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) - if (ev->num == num) - return 0; - - he_seterrev(ev, _HE_NOT_FOUND); - return -1; -} - - -/* history_prev_string(): - * Find the previous event beginning with string - */ -static int -history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) -{ - size_t len = Strlen(str); - int retval; - - for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) - if (Strncmp(str, ev->str, len) == 0) - return 0; - - he_seterrev(ev, _HE_NOT_FOUND); - return -1; -} - - -/* history_next_string(): - * Find the next event beginning with string - */ -static int -history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) -{ - size_t len = Strlen(str); - int retval; - - for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) - if (Strncmp(str, ev->str, len) == 0) - return 0; - - he_seterrev(ev, _HE_NOT_FOUND); - return -1; -} - - -/* history(): - * User interface to history functions. - */ -int -FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...) -{ - va_list va; - const Char *str; - int retval; - - va_start(va, fun); - - he_seterrev(ev, _HE_OK); - - switch (fun) { - case H_GETSIZE: - retval = history_getsize(h, ev); - break; - - case H_SETSIZE: - retval = history_setsize(h, ev, va_arg(va, int)); - break; - - case H_GETUNIQUE: - retval = history_getunique(h, ev); - break; - - case H_SETUNIQUE: - retval = history_setunique(h, ev, va_arg(va, int)); - break; - - case H_ADD: - str = va_arg(va, const Char *); - retval = HADD(h, ev, str); - break; - - case H_DEL: - retval = HDEL(h, ev, va_arg(va, const int)); - break; - - case H_ENTER: - str = va_arg(va, const Char *); - if ((retval = HENTER(h, ev, str)) != -1) - h->h_ent = ev->num; - break; - - case H_APPEND: - str = va_arg(va, const Char *); - if ((retval = HSET(h, ev, h->h_ent)) != -1) - retval = HADD(h, ev, str); - break; - - case H_FIRST: - retval = HFIRST(h, ev); - break; - - case H_NEXT: - retval = HNEXT(h, ev); - break; - - case H_LAST: - retval = HLAST(h, ev); - break; - - case H_PREV: - retval = HPREV(h, ev); - break; - - case H_CURR: - retval = HCURR(h, ev); - break; - - case H_SET: - retval = HSET(h, ev, va_arg(va, const int)); - break; - - case H_CLEAR: - HCLEAR(h, ev); - retval = 0; - break; - - case H_LOAD: - retval = history_load(h, va_arg(va, const char *)); - if (retval == -1) - he_seterrev(ev, _HE_HIST_READ); - break; - - case H_SAVE: - retval = history_save(h, va_arg(va, const char *)); - if (retval == -1) - he_seterrev(ev, _HE_HIST_WRITE); - break; - - case H_SAVE_FP: - retval = history_save_fp(h, va_arg(va, FILE *)); - if (retval == -1) - he_seterrev(ev, _HE_HIST_WRITE); - break; - - case H_PREV_EVENT: - retval = history_prev_event(h, ev, va_arg(va, int)); - break; - - case H_NEXT_EVENT: - retval = history_next_event(h, ev, va_arg(va, int)); - break; - - case H_PREV_STR: - retval = history_prev_string(h, ev, va_arg(va, const Char *)); - break; - - case H_NEXT_STR: - retval = history_next_string(h, ev, va_arg(va, const Char *)); - break; - - case H_FUNC: - { - TYPE(History) hf; - - hf.h_ref = va_arg(va, void *); - h->h_ent = -1; - hf.h_first = va_arg(va, history_gfun_t); - hf.h_next = va_arg(va, history_gfun_t); - hf.h_last = va_arg(va, history_gfun_t); - hf.h_prev = va_arg(va, history_gfun_t); - hf.h_curr = va_arg(va, history_gfun_t); - hf.h_set = va_arg(va, history_sfun_t); - hf.h_clear = va_arg(va, history_vfun_t); - hf.h_enter = va_arg(va, history_efun_t); - hf.h_add = va_arg(va, history_efun_t); - hf.h_del = va_arg(va, history_sfun_t); - - if ((retval = history_set_fun(h, &hf)) == -1) - he_seterrev(ev, _HE_PARAM_MISSING); - break; - } - - case H_END: - FUN(history,end)(h); - retval = 0; - break; - - case H_NEXT_EVDATA: - { - int num = va_arg(va, int); - void **d = va_arg(va, void **); - retval = history_next_evdata(h, ev, num, d); - break; - } - - case H_DELDATA: - { - int num = va_arg(va, int); - void **d = va_arg(va, void **); - retval = history_deldata_nth((history_t *)h->h_ref, ev, num, d); - break; - } - - case H_REPLACE: /* only use after H_NEXT_EVDATA */ - { - const Char *line = va_arg(va, const Char *); - void *d = va_arg(va, void *); - const Char *s; - if(!line || !(s = Strdup(line))) { - retval = -1; - break; - } - ((history_t *)h->h_ref)->cursor->ev.str = s; - ((history_t *)h->h_ref)->cursor->data = d; - retval = 0; - break; - } - - default: - retval = -1; - he_seterrev(ev, _HE_UNKNOWN); - break; - } - va_end(va); - return retval; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/historyn.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/historyn.c deleted file mode 100644 index 59130de..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/historyn.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "config.h" -#define NARROWCHAR -#include "history.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/keymacro.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/keymacro.c deleted file mode 100644 index 13d2089..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/keymacro.c +++ /dev/null @@ -1,669 +0,0 @@ -/* $NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * keymacro.c: This module contains the procedures for maintaining - * the extended-key map. - * - * An extended-key (key) is a sequence of keystrokes introduced - * with a sequence introducer and consisting of an arbitrary - * number of characters. This module maintains a map (the - * el->el_keymacro.map) - * to convert these extended-key sequences into input strs - * (XK_STR) or editor functions (XK_CMD). - * - * Warning: - * If key is a substr of some other keys, then the longer - * keys are lost!! That is, if the keys "abcd" and "abcef" - * are in el->el_keymacro.map, adding the key "abc" will cause - * the first two definitions to be lost. - * - * Restrictions: - * ------------- - * 1) It is not possible to have one key that is a - * substr of another. - */ -#include -#include - -#include "el.h" -#include "fcns.h" - -/* - * The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a - * linked list of these node elements - */ -struct keymacro_node_t { - wchar_t ch; /* single character of key */ - int type; /* node type */ - keymacro_value_t val; /* command code or pointer to str, */ - /* if this is a leaf */ - struct keymacro_node_t *next; /* ptr to next char of this key */ - struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/ -}; - -static int node_trav(EditLine *, keymacro_node_t *, wchar_t *, - keymacro_value_t *); -static int node__try(EditLine *, keymacro_node_t *, - const wchar_t *, keymacro_value_t *, int); -static keymacro_node_t *node__get(wint_t); -static void node__free(keymacro_node_t *); -static void node__put(EditLine *, keymacro_node_t *); -static int node__delete(EditLine *, keymacro_node_t **, - const wchar_t *); -static int node_lookup(EditLine *, const wchar_t *, - keymacro_node_t *, size_t); -static int node_enum(EditLine *, keymacro_node_t *, size_t); - -#define KEY_BUFSIZ EL_BUFSIZ - - -/* keymacro_init(): - * Initialize the key maps - */ -libedit_private int -keymacro_init(EditLine *el) -{ - - el->el_keymacro.buf = el_malloc(KEY_BUFSIZ * - sizeof(*el->el_keymacro.buf)); - if (el->el_keymacro.buf == NULL) - return -1; - el->el_keymacro.map = NULL; - keymacro_reset(el); - return 0; -} - -/* keymacro_end(): - * Free the key maps - */ -libedit_private void -keymacro_end(EditLine *el) -{ - - el_free(el->el_keymacro.buf); - el->el_keymacro.buf = NULL; - node__free(el->el_keymacro.map); -} - - -/* keymacro_map_cmd(): - * Associate cmd with a key value - */ -libedit_private keymacro_value_t * -keymacro_map_cmd(EditLine *el, int cmd) -{ - - el->el_keymacro.val.cmd = (el_action_t) cmd; - return &el->el_keymacro.val; -} - - -/* keymacro_map_str(): - * Associate str with a key value - */ -libedit_private keymacro_value_t * -keymacro_map_str(EditLine *el, wchar_t *str) -{ - - el->el_keymacro.val.str = str; - return &el->el_keymacro.val; -} - - -/* keymacro_reset(): - * Takes all nodes on el->el_keymacro.map and puts them on free list. - * Then initializes el->el_keymacro.map with arrow keys - * [Always bind the ansi arrow keys?] - */ -libedit_private void -keymacro_reset(EditLine *el) -{ - - node__put(el, el->el_keymacro.map); - el->el_keymacro.map = NULL; - return; -} - - -/* keymacro_get(): - * Calls the recursive function with entry point el->el_keymacro.map - * Looks up *ch in map and then reads characters until a - * complete match is found or a mismatch occurs. Returns the - * type of the match found (XK_STR or XK_CMD). - * Returns NULL in val.str and XK_STR for no match. - * Returns XK_NOD for end of file or read error. - * The last character read is returned in *ch. - */ -libedit_private int -keymacro_get(EditLine *el, wchar_t *ch, keymacro_value_t *val) -{ - - return node_trav(el, el->el_keymacro.map, ch, val); -} - - -/* keymacro_add(): - * Adds key to the el->el_keymacro.map and associates the value in - * val with it. If key is already is in el->el_keymacro.map, the new - * code is applied to the existing key. Ntype specifies if code is a - * command, an out str or a unix command. - */ -libedit_private void -keymacro_add(EditLine *el, const wchar_t *key, keymacro_value_t *val, - int ntype) -{ - - if (key[0] == '\0') { - (void) fprintf(el->el_errfile, - "keymacro_add: Null extended-key not allowed.\n"); - return; - } - if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) { - (void) fprintf(el->el_errfile, - "keymacro_add: sequence-lead-in command not allowed\n"); - return; - } - if (el->el_keymacro.map == NULL) - /* tree is initially empty. Set up new node to match key[0] */ - el->el_keymacro.map = node__get(key[0]); - /* it is properly initialized */ - - /* Now recurse through el->el_keymacro.map */ - (void) node__try(el, el->el_keymacro.map, key, val, ntype); - return; -} - - -/* keymacro_clear(): - * - */ -libedit_private void -keymacro_clear(EditLine *el, el_action_t *map, const wchar_t *in) -{ - if (*in > N_KEYS) /* can't be in the map */ - return; - if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) && - ((map == el->el_map.key && - el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) || - (map == el->el_map.alt && - el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN))) - (void) keymacro_delete(el, in); -} - - -/* keymacro_delete(): - * Delete the key and all longer keys staring with key, if - * they exists. - */ -libedit_private int -keymacro_delete(EditLine *el, const wchar_t *key) -{ - - if (key[0] == '\0') { - (void) fprintf(el->el_errfile, - "keymacro_delete: Null extended-key not allowed.\n"); - return -1; - } - if (el->el_keymacro.map == NULL) - return 0; - - (void) node__delete(el, &el->el_keymacro.map, key); - return 0; -} - - -/* keymacro_print(): - * Print the binding associated with key key. - * Print entire el->el_keymacro.map if null - */ -libedit_private void -keymacro_print(EditLine *el, const wchar_t *key) -{ - - /* do nothing if el->el_keymacro.map is empty and null key specified */ - if (el->el_keymacro.map == NULL && *key == 0) - return; - - el->el_keymacro.buf[0] = '"'; - if (node_lookup(el, key, el->el_keymacro.map, (size_t)1) <= -1) - /* key is not bound */ - (void) fprintf(el->el_errfile, "Unbound extended key \"%ls" - "\"\n", key); - return; -} - - -/* node_trav(): - * recursively traverses node in tree until match or mismatch is - * found. May read in more characters. - */ -static int -node_trav(EditLine *el, keymacro_node_t *ptr, wchar_t *ch, - keymacro_value_t *val) -{ - - if (ptr->ch == *ch) { - /* match found */ - if (ptr->next) { - /* key not complete so get next char */ - if (el_wgetc(el, ch) != 1) - return XK_NOD; - return node_trav(el, ptr->next, ch, val); - } else { - *val = ptr->val; - if (ptr->type != XK_CMD) - *ch = '\0'; - return ptr->type; - } - } else { - /* no match found here */ - if (ptr->sibling) { - /* try next sibling */ - return node_trav(el, ptr->sibling, ch, val); - } else { - /* no next sibling -- mismatch */ - val->str = NULL; - return XK_STR; - } - } -} - - -/* node__try(): - * Find a node that matches *str or allocate a new one - */ -static int -node__try(EditLine *el, keymacro_node_t *ptr, const wchar_t *str, - keymacro_value_t *val, int ntype) -{ - - if (ptr->ch != *str) { - keymacro_node_t *xm; - - for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) - if (xm->sibling->ch == *str) - break; - if (xm->sibling == NULL) - xm->sibling = node__get(*str); /* setup new node */ - ptr = xm->sibling; - } - if (*++str == '\0') { - /* we're there */ - if (ptr->next != NULL) { - node__put(el, ptr->next); - /* lose longer keys with this prefix */ - ptr->next = NULL; - } - switch (ptr->type) { - case XK_CMD: - case XK_NOD: - break; - case XK_STR: - if (ptr->val.str) - el_free(ptr->val.str); - break; - default: - EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", - ptr->type)); - break; - } - - switch (ptr->type = ntype) { - case XK_CMD: - ptr->val = *val; - break; - case XK_STR: - if ((ptr->val.str = wcsdup(val->str)) == NULL) - return -1; - break; - default: - EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); - break; - } - } else { - /* still more chars to go */ - if (ptr->next == NULL) - ptr->next = node__get(*str); /* setup new node */ - (void) node__try(el, ptr->next, str, val, ntype); - } - return 0; -} - - -/* node__delete(): - * Delete node that matches str - */ -static int -node__delete(EditLine *el, keymacro_node_t **inptr, const wchar_t *str) -{ - keymacro_node_t *ptr; - keymacro_node_t *prev_ptr = NULL; - - ptr = *inptr; - - if (ptr->ch != *str) { - keymacro_node_t *xm; - - for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) - if (xm->sibling->ch == *str) - break; - if (xm->sibling == NULL) - return 0; - prev_ptr = xm; - ptr = xm->sibling; - } - if (*++str == '\0') { - /* we're there */ - if (prev_ptr == NULL) - *inptr = ptr->sibling; - else - prev_ptr->sibling = ptr->sibling; - ptr->sibling = NULL; - node__put(el, ptr); - return 1; - } else if (ptr->next != NULL && - node__delete(el, &ptr->next, str) == 1) { - if (ptr->next != NULL) - return 0; - if (prev_ptr == NULL) - *inptr = ptr->sibling; - else - prev_ptr->sibling = ptr->sibling; - ptr->sibling = NULL; - node__put(el, ptr); - return 1; - } else { - return 0; - } -} - - -/* node__put(): - * Puts a tree of nodes onto free list using free(3). - */ -static void -node__put(EditLine *el, keymacro_node_t *ptr) -{ - if (ptr == NULL) - return; - - if (ptr->next != NULL) { - node__put(el, ptr->next); - ptr->next = NULL; - } - node__put(el, ptr->sibling); - - switch (ptr->type) { - case XK_CMD: - case XK_NOD: - break; - case XK_STR: - if (ptr->val.str != NULL) - el_free(ptr->val.str); - break; - default: - EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type)); - break; - } - el_free(ptr); -} - - -/* node__get(): - * Returns pointer to a keymacro_node_t for ch. - */ -static keymacro_node_t * -node__get(wint_t ch) -{ - keymacro_node_t *ptr; - - ptr = el_malloc(sizeof(*ptr)); - if (ptr == NULL) - return NULL; - ptr->ch = ch; - ptr->type = XK_NOD; - ptr->val.str = NULL; - ptr->next = NULL; - ptr->sibling = NULL; - return ptr; -} - -static void -node__free(keymacro_node_t *k) -{ - if (k == NULL) - return; - node__free(k->sibling); - node__free(k->next); - el_free(k); -} - -/* node_lookup(): - * look for the str starting at node ptr. - * Print if last node - */ -static int -node_lookup(EditLine *el, const wchar_t *str, keymacro_node_t *ptr, - size_t cnt) -{ - ssize_t used; - - if (ptr == NULL) - return -1; /* cannot have null ptr */ - - if (!str || *str == 0) { - /* no more chars in str. node_enum from here. */ - (void) node_enum(el, ptr, cnt); - return 0; - } else { - /* If match put this char into el->el_keymacro.buf. Recurse */ - if (ptr->ch == *str) { - /* match found */ - used = ct_visual_char(el->el_keymacro.buf + cnt, - KEY_BUFSIZ - cnt, ptr->ch); - if (used == -1) - return -1; /* ran out of buffer space */ - if (ptr->next != NULL) - /* not yet at leaf */ - return (node_lookup(el, str + 1, ptr->next, - (size_t)used + cnt)); - else { - /* next node is null so key should be complete */ - if (str[1] == 0) { - size_t px = cnt + (size_t)used; - el->el_keymacro.buf[px] = '"'; - el->el_keymacro.buf[px + 1] = '\0'; - keymacro_kprint(el, el->el_keymacro.buf, - &ptr->val, ptr->type); - return 0; - } else - return -1; - /* mismatch -- str still has chars */ - } - } else { - /* no match found try sibling */ - if (ptr->sibling) - return (node_lookup(el, str, ptr->sibling, - cnt)); - else - return -1; - } - } -} - - -/* node_enum(): - * Traverse the node printing the characters it is bound in buffer - */ -static int -node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt) -{ - ssize_t used; - - if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */ - el->el_keymacro.buf[++cnt] = '"'; - el->el_keymacro.buf[++cnt] = '\0'; - (void) fprintf(el->el_errfile, - "Some extended keys too long for internal print buffer"); - (void) fprintf(el->el_errfile, " \"%ls...\"\n", - el->el_keymacro.buf); - return 0; - } - if (ptr == NULL) { -#ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, - "node_enum: BUG!! Null ptr passed\n!"); -#endif - return -1; - } - /* put this char at end of str */ - used = ct_visual_char(el->el_keymacro.buf + cnt, KEY_BUFSIZ - cnt, - ptr->ch); - if (ptr->next == NULL) { - /* print this key and function */ - el->el_keymacro.buf[cnt + (size_t)used ] = '"'; - el->el_keymacro.buf[cnt + (size_t)used + 1] = '\0'; - keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type); - } else - (void) node_enum(el, ptr->next, cnt + (size_t)used); - - /* go to sibling if there is one */ - if (ptr->sibling) - (void) node_enum(el, ptr->sibling, cnt); - return 0; -} - - -/* keymacro_kprint(): - * Print the specified key and its associated - * function specified by val - */ -libedit_private void -keymacro_kprint(EditLine *el, const wchar_t *key, keymacro_value_t *val, - int ntype) -{ - el_bindings_t *fp; - char unparsbuf[EL_BUFSIZ]; - static const char fmt[] = "%-15s-> %s\n"; - - if (val != NULL) - switch (ntype) { - case XK_STR: - (void) keymacro__decode_str(val->str, unparsbuf, - sizeof(unparsbuf), - ntype == XK_STR ? "\"\"" : "[]"); - (void) fprintf(el->el_outfile, fmt, - ct_encode_string(key, &el->el_scratch), unparsbuf); - break; - case XK_CMD: - for (fp = el->el_map.help; fp->name; fp++) - if (val->cmd == fp->func) { - wcstombs(unparsbuf, fp->name, sizeof(unparsbuf)); - unparsbuf[sizeof(unparsbuf) -1] = '\0'; - (void) fprintf(el->el_outfile, fmt, - ct_encode_string(key, &el->el_scratch), unparsbuf); - break; - } -#ifdef DEBUG_KEY - if (fp->name == NULL) - (void) fprintf(el->el_outfile, - "BUG! Command not found.\n"); -#endif - - break; - default: - EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); - break; - } - else - (void) fprintf(el->el_outfile, fmt, ct_encode_string(key, - &el->el_scratch), "no input"); -} - - -#define ADDC(c) \ - if (b < eb) \ - *b++ = c; \ - else \ - b++ -/* keymacro__decode_str(): - * Make a printable version of the ey - */ -libedit_private size_t -keymacro__decode_str(const wchar_t *str, char *buf, size_t len, - const char *sep) -{ - char *b = buf, *eb = b + len; - const wchar_t *p; - - b = buf; - if (sep[0] != '\0') { - ADDC(sep[0]); - } - if (*str == '\0') { - ADDC('^'); - ADDC('@'); - goto add_endsep; - } - for (p = str; *p != 0; p++) { - wchar_t dbuf[VISUAL_WIDTH_MAX]; - wchar_t *p2 = dbuf; - ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p); - while (l-- > 0) { - ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++); - if (n == -1) /* ran out of space */ - goto add_endsep; - else - b += n; - } - } -add_endsep: - if (sep[0] != '\0' && sep[1] != '\0') { - ADDC(sep[1]); - } - ADDC('\0'); - if ((size_t)(b - buf) >= len) - buf[len - 1] = '\0'; - return (size_t)(b - buf); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/keymacro.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/keymacro.h deleted file mode 100644 index 0653bbe..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/keymacro.h +++ /dev/null @@ -1,76 +0,0 @@ -/* $NetBSD: keymacro.h,v 1.6 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)key.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.keymacro.h: Key macro header - */ -#ifndef _h_el_keymacro -#define _h_el_keymacro - -typedef union keymacro_value_t { - el_action_t cmd; /* If it is a command the # */ - wchar_t *str; /* If it is a string... */ -} keymacro_value_t; - -typedef struct keymacro_node_t keymacro_node_t; - -typedef struct el_keymacro_t { - wchar_t *buf; /* Key print buffer */ - keymacro_node_t *map; /* Key map */ - keymacro_value_t val; /* Local conversion buffer */ -} el_keymacro_t; - -#define XK_CMD 0 -#define XK_STR 1 -#define XK_NOD 2 - -libedit_private int keymacro_init(EditLine *); -libedit_private void keymacro_end(EditLine *); -libedit_private keymacro_value_t *keymacro_map_cmd(EditLine *, int); -libedit_private keymacro_value_t *keymacro_map_str(EditLine *, wchar_t *); -libedit_private void keymacro_reset(EditLine *); -libedit_private int keymacro_get(EditLine *, wchar_t *, keymacro_value_t *); -libedit_private void keymacro_add(EditLine *, const wchar_t *, - keymacro_value_t *, int); -libedit_private void keymacro_clear(EditLine *, el_action_t *, const wchar_t *); -libedit_private int keymacro_delete(EditLine *, const wchar_t *); -libedit_private void keymacro_print(EditLine *, const wchar_t *); -libedit_private void keymacro_kprint(EditLine *, const wchar_t *, - keymacro_value_t *, int); -libedit_private size_t keymacro__decode_str(const wchar_t *, char *, size_t, - const char *); - -#endif /* _h_el_keymacro */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/common.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/common.h deleted file mode 100644 index a4e83fa..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/common.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Automatically generated file, do not edit */ -#ifndef _h_common_c -#define _h_common_c -libedit_private el_action_t ed_end_of_file (EditLine *, wint_t); -libedit_private el_action_t ed_insert (EditLine *, wint_t); -libedit_private el_action_t ed_delete_prev_word (EditLine *, wint_t); -libedit_private el_action_t ed_delete_next_char (EditLine *, wint_t); -libedit_private el_action_t ed_kill_line (EditLine *, wint_t); -libedit_private el_action_t ed_move_to_end (EditLine *, wint_t); -libedit_private el_action_t ed_move_to_beg (EditLine *, wint_t); -libedit_private el_action_t ed_transpose_chars (EditLine *, wint_t); -libedit_private el_action_t ed_next_char (EditLine *, wint_t); -libedit_private el_action_t ed_prev_word (EditLine *, wint_t); -libedit_private el_action_t ed_prev_char (EditLine *, wint_t); -libedit_private el_action_t ed_quoted_insert (EditLine *, wint_t); -libedit_private el_action_t ed_digit (EditLine *, wint_t); -libedit_private el_action_t ed_argument_digit (EditLine *, wint_t); -libedit_private el_action_t ed_unassigned (EditLine *, wint_t); -libedit_private el_action_t ed_ignore (EditLine *, wint_t); -libedit_private el_action_t ed_newline (EditLine *, wint_t); -libedit_private el_action_t ed_delete_prev_char (EditLine *, wint_t); -libedit_private el_action_t ed_clear_screen (EditLine *, wint_t); -libedit_private el_action_t ed_redisplay (EditLine *, wint_t); -libedit_private el_action_t ed_start_over (EditLine *, wint_t); -libedit_private el_action_t ed_sequence_lead_in (EditLine *, wint_t); -libedit_private el_action_t ed_prev_history (EditLine *, wint_t); -libedit_private el_action_t ed_next_history (EditLine *, wint_t); -libedit_private el_action_t ed_search_prev_history (EditLine *, wint_t); -libedit_private el_action_t ed_search_next_history (EditLine *, wint_t); -libedit_private el_action_t ed_prev_line (EditLine *, wint_t); -libedit_private el_action_t ed_next_line (EditLine *, wint_t); -libedit_private el_action_t ed_command (EditLine *, wint_t); -#endif /* _h_common_c */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/config.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/config.h deleted file mode 100644 index f4c2ee5..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/config.h +++ /dev/null @@ -1,285 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if the `closedir' function returns void instead of `int'. */ -/* #undef CLOSEDIR_VOID */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_CURSES_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#define HAVE_DIRENT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `endpwent' function. */ -#define HAVE_ENDPWENT 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `fgetln' function. */ -/* #undef HAVE_FGETLN */ - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the `getline' function. */ -#define HAVE_GETLINE 1 - -/* Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1 - versions. */ -/* #undef HAVE_GETPW_R_DRAFT */ - -/* Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1 - compatible. */ -#define HAVE_GETPW_R_POSIX 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `isascii' function. */ -#define HAVE_ISASCII 1 - -/* Define to 1 if you have the `issetugid' function. */ -/* #undef HAVE_ISSETUGID */ - -/* Define to 1 if you have the `curses' library (-lcurses). */ -/* #undef HAVE_LIBCURSES */ - -/* Define to 1 if you have the `ncurses' library (-lncurses). */ -#define HAVE_LIBNCURSES 1 - -/* Define to 1 if you have the `termcap' library (-ltermcap). */ -/* #undef HAVE_LIBTERMCAP */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the `memchr' function. */ -#define HAVE_MEMCHR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NCURSES_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the `regcomp' function. */ -#define HAVE_REGCOMP 1 - -/* Define to 1 if you have the `re_comp' function. */ -#define HAVE_RE_COMP 1 - -/* Define to 1 if you have the `secure_getenv' function. */ -/* #undef HAVE_SECURE_GETENV */ - -/* Define to 1 if `stat' has the bug that it succeeds when given the - zero-length file name argument. */ -/* #undef HAVE_STAT_EMPTY_STRING_BUG */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strchr' function. */ -#define HAVE_STRCHR 1 - -/* Define to 1 if you have the `strcspn' function. */ -#define HAVE_STRCSPN 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcat' function. */ -/* #undef HAVE_STRLCAT */ - -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - -/* Define to 1 if you have the `strrchr' function. */ -#define HAVE_STRRCHR 1 - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the `strtol' function. */ -#define HAVE_STRTOL 1 - -/* Define to 1 if struct dirent has member d_namlen */ -/* #undef HAVE_STRUCT_DIRENT_D_NAMLEN */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_CDEFS_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TERMCAP_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TERM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `unvis' function. */ -/* #undef HAVE_UNVIS */ - -/* Define to 1 if the system has the type `u_int32_t'. */ -#define HAVE_U_INT32_T 1 - -/* Define to 1 if you have the `vfork' function. */ -#define HAVE_VFORK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_VFORK_H */ - -/* Define to 1 if you have the `vis' function. */ -/* #undef HAVE_VIS */ - -/* Define to 1 if you have the `wcsdup' function. */ -#define HAVE_WCSDUP 1 - -/* Define to 1 if `fork' works. */ -#define HAVE_WORKING_FORK 1 - -/* Define to 1 if `vfork' works. */ -#define HAVE_WORKING_VFORK 1 - -/* Define to 1 if you have the `__secure_getenv' function. */ -/* #undef HAVE___SECURE_GETENV */ - -/* Define to 1 if `lstat' dereferences a symlink specified with a trailing - slash. */ -#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* Name of package */ -#define PACKAGE "libedit-20180802" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "libedit" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libedit 3.1" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "libedit-20180802" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "3.1" - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Version number of package */ -#define VERSION "3.1" - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `int' if does not define. */ -/* #undef pid_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define as `fork' if `vfork' does not work. */ -/* #undef vfork */ - - -#include "sys.h" -#define SCCSID -/* #undef LIBC_SCCS */ -#define lint - diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/emacs.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/emacs.h deleted file mode 100644 index 6e37261..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/emacs.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Automatically generated file, do not edit */ -#ifndef _h_emacs_c -#define _h_emacs_c -libedit_private el_action_t em_delete_or_list (EditLine *, wint_t); -libedit_private el_action_t em_delete_next_word (EditLine *, wint_t); -libedit_private el_action_t em_yank (EditLine *, wint_t); -libedit_private el_action_t em_kill_line (EditLine *, wint_t); -libedit_private el_action_t em_kill_region (EditLine *, wint_t); -libedit_private el_action_t em_copy_region (EditLine *, wint_t); -libedit_private el_action_t em_gosmacs_transpose (EditLine *, wint_t); -libedit_private el_action_t em_next_word (EditLine *, wint_t); -libedit_private el_action_t em_upper_case (EditLine *, wint_t); -libedit_private el_action_t em_capitol_case (EditLine *, wint_t); -libedit_private el_action_t em_lower_case (EditLine *, wint_t); -libedit_private el_action_t em_set_mark (EditLine *, wint_t); -libedit_private el_action_t em_exchange_mark (EditLine *, wint_t); -libedit_private el_action_t em_universal_argument (EditLine *, wint_t); -libedit_private el_action_t em_meta_next (EditLine *, wint_t); -libedit_private el_action_t em_toggle_overwrite (EditLine *, wint_t); -libedit_private el_action_t em_copy_prev_word (EditLine *, wint_t); -libedit_private el_action_t em_inc_search_next (EditLine *, wint_t); -libedit_private el_action_t em_inc_search_prev (EditLine *, wint_t); -libedit_private el_action_t em_delete_prev_char (EditLine *, wint_t); -#endif /* _h_emacs_c */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/fcns.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/fcns.h deleted file mode 100644 index 5ac2912..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/fcns.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Automatically generated file, do not edit */ -#define ED_ARGUMENT_DIGIT 0 -#define ED_CLEAR_SCREEN 1 -#define ED_COMMAND 2 -#define ED_DELETE_NEXT_CHAR 3 -#define ED_DELETE_PREV_CHAR 4 -#define ED_DELETE_PREV_WORD 5 -#define ED_DIGIT 6 -#define ED_END_OF_FILE 7 -#define ED_IGNORE 8 -#define ED_INSERT 9 -#define ED_KILL_LINE 10 -#define ED_MOVE_TO_BEG 11 -#define ED_MOVE_TO_END 12 -#define ED_NEWLINE 13 -#define ED_NEXT_CHAR 14 -#define ED_NEXT_HISTORY 15 -#define ED_NEXT_LINE 16 -#define ED_PREV_CHAR 17 -#define ED_PREV_HISTORY 18 -#define ED_PREV_LINE 19 -#define ED_PREV_WORD 20 -#define ED_QUOTED_INSERT 21 -#define ED_REDISPLAY 22 -#define ED_SEARCH_NEXT_HISTORY 23 -#define ED_SEARCH_PREV_HISTORY 24 -#define ED_SEQUENCE_LEAD_IN 25 -#define ED_START_OVER 26 -#define ED_TRANSPOSE_CHARS 27 -#define ED_UNASSIGNED 28 -#define EM_CAPITOL_CASE 29 -#define EM_COPY_PREV_WORD 30 -#define EM_COPY_REGION 31 -#define EM_DELETE_NEXT_WORD 32 -#define EM_DELETE_OR_LIST 33 -#define EM_DELETE_PREV_CHAR 34 -#define EM_EXCHANGE_MARK 35 -#define EM_GOSMACS_TRANSPOSE 36 -#define EM_INC_SEARCH_NEXT 37 -#define EM_INC_SEARCH_PREV 38 -#define EM_KILL_LINE 39 -#define EM_KILL_REGION 40 -#define EM_LOWER_CASE 41 -#define EM_META_NEXT 42 -#define EM_NEXT_WORD 43 -#define EM_SET_MARK 44 -#define EM_TOGGLE_OVERWRITE 45 -#define EM_UNIVERSAL_ARGUMENT 46 -#define EM_UPPER_CASE 47 -#define EM_YANK 48 -#define VI_ADD 49 -#define VI_ADD_AT_EOL 50 -#define VI_ALIAS 51 -#define VI_CHANGE_CASE 52 -#define VI_CHANGE_META 53 -#define VI_CHANGE_TO_EOL 54 -#define VI_COMMAND_MODE 55 -#define VI_COMMENT_OUT 56 -#define VI_DELETE_META 57 -#define VI_DELETE_PREV_CHAR 58 -#define VI_END_BIG_WORD 59 -#define VI_END_WORD 60 -#define VI_HISTEDIT 61 -#define VI_HISTORY_WORD 62 -#define VI_INSERT 63 -#define VI_INSERT_AT_BOL 64 -#define VI_KILL_LINE_PREV 65 -#define VI_LIST_OR_EOF 66 -#define VI_MATCH 67 -#define VI_NEXT_BIG_WORD 68 -#define VI_NEXT_CHAR 69 -#define VI_NEXT_WORD 70 -#define VI_PASTE_NEXT 71 -#define VI_PASTE_PREV 72 -#define VI_PREV_BIG_WORD 73 -#define VI_PREV_CHAR 74 -#define VI_PREV_WORD 75 -#define VI_REDO 76 -#define VI_REPEAT_NEXT_CHAR 77 -#define VI_REPEAT_PREV_CHAR 78 -#define VI_REPEAT_SEARCH_NEXT 79 -#define VI_REPEAT_SEARCH_PREV 80 -#define VI_REPLACE_CHAR 81 -#define VI_REPLACE_MODE 82 -#define VI_SEARCH_NEXT 83 -#define VI_SEARCH_PREV 84 -#define VI_SUBSTITUTE_CHAR 85 -#define VI_SUBSTITUTE_LINE 86 -#define VI_TO_COLUMN 87 -#define VI_TO_HISTORY_LINE 88 -#define VI_TO_NEXT_CHAR 89 -#define VI_TO_PREV_CHAR 90 -#define VI_UNDO 91 -#define VI_UNDO_LINE 92 -#define VI_YANK 93 -#define VI_YANK_END 94 -#define VI_ZERO 95 -#define EL_NUM_FCNS 96 diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/func.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/func.h deleted file mode 100644 index dfb93b2..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/func.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Automatically generated file, do not edit */ -static const el_func_t el_func[] = { - ed_argument_digit, ed_clear_screen, - ed_command, ed_delete_next_char, - ed_delete_prev_char, ed_delete_prev_word, - ed_digit, ed_end_of_file, - ed_ignore, ed_insert, - ed_kill_line, ed_move_to_beg, - ed_move_to_end, ed_newline, - ed_next_char, ed_next_history, - ed_next_line, ed_prev_char, - ed_prev_history, ed_prev_line, - ed_prev_word, ed_quoted_insert, - ed_redisplay, ed_search_next_history, - ed_search_prev_history, ed_sequence_lead_in, - ed_start_over, ed_transpose_chars, - ed_unassigned, em_capitol_case, - em_copy_prev_word, em_copy_region, - em_delete_next_word, em_delete_or_list, - em_delete_prev_char, em_exchange_mark, - em_gosmacs_transpose, em_inc_search_next, - em_inc_search_prev, em_kill_line, - em_kill_region, em_lower_case, - em_meta_next, em_next_word, - em_set_mark, em_toggle_overwrite, - em_universal_argument, em_upper_case, - em_yank, vi_add, - vi_add_at_eol, vi_alias, - vi_change_case, vi_change_meta, - vi_change_to_eol, vi_command_mode, - vi_comment_out, vi_delete_meta, - vi_delete_prev_char, vi_end_big_word, - vi_end_word, vi_histedit, - vi_history_word, vi_insert, - vi_insert_at_bol, vi_kill_line_prev, - vi_list_or_eof, vi_match, - vi_next_big_word, vi_next_char, - vi_next_word, vi_paste_next, - vi_paste_prev, vi_prev_big_word, - vi_prev_char, vi_prev_word, - vi_redo, vi_repeat_next_char, - vi_repeat_prev_char, vi_repeat_search_next, - vi_repeat_search_prev, vi_replace_char, - vi_replace_mode, vi_search_next, - vi_search_prev, vi_substitute_char, - vi_substitute_line, vi_to_column, - vi_to_history_line, vi_to_next_char, - vi_to_prev_char, vi_undo, - vi_undo_line, vi_yank, - vi_yank_end, vi_zero, -}; diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/help.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/help.h deleted file mode 100644 index 0fd61ae..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/help.h +++ /dev/null @@ -1,195 +0,0 @@ -/* Automatically generated file, do not edit */ -static const struct el_bindings_t el_func_help[] = { - { L"vi-paste-next", VI_PASTE_NEXT, - L"Vi paste previous deletion to the right of the cursor" }, - { L"vi-paste-prev", VI_PASTE_PREV, - L"Vi paste previous deletion to the left of the cursor" }, - { L"vi-prev-big-word", VI_PREV_BIG_WORD, - L"Vi move to the previous space delimited word" }, - { L"vi-prev-word", VI_PREV_WORD, - L"Vi move to the previous word" }, - { L"vi-next-big-word", VI_NEXT_BIG_WORD, - L"Vi move to the next space delimited word" }, - { L"vi-next-word", VI_NEXT_WORD, - L"Vi move to the next word" }, - { L"vi-change-case", VI_CHANGE_CASE, - L"Vi change case of character under the cursor and advance one character" }, - { L"vi-change-meta", VI_CHANGE_META, - L"Vi change prefix command" }, - { L"vi-insert-at-bol", VI_INSERT_AT_BOL, - L"Vi enter insert mode at the beginning of line" }, - { L"vi-replace-char", VI_REPLACE_CHAR, - L"Vi replace character under the cursor with the next character typed" }, - { L"vi-replace-mode", VI_REPLACE_MODE, - L"Vi enter replace mode" }, - { L"vi-substitute-char", VI_SUBSTITUTE_CHAR, - L"Vi replace character under the cursor and enter insert mode" }, - { L"vi-substitute-line", VI_SUBSTITUTE_LINE, - L"Vi substitute entire line" }, - { L"vi-change-to-eol", VI_CHANGE_TO_EOL, - L"Vi change to end of line" }, - { L"vi-insert", VI_INSERT, - L"Vi enter insert mode" }, - { L"vi-add", VI_ADD, - L"Vi enter insert mode after the cursor" }, - { L"vi-add-at-eol", VI_ADD_AT_EOL, - L"Vi enter insert mode at end of line" }, - { L"vi-delete-meta", VI_DELETE_META, - L"Vi delete prefix command" }, - { L"vi-end-big-word", VI_END_BIG_WORD, - L"Vi move to the end of the current space delimited word" }, - { L"vi-end-word", VI_END_WORD, - L"Vi move to the end of the current word" }, - { L"vi-undo", VI_UNDO, - L"Vi undo last change" }, - { L"vi-command-mode", VI_COMMAND_MODE, - L"Vi enter command mode (use alternative key bindings)" }, - { L"vi-zero", VI_ZERO, - L"Vi move to the beginning of line" }, - { L"vi-delete-prev-char", VI_DELETE_PREV_CHAR, - L"Vi move to previous character (backspace)" }, - { L"vi-list-or-eof", VI_LIST_OR_EOF, - L"Vi list choices for completion or indicate end of file if empty line" }, - { L"vi-kill-line-prev", VI_KILL_LINE_PREV, - L"Vi cut from beginning of line to cursor" }, - { L"vi-search-prev", VI_SEARCH_PREV, - L"Vi search history previous" }, - { L"vi-search-next", VI_SEARCH_NEXT, - L"Vi search history next" }, - { L"vi-repeat-search-next", VI_REPEAT_SEARCH_NEXT, - L"Vi repeat current search in the same search direction" }, - { L"vi-repeat-search-prev", VI_REPEAT_SEARCH_PREV, - L"Vi repeat current search in the opposite search direction" }, - { L"vi-next-char", VI_NEXT_CHAR, - L"Vi move to the character specified next" }, - { L"vi-prev-char", VI_PREV_CHAR, - L"Vi move to the character specified previous" }, - { L"vi-to-next-char", VI_TO_NEXT_CHAR, - L"Vi move up to the character specified next" }, - { L"vi-to-prev-char", VI_TO_PREV_CHAR, - L"Vi move up to the character specified previous" }, - { L"vi-repeat-next-char", VI_REPEAT_NEXT_CHAR, - L"Vi repeat current character search in the same search direction" }, - { L"vi-repeat-prev-char", VI_REPEAT_PREV_CHAR, - L"Vi repeat current character search in the opposite search direction" }, - { L"vi-match", VI_MATCH, - L"Vi go to matching () {} or []" }, - { L"vi-undo-line", VI_UNDO_LINE, - L"Vi undo all changes to line" }, - { L"vi-to-column", VI_TO_COLUMN, - L"Vi go to specified column" }, - { L"vi-yank-end", VI_YANK_END, - L"Vi yank to end of line" }, - { L"vi-yank", VI_YANK, - L"Vi yank" }, - { L"vi-comment-out", VI_COMMENT_OUT, - L"Vi comment out current command" }, - { L"vi-alias", VI_ALIAS, - L"Vi include shell alias" }, - { L"vi-to-history-line", VI_TO_HISTORY_LINE, - L"Vi go to specified history file line." }, - { L"vi-histedit", VI_HISTEDIT, - L"Vi edit history line with vi" }, - { L"vi-history-word", VI_HISTORY_WORD, - L"Vi append word from previous input line" }, - { L"vi-redo", VI_REDO, - L"Vi redo last non-motion command" }, - { L"em-delete-or-list", EM_DELETE_OR_LIST, - L"Delete character under cursor or list completions if at end of line" }, - { L"em-delete-next-word", EM_DELETE_NEXT_WORD, - L"Cut from cursor to end of current word" }, - { L"em-yank", EM_YANK, - L"Paste cut buffer at cursor position" }, - { L"em-kill-line", EM_KILL_LINE, - L"Cut the entire line and save in cut buffer" }, - { L"em-kill-region", EM_KILL_REGION, - L"Cut area between mark and cursor and save in cut buffer" }, - { L"em-copy-region", EM_COPY_REGION, - L"Copy area between mark and cursor to cut buffer" }, - { L"em-gosmacs-transpose", EM_GOSMACS_TRANSPOSE, - L"Exchange the two characters before the cursor" }, - { L"em-next-word", EM_NEXT_WORD, - L"Move next to end of current word" }, - { L"em-upper-case", EM_UPPER_CASE, - L"Uppercase the characters from cursor to end of current word" }, - { L"em-capitol-case", EM_CAPITOL_CASE, - L"Capitalize the characters from cursor to end of current word" }, - { L"em-lower-case", EM_LOWER_CASE, - L"Lowercase the characters from cursor to end of current word" }, - { L"em-set-mark", EM_SET_MARK, - L"Set the mark at cursor" }, - { L"em-exchange-mark", EM_EXCHANGE_MARK, - L"Exchange the cursor and mark" }, - { L"em-universal-argument", EM_UNIVERSAL_ARGUMENT, - L"Universal argument (argument times 4)" }, - { L"em-meta-next", EM_META_NEXT, - L"Add 8th bit to next character typed" }, - { L"em-toggle-overwrite", EM_TOGGLE_OVERWRITE, - L"Switch from insert to overwrite mode or vice versa" }, - { L"em-copy-prev-word", EM_COPY_PREV_WORD, - L"Copy current word to cursor" }, - { L"em-inc-search-next", EM_INC_SEARCH_NEXT, - L"Emacs incremental next search" }, - { L"em-inc-search-prev", EM_INC_SEARCH_PREV, - L"Emacs incremental reverse search" }, - { L"em-delete-prev-char", EM_DELETE_PREV_CHAR, - L"Delete the character to the left of the cursor" }, - { L"ed-end-of-file", ED_END_OF_FILE, - L"Indicate end of file" }, - { L"ed-insert", ED_INSERT, - L"Add character to the line" }, - { L"ed-delete-prev-word", ED_DELETE_PREV_WORD, - L"Delete from beginning of current word to cursor" }, - { L"ed-delete-next-char", ED_DELETE_NEXT_CHAR, - L"Delete character under cursor" }, - { L"ed-kill-line", ED_KILL_LINE, - L"Cut to the end of line" }, - { L"ed-move-to-end", ED_MOVE_TO_END, - L"Move cursor to the end of line" }, - { L"ed-move-to-beg", ED_MOVE_TO_BEG, - L"Move cursor to the beginning of line" }, - { L"ed-transpose-chars", ED_TRANSPOSE_CHARS, - L"Exchange the character to the left of the cursor with the one under it" }, - { L"ed-next-char", ED_NEXT_CHAR, - L"Move to the right one character" }, - { L"ed-prev-word", ED_PREV_WORD, - L"Move to the beginning of the current word" }, - { L"ed-prev-char", ED_PREV_CHAR, - L"Move to the left one character" }, - { L"ed-quoted-insert", ED_QUOTED_INSERT, - L"Add the next character typed verbatim" }, - { L"ed-digit", ED_DIGIT, - L"Adds to argument or enters a digit" }, - { L"ed-argument-digit", ED_ARGUMENT_DIGIT, - L"Digit that starts argument" }, - { L"ed-unassigned", ED_UNASSIGNED, - L"Indicates unbound character" }, - { L"ed-ignore", ED_IGNORE, - L"Input characters that have no effect" }, - { L"ed-newline", ED_NEWLINE, - L"Execute command" }, - { L"ed-delete-prev-char", ED_DELETE_PREV_CHAR, - L"Delete the character to the left of the cursor" }, - { L"ed-clear-screen", ED_CLEAR_SCREEN, - L"Clear screen leaving current line at the top" }, - { L"ed-redisplay", ED_REDISPLAY, - L"Redisplay everything" }, - { L"ed-start-over", ED_START_OVER, - L"Erase current line and start from scratch" }, - { L"ed-sequence-lead-in", ED_SEQUENCE_LEAD_IN, - L"First character in a bound sequence" }, - { L"ed-prev-history", ED_PREV_HISTORY, - L"Move to the previous history line" }, - { L"ed-next-history", ED_NEXT_HISTORY, - L"Move to the next history line" }, - { L"ed-search-prev-history", ED_SEARCH_PREV_HISTORY, - L"Search previous in history for a line matching the current" }, - { L"ed-search-next-history", ED_SEARCH_NEXT_HISTORY, - L"Search next in history for a line matching the current" }, - { L"ed-prev-line", ED_PREV_LINE, - L"Move up one line" }, - { L"ed-next-line", ED_NEXT_LINE, - L"Move down one line" }, - { L"ed-command", ED_COMMAND, - L"Editline extended command" }, -}; diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/vi.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/vi.h deleted file mode 100644 index eb4eca9..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/linux-build/vi.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Automatically generated file, do not edit */ -#ifndef _h_vi_c -#define _h_vi_c -libedit_private el_action_t vi_paste_next (EditLine *, wint_t); -libedit_private el_action_t vi_paste_prev (EditLine *, wint_t); -libedit_private el_action_t vi_prev_big_word (EditLine *, wint_t); -libedit_private el_action_t vi_prev_word (EditLine *, wint_t); -libedit_private el_action_t vi_next_big_word (EditLine *, wint_t); -libedit_private el_action_t vi_next_word (EditLine *, wint_t); -libedit_private el_action_t vi_change_case (EditLine *, wint_t); -libedit_private el_action_t vi_change_meta (EditLine *, wint_t); -libedit_private el_action_t vi_insert_at_bol (EditLine *, wint_t); -libedit_private el_action_t vi_replace_char (EditLine *, wint_t); -libedit_private el_action_t vi_replace_mode (EditLine *, wint_t); -libedit_private el_action_t vi_substitute_char (EditLine *, wint_t); -libedit_private el_action_t vi_substitute_line (EditLine *, wint_t); -libedit_private el_action_t vi_change_to_eol (EditLine *, wint_t); -libedit_private el_action_t vi_insert (EditLine *, wint_t); -libedit_private el_action_t vi_add (EditLine *, wint_t); -libedit_private el_action_t vi_add_at_eol (EditLine *, wint_t); -libedit_private el_action_t vi_delete_meta (EditLine *, wint_t); -libedit_private el_action_t vi_end_big_word (EditLine *, wint_t); -libedit_private el_action_t vi_end_word (EditLine *, wint_t); -libedit_private el_action_t vi_undo (EditLine *, wint_t); -libedit_private el_action_t vi_command_mode (EditLine *, wint_t); -libedit_private el_action_t vi_zero (EditLine *, wint_t); -libedit_private el_action_t vi_delete_prev_char (EditLine *, wint_t); -libedit_private el_action_t vi_list_or_eof (EditLine *, wint_t); -libedit_private el_action_t vi_kill_line_prev (EditLine *, wint_t); -libedit_private el_action_t vi_search_prev (EditLine *, wint_t); -libedit_private el_action_t vi_search_next (EditLine *, wint_t); -libedit_private el_action_t vi_repeat_search_next (EditLine *, wint_t); -libedit_private el_action_t vi_repeat_search_prev (EditLine *, wint_t); -libedit_private el_action_t vi_next_char (EditLine *, wint_t); -libedit_private el_action_t vi_prev_char (EditLine *, wint_t); -libedit_private el_action_t vi_to_next_char (EditLine *, wint_t); -libedit_private el_action_t vi_to_prev_char (EditLine *, wint_t); -libedit_private el_action_t vi_repeat_next_char (EditLine *, wint_t); -libedit_private el_action_t vi_repeat_prev_char (EditLine *, wint_t); -libedit_private el_action_t vi_match (EditLine *, wint_t); -libedit_private el_action_t vi_undo_line (EditLine *, wint_t); -libedit_private el_action_t vi_to_column (EditLine *, wint_t); -libedit_private el_action_t vi_yank_end (EditLine *, wint_t); -libedit_private el_action_t vi_yank (EditLine *, wint_t); -libedit_private el_action_t vi_comment_out (EditLine *, wint_t); -libedit_private el_action_t vi_alias (EditLine *, wint_t); -libedit_private el_action_t vi_to_history_line (EditLine *, wint_t); -libedit_private el_action_t vi_histedit (EditLine *, wint_t); -libedit_private el_action_t vi_history_word (EditLine *, wint_t); -libedit_private el_action_t vi_redo (EditLine *, wint_t); -#endif /* _h_vi_c */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/map.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/map.c deleted file mode 100644 index f72d272..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/map.c +++ /dev/null @@ -1,1427 +0,0 @@ -/* $NetBSD: map.c,v 1.51 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: map.c,v 1.51 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * map.c: Editor function definitions - */ -#include -#include -#include - -#include "el.h" -#include "common.h" -#include "emacs.h" -#include "vi.h" -#include "fcns.h" -#include "func.h" -#include "help.h" -#include "parse.h" - -static void map_print_key(EditLine *, el_action_t *, const wchar_t *); -static void map_print_some_keys(EditLine *, el_action_t *, wint_t, wint_t); -static void map_print_all_keys(EditLine *); -static void map_init_nls(EditLine *); -static void map_init_meta(EditLine *); - -/* keymap tables ; should be N_KEYS*sizeof(KEYCMD) bytes long */ - - -static const el_action_t el_map_emacs[] = { - /* 0 */ EM_SET_MARK, /* ^@ */ - /* 1 */ ED_MOVE_TO_BEG, /* ^A */ - /* 2 */ ED_PREV_CHAR, /* ^B */ - /* 3 */ ED_IGNORE, /* ^C */ - /* 4 */ EM_DELETE_OR_LIST, /* ^D */ - /* 5 */ ED_MOVE_TO_END, /* ^E */ - /* 6 */ ED_NEXT_CHAR, /* ^F */ - /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ EM_DELETE_PREV_CHAR, /* ^H */ - /* 9 */ ED_UNASSIGNED, /* ^I */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_KILL_LINE, /* ^K */ - /* 12 */ ED_CLEAR_SCREEN, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_NEXT_HISTORY, /* ^N */ - /* 15 */ ED_IGNORE, /* ^O */ - /* 16 */ ED_PREV_HISTORY, /* ^P */ - /* 17 */ ED_IGNORE, /* ^Q */ - /* 18 */ ED_REDISPLAY, /* ^R */ - /* 19 */ ED_IGNORE, /* ^S */ - /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */ - /* 21 */ EM_KILL_LINE, /* ^U */ - /* 22 */ ED_QUOTED_INSERT, /* ^V */ - /* 23 */ EM_KILL_REGION, /* ^W */ - /* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */ - /* 25 */ EM_YANK, /* ^Y */ - /* 26 */ ED_IGNORE, /* ^Z */ - /* 27 */ EM_META_NEXT, /* ^[ */ - /* 28 */ ED_IGNORE, /* ^\ */ - /* 29 */ ED_IGNORE, /* ^] */ - /* 30 */ ED_UNASSIGNED, /* ^^ */ - /* 31 */ ED_UNASSIGNED, /* ^_ */ - /* 32 */ ED_INSERT, /* SPACE */ - /* 33 */ ED_INSERT, /* ! */ - /* 34 */ ED_INSERT, /* " */ - /* 35 */ ED_INSERT, /* # */ - /* 36 */ ED_INSERT, /* $ */ - /* 37 */ ED_INSERT, /* % */ - /* 38 */ ED_INSERT, /* & */ - /* 39 */ ED_INSERT, /* ' */ - /* 40 */ ED_INSERT, /* ( */ - /* 41 */ ED_INSERT, /* ) */ - /* 42 */ ED_INSERT, /* * */ - /* 43 */ ED_INSERT, /* + */ - /* 44 */ ED_INSERT, /* , */ - /* 45 */ ED_INSERT, /* - */ - /* 46 */ ED_INSERT, /* . */ - /* 47 */ ED_INSERT, /* / */ - /* 48 */ ED_DIGIT, /* 0 */ - /* 49 */ ED_DIGIT, /* 1 */ - /* 50 */ ED_DIGIT, /* 2 */ - /* 51 */ ED_DIGIT, /* 3 */ - /* 52 */ ED_DIGIT, /* 4 */ - /* 53 */ ED_DIGIT, /* 5 */ - /* 54 */ ED_DIGIT, /* 6 */ - /* 55 */ ED_DIGIT, /* 7 */ - /* 56 */ ED_DIGIT, /* 8 */ - /* 57 */ ED_DIGIT, /* 9 */ - /* 58 */ ED_INSERT, /* : */ - /* 59 */ ED_INSERT, /* ; */ - /* 60 */ ED_INSERT, /* < */ - /* 61 */ ED_INSERT, /* = */ - /* 62 */ ED_INSERT, /* > */ - /* 63 */ ED_INSERT, /* ? */ - /* 64 */ ED_INSERT, /* @ */ - /* 65 */ ED_INSERT, /* A */ - /* 66 */ ED_INSERT, /* B */ - /* 67 */ ED_INSERT, /* C */ - /* 68 */ ED_INSERT, /* D */ - /* 69 */ ED_INSERT, /* E */ - /* 70 */ ED_INSERT, /* F */ - /* 71 */ ED_INSERT, /* G */ - /* 72 */ ED_INSERT, /* H */ - /* 73 */ ED_INSERT, /* I */ - /* 74 */ ED_INSERT, /* J */ - /* 75 */ ED_INSERT, /* K */ - /* 76 */ ED_INSERT, /* L */ - /* 77 */ ED_INSERT, /* M */ - /* 78 */ ED_INSERT, /* N */ - /* 79 */ ED_INSERT, /* O */ - /* 80 */ ED_INSERT, /* P */ - /* 81 */ ED_INSERT, /* Q */ - /* 82 */ ED_INSERT, /* R */ - /* 83 */ ED_INSERT, /* S */ - /* 84 */ ED_INSERT, /* T */ - /* 85 */ ED_INSERT, /* U */ - /* 86 */ ED_INSERT, /* V */ - /* 87 */ ED_INSERT, /* W */ - /* 88 */ ED_INSERT, /* X */ - /* 89 */ ED_INSERT, /* Y */ - /* 90 */ ED_INSERT, /* Z */ - /* 91 */ ED_INSERT, /* [ */ - /* 92 */ ED_INSERT, /* \ */ - /* 93 */ ED_INSERT, /* ] */ - /* 94 */ ED_INSERT, /* ^ */ - /* 95 */ ED_INSERT, /* _ */ - /* 96 */ ED_INSERT, /* ` */ - /* 97 */ ED_INSERT, /* a */ - /* 98 */ ED_INSERT, /* b */ - /* 99 */ ED_INSERT, /* c */ - /* 100 */ ED_INSERT, /* d */ - /* 101 */ ED_INSERT, /* e */ - /* 102 */ ED_INSERT, /* f */ - /* 103 */ ED_INSERT, /* g */ - /* 104 */ ED_INSERT, /* h */ - /* 105 */ ED_INSERT, /* i */ - /* 106 */ ED_INSERT, /* j */ - /* 107 */ ED_INSERT, /* k */ - /* 108 */ ED_INSERT, /* l */ - /* 109 */ ED_INSERT, /* m */ - /* 110 */ ED_INSERT, /* n */ - /* 111 */ ED_INSERT, /* o */ - /* 112 */ ED_INSERT, /* p */ - /* 113 */ ED_INSERT, /* q */ - /* 114 */ ED_INSERT, /* r */ - /* 115 */ ED_INSERT, /* s */ - /* 116 */ ED_INSERT, /* t */ - /* 117 */ ED_INSERT, /* u */ - /* 118 */ ED_INSERT, /* v */ - /* 119 */ ED_INSERT, /* w */ - /* 120 */ ED_INSERT, /* x */ - /* 121 */ ED_INSERT, /* y */ - /* 122 */ ED_INSERT, /* z */ - /* 123 */ ED_INSERT, /* { */ - /* 124 */ ED_INSERT, /* | */ - /* 125 */ ED_INSERT, /* } */ - /* 126 */ ED_INSERT, /* ~ */ - /* 127 */ EM_DELETE_PREV_CHAR, /* ^? */ - /* 128 */ ED_UNASSIGNED, /* M-^@ */ - /* 129 */ ED_UNASSIGNED, /* M-^A */ - /* 130 */ ED_UNASSIGNED, /* M-^B */ - /* 131 */ ED_UNASSIGNED, /* M-^C */ - /* 132 */ ED_UNASSIGNED, /* M-^D */ - /* 133 */ ED_UNASSIGNED, /* M-^E */ - /* 134 */ ED_UNASSIGNED, /* M-^F */ - /* 135 */ ED_UNASSIGNED, /* M-^G */ - /* 136 */ ED_DELETE_PREV_WORD, /* M-^H */ - /* 137 */ ED_UNASSIGNED, /* M-^I */ - /* 138 */ ED_UNASSIGNED, /* M-^J */ - /* 139 */ ED_UNASSIGNED, /* M-^K */ - /* 140 */ ED_CLEAR_SCREEN, /* M-^L */ - /* 141 */ ED_UNASSIGNED, /* M-^M */ - /* 142 */ ED_UNASSIGNED, /* M-^N */ - /* 143 */ ED_UNASSIGNED, /* M-^O */ - /* 144 */ ED_UNASSIGNED, /* M-^P */ - /* 145 */ ED_UNASSIGNED, /* M-^Q */ - /* 146 */ ED_UNASSIGNED, /* M-^R */ - /* 147 */ ED_UNASSIGNED, /* M-^S */ - /* 148 */ ED_UNASSIGNED, /* M-^T */ - /* 149 */ ED_UNASSIGNED, /* M-^U */ - /* 150 */ ED_UNASSIGNED, /* M-^V */ - /* 151 */ ED_UNASSIGNED, /* M-^W */ - /* 152 */ ED_UNASSIGNED, /* M-^X */ - /* 153 */ ED_UNASSIGNED, /* M-^Y */ - /* 154 */ ED_UNASSIGNED, /* M-^Z */ - /* 155 */ ED_UNASSIGNED, /* M-^[ */ - /* 156 */ ED_UNASSIGNED, /* M-^\ */ - /* 157 */ ED_UNASSIGNED, /* M-^] */ - /* 158 */ ED_UNASSIGNED, /* M-^^ */ - /* 159 */ EM_COPY_PREV_WORD, /* M-^_ */ - /* 160 */ ED_UNASSIGNED, /* M-SPACE */ - /* 161 */ ED_UNASSIGNED, /* M-! */ - /* 162 */ ED_UNASSIGNED, /* M-" */ - /* 163 */ ED_UNASSIGNED, /* M-# */ - /* 164 */ ED_UNASSIGNED, /* M-$ */ - /* 165 */ ED_UNASSIGNED, /* M-% */ - /* 166 */ ED_UNASSIGNED, /* M-& */ - /* 167 */ ED_UNASSIGNED, /* M-' */ - /* 168 */ ED_UNASSIGNED, /* M-( */ - /* 169 */ ED_UNASSIGNED, /* M-) */ - /* 170 */ ED_UNASSIGNED, /* M-* */ - /* 171 */ ED_UNASSIGNED, /* M-+ */ - /* 172 */ ED_UNASSIGNED, /* M-, */ - /* 173 */ ED_UNASSIGNED, /* M-- */ - /* 174 */ ED_UNASSIGNED, /* M-. */ - /* 175 */ ED_UNASSIGNED, /* M-/ */ - /* 176 */ ED_ARGUMENT_DIGIT, /* M-0 */ - /* 177 */ ED_ARGUMENT_DIGIT, /* M-1 */ - /* 178 */ ED_ARGUMENT_DIGIT, /* M-2 */ - /* 179 */ ED_ARGUMENT_DIGIT, /* M-3 */ - /* 180 */ ED_ARGUMENT_DIGIT, /* M-4 */ - /* 181 */ ED_ARGUMENT_DIGIT, /* M-5 */ - /* 182 */ ED_ARGUMENT_DIGIT, /* M-6 */ - /* 183 */ ED_ARGUMENT_DIGIT, /* M-7 */ - /* 184 */ ED_ARGUMENT_DIGIT, /* M-8 */ - /* 185 */ ED_ARGUMENT_DIGIT, /* M-9 */ - /* 186 */ ED_UNASSIGNED, /* M-: */ - /* 187 */ ED_UNASSIGNED, /* M-; */ - /* 188 */ ED_UNASSIGNED, /* M-< */ - /* 189 */ ED_UNASSIGNED, /* M-= */ - /* 190 */ ED_UNASSIGNED, /* M-> */ - /* 191 */ ED_UNASSIGNED, /* M-? */ - /* 192 */ ED_UNASSIGNED, /* M-@ */ - /* 193 */ ED_UNASSIGNED, /* M-A */ - /* 194 */ ED_PREV_WORD, /* M-B */ - /* 195 */ EM_CAPITOL_CASE, /* M-C */ - /* 196 */ EM_DELETE_NEXT_WORD, /* M-D */ - /* 197 */ ED_UNASSIGNED, /* M-E */ - /* 198 */ EM_NEXT_WORD, /* M-F */ - /* 199 */ ED_UNASSIGNED, /* M-G */ - /* 200 */ ED_UNASSIGNED, /* M-H */ - /* 201 */ ED_UNASSIGNED, /* M-I */ - /* 202 */ ED_UNASSIGNED, /* M-J */ - /* 203 */ ED_UNASSIGNED, /* M-K */ - /* 204 */ EM_LOWER_CASE, /* M-L */ - /* 205 */ ED_UNASSIGNED, /* M-M */ - /* 206 */ ED_SEARCH_NEXT_HISTORY, /* M-N */ - /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */ - /* 208 */ ED_SEARCH_PREV_HISTORY, /* M-P */ - /* 209 */ ED_UNASSIGNED, /* M-Q */ - /* 210 */ ED_UNASSIGNED, /* M-R */ - /* 211 */ ED_UNASSIGNED, /* M-S */ - /* 212 */ ED_UNASSIGNED, /* M-T */ - /* 213 */ EM_UPPER_CASE, /* M-U */ - /* 214 */ ED_UNASSIGNED, /* M-V */ - /* 215 */ EM_COPY_REGION, /* M-W */ - /* 216 */ ED_COMMAND, /* M-X */ - /* 217 */ ED_UNASSIGNED, /* M-Y */ - /* 218 */ ED_UNASSIGNED, /* M-Z */ - /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */ - /* 220 */ ED_UNASSIGNED, /* M-\ */ - /* 221 */ ED_UNASSIGNED, /* M-] */ - /* 222 */ ED_UNASSIGNED, /* M-^ */ - /* 223 */ ED_UNASSIGNED, /* M-_ */ - /* 223 */ ED_UNASSIGNED, /* M-` */ - /* 224 */ ED_UNASSIGNED, /* M-a */ - /* 225 */ ED_PREV_WORD, /* M-b */ - /* 226 */ EM_CAPITOL_CASE, /* M-c */ - /* 227 */ EM_DELETE_NEXT_WORD, /* M-d */ - /* 228 */ ED_UNASSIGNED, /* M-e */ - /* 229 */ EM_NEXT_WORD, /* M-f */ - /* 230 */ ED_UNASSIGNED, /* M-g */ - /* 231 */ ED_UNASSIGNED, /* M-h */ - /* 232 */ ED_UNASSIGNED, /* M-i */ - /* 233 */ ED_UNASSIGNED, /* M-j */ - /* 234 */ ED_UNASSIGNED, /* M-k */ - /* 235 */ EM_LOWER_CASE, /* M-l */ - /* 236 */ ED_UNASSIGNED, /* M-m */ - /* 237 */ ED_SEARCH_NEXT_HISTORY, /* M-n */ - /* 238 */ ED_UNASSIGNED, /* M-o */ - /* 239 */ ED_SEARCH_PREV_HISTORY, /* M-p */ - /* 240 */ ED_UNASSIGNED, /* M-q */ - /* 241 */ ED_UNASSIGNED, /* M-r */ - /* 242 */ ED_UNASSIGNED, /* M-s */ - /* 243 */ ED_UNASSIGNED, /* M-t */ - /* 244 */ EM_UPPER_CASE, /* M-u */ - /* 245 */ ED_UNASSIGNED, /* M-v */ - /* 246 */ EM_COPY_REGION, /* M-w */ - /* 247 */ ED_COMMAND, /* M-x */ - /* 248 */ ED_UNASSIGNED, /* M-y */ - /* 249 */ ED_UNASSIGNED, /* M-z */ - /* 250 */ ED_UNASSIGNED, /* M-{ */ - /* 251 */ ED_UNASSIGNED, /* M-| */ - /* 252 */ ED_UNASSIGNED, /* M-} */ - /* 253 */ ED_UNASSIGNED, /* M-~ */ - /* 254 */ ED_DELETE_PREV_WORD /* M-^? */ - /* 255 */ -}; - - -/* - * keymap table for vi. Each index into above tbl; should be - * N_KEYS entries long. Vi mode uses a sticky-extend to do command mode: - * insert mode characters are in the normal keymap, and command mode - * in the extended keymap. - */ -static const el_action_t el_map_vi_insert[] = { -#ifdef KSHVI - /* 0 */ ED_UNASSIGNED, /* ^@ */ - /* 1 */ ED_INSERT, /* ^A */ - /* 2 */ ED_INSERT, /* ^B */ - /* 3 */ ED_INSERT, /* ^C */ - /* 4 */ VI_LIST_OR_EOF, /* ^D */ - /* 5 */ ED_INSERT, /* ^E */ - /* 6 */ ED_INSERT, /* ^F */ - /* 7 */ ED_INSERT, /* ^G */ - /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ - /* 9 */ ED_INSERT, /* ^I */ /* Tab Key */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_INSERT, /* ^K */ - /* 12 */ ED_INSERT, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_INSERT, /* ^N */ - /* 15 */ ED_INSERT, /* ^O */ - /* 16 */ ED_INSERT, /* ^P */ - /* 17 */ ED_IGNORE, /* ^Q */ - /* 18 */ ED_INSERT, /* ^R */ - /* 19 */ ED_IGNORE, /* ^S */ - /* 20 */ ED_INSERT, /* ^T */ - /* 21 */ VI_KILL_LINE_PREV, /* ^U */ - /* 22 */ ED_QUOTED_INSERT, /* ^V */ - /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ - /* ED_DELETE_PREV_WORD: Only until strt edit pos */ - /* 24 */ ED_INSERT, /* ^X */ - /* 25 */ ED_INSERT, /* ^Y */ - /* 26 */ ED_INSERT, /* ^Z */ - /* 27 */ VI_COMMAND_MODE, /* ^[ */ /* [ Esc ] key */ - /* 28 */ ED_IGNORE, /* ^\ */ - /* 29 */ ED_INSERT, /* ^] */ - /* 30 */ ED_INSERT, /* ^^ */ - /* 31 */ ED_INSERT, /* ^_ */ -#else /* !KSHVI */ - /* - * NOTE: These mappings do NOT Correspond well - * to the KSH VI editing assignments. - * On the other and they are convenient and - * many people have have gotten used to them. - */ - /* 0 */ ED_UNASSIGNED, /* ^@ */ - /* 1 */ ED_MOVE_TO_BEG, /* ^A */ - /* 2 */ ED_PREV_CHAR, /* ^B */ - /* 3 */ ED_IGNORE, /* ^C */ - /* 4 */ VI_LIST_OR_EOF, /* ^D */ - /* 5 */ ED_MOVE_TO_END, /* ^E */ - /* 6 */ ED_NEXT_CHAR, /* ^F */ - /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ - /* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_KILL_LINE, /* ^K */ - /* 12 */ ED_CLEAR_SCREEN, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_NEXT_HISTORY, /* ^N */ - /* 15 */ ED_IGNORE, /* ^O */ - /* 16 */ ED_PREV_HISTORY, /* ^P */ - /* 17 */ ED_IGNORE, /* ^Q */ - /* 18 */ ED_REDISPLAY, /* ^R */ - /* 19 */ ED_IGNORE, /* ^S */ - /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */ - /* 21 */ VI_KILL_LINE_PREV, /* ^U */ - /* 22 */ ED_QUOTED_INSERT, /* ^V */ - /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ - /* 24 */ ED_UNASSIGNED, /* ^X */ - /* 25 */ ED_IGNORE, /* ^Y */ - /* 26 */ ED_IGNORE, /* ^Z */ - /* 27 */ VI_COMMAND_MODE, /* ^[ */ - /* 28 */ ED_IGNORE, /* ^\ */ - /* 29 */ ED_UNASSIGNED, /* ^] */ - /* 30 */ ED_UNASSIGNED, /* ^^ */ - /* 31 */ ED_UNASSIGNED, /* ^_ */ -#endif /* KSHVI */ - /* 32 */ ED_INSERT, /* SPACE */ - /* 33 */ ED_INSERT, /* ! */ - /* 34 */ ED_INSERT, /* " */ - /* 35 */ ED_INSERT, /* # */ - /* 36 */ ED_INSERT, /* $ */ - /* 37 */ ED_INSERT, /* % */ - /* 38 */ ED_INSERT, /* & */ - /* 39 */ ED_INSERT, /* ' */ - /* 40 */ ED_INSERT, /* ( */ - /* 41 */ ED_INSERT, /* ) */ - /* 42 */ ED_INSERT, /* * */ - /* 43 */ ED_INSERT, /* + */ - /* 44 */ ED_INSERT, /* , */ - /* 45 */ ED_INSERT, /* - */ - /* 46 */ ED_INSERT, /* . */ - /* 47 */ ED_INSERT, /* / */ - /* 48 */ ED_INSERT, /* 0 */ - /* 49 */ ED_INSERT, /* 1 */ - /* 50 */ ED_INSERT, /* 2 */ - /* 51 */ ED_INSERT, /* 3 */ - /* 52 */ ED_INSERT, /* 4 */ - /* 53 */ ED_INSERT, /* 5 */ - /* 54 */ ED_INSERT, /* 6 */ - /* 55 */ ED_INSERT, /* 7 */ - /* 56 */ ED_INSERT, /* 8 */ - /* 57 */ ED_INSERT, /* 9 */ - /* 58 */ ED_INSERT, /* : */ - /* 59 */ ED_INSERT, /* ; */ - /* 60 */ ED_INSERT, /* < */ - /* 61 */ ED_INSERT, /* = */ - /* 62 */ ED_INSERT, /* > */ - /* 63 */ ED_INSERT, /* ? */ - /* 64 */ ED_INSERT, /* @ */ - /* 65 */ ED_INSERT, /* A */ - /* 66 */ ED_INSERT, /* B */ - /* 67 */ ED_INSERT, /* C */ - /* 68 */ ED_INSERT, /* D */ - /* 69 */ ED_INSERT, /* E */ - /* 70 */ ED_INSERT, /* F */ - /* 71 */ ED_INSERT, /* G */ - /* 72 */ ED_INSERT, /* H */ - /* 73 */ ED_INSERT, /* I */ - /* 74 */ ED_INSERT, /* J */ - /* 75 */ ED_INSERT, /* K */ - /* 76 */ ED_INSERT, /* L */ - /* 77 */ ED_INSERT, /* M */ - /* 78 */ ED_INSERT, /* N */ - /* 79 */ ED_INSERT, /* O */ - /* 80 */ ED_INSERT, /* P */ - /* 81 */ ED_INSERT, /* Q */ - /* 82 */ ED_INSERT, /* R */ - /* 83 */ ED_INSERT, /* S */ - /* 84 */ ED_INSERT, /* T */ - /* 85 */ ED_INSERT, /* U */ - /* 86 */ ED_INSERT, /* V */ - /* 87 */ ED_INSERT, /* W */ - /* 88 */ ED_INSERT, /* X */ - /* 89 */ ED_INSERT, /* Y */ - /* 90 */ ED_INSERT, /* Z */ - /* 91 */ ED_INSERT, /* [ */ - /* 92 */ ED_INSERT, /* \ */ - /* 93 */ ED_INSERT, /* ] */ - /* 94 */ ED_INSERT, /* ^ */ - /* 95 */ ED_INSERT, /* _ */ - /* 96 */ ED_INSERT, /* ` */ - /* 97 */ ED_INSERT, /* a */ - /* 98 */ ED_INSERT, /* b */ - /* 99 */ ED_INSERT, /* c */ - /* 100 */ ED_INSERT, /* d */ - /* 101 */ ED_INSERT, /* e */ - /* 102 */ ED_INSERT, /* f */ - /* 103 */ ED_INSERT, /* g */ - /* 104 */ ED_INSERT, /* h */ - /* 105 */ ED_INSERT, /* i */ - /* 106 */ ED_INSERT, /* j */ - /* 107 */ ED_INSERT, /* k */ - /* 108 */ ED_INSERT, /* l */ - /* 109 */ ED_INSERT, /* m */ - /* 110 */ ED_INSERT, /* n */ - /* 111 */ ED_INSERT, /* o */ - /* 112 */ ED_INSERT, /* p */ - /* 113 */ ED_INSERT, /* q */ - /* 114 */ ED_INSERT, /* r */ - /* 115 */ ED_INSERT, /* s */ - /* 116 */ ED_INSERT, /* t */ - /* 117 */ ED_INSERT, /* u */ - /* 118 */ ED_INSERT, /* v */ - /* 119 */ ED_INSERT, /* w */ - /* 120 */ ED_INSERT, /* x */ - /* 121 */ ED_INSERT, /* y */ - /* 122 */ ED_INSERT, /* z */ - /* 123 */ ED_INSERT, /* { */ - /* 124 */ ED_INSERT, /* | */ - /* 125 */ ED_INSERT, /* } */ - /* 126 */ ED_INSERT, /* ~ */ - /* 127 */ VI_DELETE_PREV_CHAR, /* ^? */ - /* 128 */ ED_INSERT, /* M-^@ */ - /* 129 */ ED_INSERT, /* M-^A */ - /* 130 */ ED_INSERT, /* M-^B */ - /* 131 */ ED_INSERT, /* M-^C */ - /* 132 */ ED_INSERT, /* M-^D */ - /* 133 */ ED_INSERT, /* M-^E */ - /* 134 */ ED_INSERT, /* M-^F */ - /* 135 */ ED_INSERT, /* M-^G */ - /* 136 */ ED_INSERT, /* M-^H */ - /* 137 */ ED_INSERT, /* M-^I */ - /* 138 */ ED_INSERT, /* M-^J */ - /* 139 */ ED_INSERT, /* M-^K */ - /* 140 */ ED_INSERT, /* M-^L */ - /* 141 */ ED_INSERT, /* M-^M */ - /* 142 */ ED_INSERT, /* M-^N */ - /* 143 */ ED_INSERT, /* M-^O */ - /* 144 */ ED_INSERT, /* M-^P */ - /* 145 */ ED_INSERT, /* M-^Q */ - /* 146 */ ED_INSERT, /* M-^R */ - /* 147 */ ED_INSERT, /* M-^S */ - /* 148 */ ED_INSERT, /* M-^T */ - /* 149 */ ED_INSERT, /* M-^U */ - /* 150 */ ED_INSERT, /* M-^V */ - /* 151 */ ED_INSERT, /* M-^W */ - /* 152 */ ED_INSERT, /* M-^X */ - /* 153 */ ED_INSERT, /* M-^Y */ - /* 154 */ ED_INSERT, /* M-^Z */ - /* 155 */ ED_INSERT, /* M-^[ */ - /* 156 */ ED_INSERT, /* M-^\ */ - /* 157 */ ED_INSERT, /* M-^] */ - /* 158 */ ED_INSERT, /* M-^^ */ - /* 159 */ ED_INSERT, /* M-^_ */ - /* 160 */ ED_INSERT, /* M-SPACE */ - /* 161 */ ED_INSERT, /* M-! */ - /* 162 */ ED_INSERT, /* M-" */ - /* 163 */ ED_INSERT, /* M-# */ - /* 164 */ ED_INSERT, /* M-$ */ - /* 165 */ ED_INSERT, /* M-% */ - /* 166 */ ED_INSERT, /* M-& */ - /* 167 */ ED_INSERT, /* M-' */ - /* 168 */ ED_INSERT, /* M-( */ - /* 169 */ ED_INSERT, /* M-) */ - /* 170 */ ED_INSERT, /* M-* */ - /* 171 */ ED_INSERT, /* M-+ */ - /* 172 */ ED_INSERT, /* M-, */ - /* 173 */ ED_INSERT, /* M-- */ - /* 174 */ ED_INSERT, /* M-. */ - /* 175 */ ED_INSERT, /* M-/ */ - /* 176 */ ED_INSERT, /* M-0 */ - /* 177 */ ED_INSERT, /* M-1 */ - /* 178 */ ED_INSERT, /* M-2 */ - /* 179 */ ED_INSERT, /* M-3 */ - /* 180 */ ED_INSERT, /* M-4 */ - /* 181 */ ED_INSERT, /* M-5 */ - /* 182 */ ED_INSERT, /* M-6 */ - /* 183 */ ED_INSERT, /* M-7 */ - /* 184 */ ED_INSERT, /* M-8 */ - /* 185 */ ED_INSERT, /* M-9 */ - /* 186 */ ED_INSERT, /* M-: */ - /* 187 */ ED_INSERT, /* M-; */ - /* 188 */ ED_INSERT, /* M-< */ - /* 189 */ ED_INSERT, /* M-= */ - /* 190 */ ED_INSERT, /* M-> */ - /* 191 */ ED_INSERT, /* M-? */ - /* 192 */ ED_INSERT, /* M-@ */ - /* 193 */ ED_INSERT, /* M-A */ - /* 194 */ ED_INSERT, /* M-B */ - /* 195 */ ED_INSERT, /* M-C */ - /* 196 */ ED_INSERT, /* M-D */ - /* 197 */ ED_INSERT, /* M-E */ - /* 198 */ ED_INSERT, /* M-F */ - /* 199 */ ED_INSERT, /* M-G */ - /* 200 */ ED_INSERT, /* M-H */ - /* 201 */ ED_INSERT, /* M-I */ - /* 202 */ ED_INSERT, /* M-J */ - /* 203 */ ED_INSERT, /* M-K */ - /* 204 */ ED_INSERT, /* M-L */ - /* 205 */ ED_INSERT, /* M-M */ - /* 206 */ ED_INSERT, /* M-N */ - /* 207 */ ED_INSERT, /* M-O */ - /* 208 */ ED_INSERT, /* M-P */ - /* 209 */ ED_INSERT, /* M-Q */ - /* 210 */ ED_INSERT, /* M-R */ - /* 211 */ ED_INSERT, /* M-S */ - /* 212 */ ED_INSERT, /* M-T */ - /* 213 */ ED_INSERT, /* M-U */ - /* 214 */ ED_INSERT, /* M-V */ - /* 215 */ ED_INSERT, /* M-W */ - /* 216 */ ED_INSERT, /* M-X */ - /* 217 */ ED_INSERT, /* M-Y */ - /* 218 */ ED_INSERT, /* M-Z */ - /* 219 */ ED_INSERT, /* M-[ */ - /* 220 */ ED_INSERT, /* M-\ */ - /* 221 */ ED_INSERT, /* M-] */ - /* 222 */ ED_INSERT, /* M-^ */ - /* 223 */ ED_INSERT, /* M-_ */ - /* 224 */ ED_INSERT, /* M-` */ - /* 225 */ ED_INSERT, /* M-a */ - /* 226 */ ED_INSERT, /* M-b */ - /* 227 */ ED_INSERT, /* M-c */ - /* 228 */ ED_INSERT, /* M-d */ - /* 229 */ ED_INSERT, /* M-e */ - /* 230 */ ED_INSERT, /* M-f */ - /* 231 */ ED_INSERT, /* M-g */ - /* 232 */ ED_INSERT, /* M-h */ - /* 233 */ ED_INSERT, /* M-i */ - /* 234 */ ED_INSERT, /* M-j */ - /* 235 */ ED_INSERT, /* M-k */ - /* 236 */ ED_INSERT, /* M-l */ - /* 237 */ ED_INSERT, /* M-m */ - /* 238 */ ED_INSERT, /* M-n */ - /* 239 */ ED_INSERT, /* M-o */ - /* 240 */ ED_INSERT, /* M-p */ - /* 241 */ ED_INSERT, /* M-q */ - /* 242 */ ED_INSERT, /* M-r */ - /* 243 */ ED_INSERT, /* M-s */ - /* 244 */ ED_INSERT, /* M-t */ - /* 245 */ ED_INSERT, /* M-u */ - /* 246 */ ED_INSERT, /* M-v */ - /* 247 */ ED_INSERT, /* M-w */ - /* 248 */ ED_INSERT, /* M-x */ - /* 249 */ ED_INSERT, /* M-y */ - /* 250 */ ED_INSERT, /* M-z */ - /* 251 */ ED_INSERT, /* M-{ */ - /* 252 */ ED_INSERT, /* M-| */ - /* 253 */ ED_INSERT, /* M-} */ - /* 254 */ ED_INSERT, /* M-~ */ - /* 255 */ ED_INSERT /* M-^? */ -}; - -static const el_action_t el_map_vi_command[] = { - /* 0 */ ED_UNASSIGNED, /* ^@ */ - /* 1 */ ED_MOVE_TO_BEG, /* ^A */ - /* 2 */ ED_UNASSIGNED, /* ^B */ - /* 3 */ ED_IGNORE, /* ^C */ - /* 4 */ ED_UNASSIGNED, /* ^D */ - /* 5 */ ED_MOVE_TO_END, /* ^E */ - /* 6 */ ED_UNASSIGNED, /* ^F */ - /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ - /* 9 */ ED_UNASSIGNED, /* ^I */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_KILL_LINE, /* ^K */ - /* 12 */ ED_CLEAR_SCREEN, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_NEXT_HISTORY, /* ^N */ - /* 15 */ ED_IGNORE, /* ^O */ - /* 16 */ ED_PREV_HISTORY, /* ^P */ - /* 17 */ ED_IGNORE, /* ^Q */ - /* 18 */ ED_REDISPLAY, /* ^R */ - /* 19 */ ED_IGNORE, /* ^S */ - /* 20 */ ED_UNASSIGNED, /* ^T */ - /* 21 */ VI_KILL_LINE_PREV, /* ^U */ - /* 22 */ ED_UNASSIGNED, /* ^V */ - /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ - /* 24 */ ED_UNASSIGNED, /* ^X */ - /* 25 */ ED_UNASSIGNED, /* ^Y */ - /* 26 */ ED_UNASSIGNED, /* ^Z */ - /* 27 */ EM_META_NEXT, /* ^[ */ - /* 28 */ ED_IGNORE, /* ^\ */ - /* 29 */ ED_UNASSIGNED, /* ^] */ - /* 30 */ ED_UNASSIGNED, /* ^^ */ - /* 31 */ ED_UNASSIGNED, /* ^_ */ - /* 32 */ ED_NEXT_CHAR, /* SPACE */ - /* 33 */ ED_UNASSIGNED, /* ! */ - /* 34 */ ED_UNASSIGNED, /* " */ - /* 35 */ VI_COMMENT_OUT, /* # */ - /* 36 */ ED_MOVE_TO_END, /* $ */ - /* 37 */ VI_MATCH, /* % */ - /* 38 */ ED_UNASSIGNED, /* & */ - /* 39 */ ED_UNASSIGNED, /* ' */ - /* 40 */ ED_UNASSIGNED, /* ( */ - /* 41 */ ED_UNASSIGNED, /* ) */ - /* 42 */ ED_UNASSIGNED, /* * */ - /* 43 */ ED_NEXT_HISTORY, /* + */ - /* 44 */ VI_REPEAT_PREV_CHAR, /* , */ - /* 45 */ ED_PREV_HISTORY, /* - */ - /* 46 */ VI_REDO, /* . */ - /* 47 */ VI_SEARCH_PREV, /* / */ - /* 48 */ VI_ZERO, /* 0 */ - /* 49 */ ED_ARGUMENT_DIGIT, /* 1 */ - /* 50 */ ED_ARGUMENT_DIGIT, /* 2 */ - /* 51 */ ED_ARGUMENT_DIGIT, /* 3 */ - /* 52 */ ED_ARGUMENT_DIGIT, /* 4 */ - /* 53 */ ED_ARGUMENT_DIGIT, /* 5 */ - /* 54 */ ED_ARGUMENT_DIGIT, /* 6 */ - /* 55 */ ED_ARGUMENT_DIGIT, /* 7 */ - /* 56 */ ED_ARGUMENT_DIGIT, /* 8 */ - /* 57 */ ED_ARGUMENT_DIGIT, /* 9 */ - /* 58 */ ED_COMMAND, /* : */ - /* 59 */ VI_REPEAT_NEXT_CHAR, /* ; */ - /* 60 */ ED_UNASSIGNED, /* < */ - /* 61 */ ED_UNASSIGNED, /* = */ - /* 62 */ ED_UNASSIGNED, /* > */ - /* 63 */ VI_SEARCH_NEXT, /* ? */ - /* 64 */ VI_ALIAS, /* @ */ - /* 65 */ VI_ADD_AT_EOL, /* A */ - /* 66 */ VI_PREV_BIG_WORD, /* B */ - /* 67 */ VI_CHANGE_TO_EOL, /* C */ - /* 68 */ ED_KILL_LINE, /* D */ - /* 69 */ VI_END_BIG_WORD, /* E */ - /* 70 */ VI_PREV_CHAR, /* F */ - /* 71 */ VI_TO_HISTORY_LINE, /* G */ - /* 72 */ ED_UNASSIGNED, /* H */ - /* 73 */ VI_INSERT_AT_BOL, /* I */ - /* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */ - /* 75 */ ED_SEARCH_PREV_HISTORY, /* K */ - /* 76 */ ED_UNASSIGNED, /* L */ - /* 77 */ ED_UNASSIGNED, /* M */ - /* 78 */ VI_REPEAT_SEARCH_PREV, /* N */ - /* 79 */ ED_SEQUENCE_LEAD_IN, /* O */ - /* 80 */ VI_PASTE_PREV, /* P */ - /* 81 */ ED_UNASSIGNED, /* Q */ - /* 82 */ VI_REPLACE_MODE, /* R */ - /* 83 */ VI_SUBSTITUTE_LINE, /* S */ - /* 84 */ VI_TO_PREV_CHAR, /* T */ - /* 85 */ VI_UNDO_LINE, /* U */ - /* 86 */ ED_UNASSIGNED, /* V */ - /* 87 */ VI_NEXT_BIG_WORD, /* W */ - /* 88 */ ED_DELETE_PREV_CHAR, /* X */ - /* 89 */ VI_YANK_END, /* Y */ - /* 90 */ ED_UNASSIGNED, /* Z */ - /* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */ - /* 92 */ ED_UNASSIGNED, /* \ */ - /* 93 */ ED_UNASSIGNED, /* ] */ - /* 94 */ ED_MOVE_TO_BEG, /* ^ */ - /* 95 */ VI_HISTORY_WORD, /* _ */ - /* 96 */ ED_UNASSIGNED, /* ` */ - /* 97 */ VI_ADD, /* a */ - /* 98 */ VI_PREV_WORD, /* b */ - /* 99 */ VI_CHANGE_META, /* c */ - /* 100 */ VI_DELETE_META, /* d */ - /* 101 */ VI_END_WORD, /* e */ - /* 102 */ VI_NEXT_CHAR, /* f */ - /* 103 */ ED_UNASSIGNED, /* g */ - /* 104 */ ED_PREV_CHAR, /* h */ - /* 105 */ VI_INSERT, /* i */ - /* 106 */ ED_NEXT_HISTORY, /* j */ - /* 107 */ ED_PREV_HISTORY, /* k */ - /* 108 */ ED_NEXT_CHAR, /* l */ - /* 109 */ ED_UNASSIGNED, /* m */ - /* 110 */ VI_REPEAT_SEARCH_NEXT, /* n */ - /* 111 */ ED_UNASSIGNED, /* o */ - /* 112 */ VI_PASTE_NEXT, /* p */ - /* 113 */ ED_UNASSIGNED, /* q */ - /* 114 */ VI_REPLACE_CHAR, /* r */ - /* 115 */ VI_SUBSTITUTE_CHAR, /* s */ - /* 116 */ VI_TO_NEXT_CHAR, /* t */ - /* 117 */ VI_UNDO, /* u */ - /* 118 */ VI_HISTEDIT, /* v */ - /* 119 */ VI_NEXT_WORD, /* w */ - /* 120 */ ED_DELETE_NEXT_CHAR, /* x */ - /* 121 */ VI_YANK, /* y */ - /* 122 */ ED_UNASSIGNED, /* z */ - /* 123 */ ED_UNASSIGNED, /* { */ - /* 124 */ VI_TO_COLUMN, /* | */ - /* 125 */ ED_UNASSIGNED, /* } */ - /* 126 */ VI_CHANGE_CASE, /* ~ */ - /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ - /* 128 */ ED_UNASSIGNED, /* M-^@ */ - /* 129 */ ED_UNASSIGNED, /* M-^A */ - /* 130 */ ED_UNASSIGNED, /* M-^B */ - /* 131 */ ED_UNASSIGNED, /* M-^C */ - /* 132 */ ED_UNASSIGNED, /* M-^D */ - /* 133 */ ED_UNASSIGNED, /* M-^E */ - /* 134 */ ED_UNASSIGNED, /* M-^F */ - /* 135 */ ED_UNASSIGNED, /* M-^G */ - /* 136 */ ED_UNASSIGNED, /* M-^H */ - /* 137 */ ED_UNASSIGNED, /* M-^I */ - /* 138 */ ED_UNASSIGNED, /* M-^J */ - /* 139 */ ED_UNASSIGNED, /* M-^K */ - /* 140 */ ED_UNASSIGNED, /* M-^L */ - /* 141 */ ED_UNASSIGNED, /* M-^M */ - /* 142 */ ED_UNASSIGNED, /* M-^N */ - /* 143 */ ED_UNASSIGNED, /* M-^O */ - /* 144 */ ED_UNASSIGNED, /* M-^P */ - /* 145 */ ED_UNASSIGNED, /* M-^Q */ - /* 146 */ ED_UNASSIGNED, /* M-^R */ - /* 147 */ ED_UNASSIGNED, /* M-^S */ - /* 148 */ ED_UNASSIGNED, /* M-^T */ - /* 149 */ ED_UNASSIGNED, /* M-^U */ - /* 150 */ ED_UNASSIGNED, /* M-^V */ - /* 151 */ ED_UNASSIGNED, /* M-^W */ - /* 152 */ ED_UNASSIGNED, /* M-^X */ - /* 153 */ ED_UNASSIGNED, /* M-^Y */ - /* 154 */ ED_UNASSIGNED, /* M-^Z */ - /* 155 */ ED_UNASSIGNED, /* M-^[ */ - /* 156 */ ED_UNASSIGNED, /* M-^\ */ - /* 157 */ ED_UNASSIGNED, /* M-^] */ - /* 158 */ ED_UNASSIGNED, /* M-^^ */ - /* 159 */ ED_UNASSIGNED, /* M-^_ */ - /* 160 */ ED_UNASSIGNED, /* M-SPACE */ - /* 161 */ ED_UNASSIGNED, /* M-! */ - /* 162 */ ED_UNASSIGNED, /* M-" */ - /* 163 */ ED_UNASSIGNED, /* M-# */ - /* 164 */ ED_UNASSIGNED, /* M-$ */ - /* 165 */ ED_UNASSIGNED, /* M-% */ - /* 166 */ ED_UNASSIGNED, /* M-& */ - /* 167 */ ED_UNASSIGNED, /* M-' */ - /* 168 */ ED_UNASSIGNED, /* M-( */ - /* 169 */ ED_UNASSIGNED, /* M-) */ - /* 170 */ ED_UNASSIGNED, /* M-* */ - /* 171 */ ED_UNASSIGNED, /* M-+ */ - /* 172 */ ED_UNASSIGNED, /* M-, */ - /* 173 */ ED_UNASSIGNED, /* M-- */ - /* 174 */ ED_UNASSIGNED, /* M-. */ - /* 175 */ ED_UNASSIGNED, /* M-/ */ - /* 176 */ ED_UNASSIGNED, /* M-0 */ - /* 177 */ ED_UNASSIGNED, /* M-1 */ - /* 178 */ ED_UNASSIGNED, /* M-2 */ - /* 179 */ ED_UNASSIGNED, /* M-3 */ - /* 180 */ ED_UNASSIGNED, /* M-4 */ - /* 181 */ ED_UNASSIGNED, /* M-5 */ - /* 182 */ ED_UNASSIGNED, /* M-6 */ - /* 183 */ ED_UNASSIGNED, /* M-7 */ - /* 184 */ ED_UNASSIGNED, /* M-8 */ - /* 185 */ ED_UNASSIGNED, /* M-9 */ - /* 186 */ ED_UNASSIGNED, /* M-: */ - /* 187 */ ED_UNASSIGNED, /* M-; */ - /* 188 */ ED_UNASSIGNED, /* M-< */ - /* 189 */ ED_UNASSIGNED, /* M-= */ - /* 190 */ ED_UNASSIGNED, /* M-> */ - /* 191 */ ED_UNASSIGNED, /* M-? */ - /* 192 */ ED_UNASSIGNED, /* M-@ */ - /* 193 */ ED_UNASSIGNED, /* M-A */ - /* 194 */ ED_UNASSIGNED, /* M-B */ - /* 195 */ ED_UNASSIGNED, /* M-C */ - /* 196 */ ED_UNASSIGNED, /* M-D */ - /* 197 */ ED_UNASSIGNED, /* M-E */ - /* 198 */ ED_UNASSIGNED, /* M-F */ - /* 199 */ ED_UNASSIGNED, /* M-G */ - /* 200 */ ED_UNASSIGNED, /* M-H */ - /* 201 */ ED_UNASSIGNED, /* M-I */ - /* 202 */ ED_UNASSIGNED, /* M-J */ - /* 203 */ ED_UNASSIGNED, /* M-K */ - /* 204 */ ED_UNASSIGNED, /* M-L */ - /* 205 */ ED_UNASSIGNED, /* M-M */ - /* 206 */ ED_UNASSIGNED, /* M-N */ - /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */ - /* 208 */ ED_UNASSIGNED, /* M-P */ - /* 209 */ ED_UNASSIGNED, /* M-Q */ - /* 210 */ ED_UNASSIGNED, /* M-R */ - /* 211 */ ED_UNASSIGNED, /* M-S */ - /* 212 */ ED_UNASSIGNED, /* M-T */ - /* 213 */ ED_UNASSIGNED, /* M-U */ - /* 214 */ ED_UNASSIGNED, /* M-V */ - /* 215 */ ED_UNASSIGNED, /* M-W */ - /* 216 */ ED_UNASSIGNED, /* M-X */ - /* 217 */ ED_UNASSIGNED, /* M-Y */ - /* 218 */ ED_UNASSIGNED, /* M-Z */ - /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */ - /* 220 */ ED_UNASSIGNED, /* M-\ */ - /* 221 */ ED_UNASSIGNED, /* M-] */ - /* 222 */ ED_UNASSIGNED, /* M-^ */ - /* 223 */ ED_UNASSIGNED, /* M-_ */ - /* 224 */ ED_UNASSIGNED, /* M-` */ - /* 225 */ ED_UNASSIGNED, /* M-a */ - /* 226 */ ED_UNASSIGNED, /* M-b */ - /* 227 */ ED_UNASSIGNED, /* M-c */ - /* 228 */ ED_UNASSIGNED, /* M-d */ - /* 229 */ ED_UNASSIGNED, /* M-e */ - /* 230 */ ED_UNASSIGNED, /* M-f */ - /* 231 */ ED_UNASSIGNED, /* M-g */ - /* 232 */ ED_UNASSIGNED, /* M-h */ - /* 233 */ ED_UNASSIGNED, /* M-i */ - /* 234 */ ED_UNASSIGNED, /* M-j */ - /* 235 */ ED_UNASSIGNED, /* M-k */ - /* 236 */ ED_UNASSIGNED, /* M-l */ - /* 237 */ ED_UNASSIGNED, /* M-m */ - /* 238 */ ED_UNASSIGNED, /* M-n */ - /* 239 */ ED_UNASSIGNED, /* M-o */ - /* 240 */ ED_UNASSIGNED, /* M-p */ - /* 241 */ ED_UNASSIGNED, /* M-q */ - /* 242 */ ED_UNASSIGNED, /* M-r */ - /* 243 */ ED_UNASSIGNED, /* M-s */ - /* 244 */ ED_UNASSIGNED, /* M-t */ - /* 245 */ ED_UNASSIGNED, /* M-u */ - /* 246 */ ED_UNASSIGNED, /* M-v */ - /* 247 */ ED_UNASSIGNED, /* M-w */ - /* 248 */ ED_UNASSIGNED, /* M-x */ - /* 249 */ ED_UNASSIGNED, /* M-y */ - /* 250 */ ED_UNASSIGNED, /* M-z */ - /* 251 */ ED_UNASSIGNED, /* M-{ */ - /* 252 */ ED_UNASSIGNED, /* M-| */ - /* 253 */ ED_UNASSIGNED, /* M-} */ - /* 254 */ ED_UNASSIGNED, /* M-~ */ - /* 255 */ ED_UNASSIGNED /* M-^? */ -}; - - -/* map_init(): - * Initialize and allocate the maps - */ -libedit_private int -map_init(EditLine *el) -{ - - /* - * Make sure those are correct before starting. - */ -#ifdef MAP_DEBUG - if (sizeof(el_map_emacs) != N_KEYS * sizeof(el_action_t)) - EL_ABORT((el->errfile, "Emacs map incorrect\n")); - if (sizeof(el_map_vi_command) != N_KEYS * sizeof(el_action_t)) - EL_ABORT((el->errfile, "Vi command map incorrect\n")); - if (sizeof(el_map_vi_insert) != N_KEYS * sizeof(el_action_t)) - EL_ABORT((el->errfile, "Vi insert map incorrect\n")); -#endif - - el->el_map.alt = el_malloc(sizeof(*el->el_map.alt) * N_KEYS); - if (el->el_map.alt == NULL) - return -1; - el->el_map.key = el_malloc(sizeof(*el->el_map.key) * N_KEYS); - if (el->el_map.key == NULL) - return -1; - el->el_map.emacs = el_map_emacs; - el->el_map.vic = el_map_vi_command; - el->el_map.vii = el_map_vi_insert; - el->el_map.help = el_malloc(sizeof(*el->el_map.help) * EL_NUM_FCNS); - if (el->el_map.help == NULL) - return -1; - (void) memcpy(el->el_map.help, el_func_help, - sizeof(*el->el_map.help) * EL_NUM_FCNS); - el->el_map.func = el_malloc(sizeof(*el->el_map.func) * EL_NUM_FCNS); - if (el->el_map.func == NULL) - return -1; - memcpy(el->el_map.func, el_func, sizeof(*el->el_map.func) - * EL_NUM_FCNS); - el->el_map.nfunc = EL_NUM_FCNS; - -#ifdef VIDEFAULT - map_init_vi(el); -#else - map_init_emacs(el); -#endif /* VIDEFAULT */ - return 0; -} - - -/* map_end(): - * Free the space taken by the editor maps - */ -libedit_private void -map_end(EditLine *el) -{ - - el_free(el->el_map.alt); - el->el_map.alt = NULL; - el_free(el->el_map.key); - el->el_map.key = NULL; - el->el_map.emacs = NULL; - el->el_map.vic = NULL; - el->el_map.vii = NULL; - el_free(el->el_map.help); - el->el_map.help = NULL; - el_free(el->el_map.func); - el->el_map.func = NULL; -} - - -/* map_init_nls(): - * Find all the printable keys and bind them to self insert - */ -static void -map_init_nls(EditLine *el) -{ - int i; - - el_action_t *map = el->el_map.key; - - for (i = 0200; i <= 0377; i++) - if (iswprint(i)) - map[i] = ED_INSERT; -} - - -/* map_init_meta(): - * Bind all the meta keys to the appropriate ESC- sequence - */ -static void -map_init_meta(EditLine *el) -{ - wchar_t buf[3]; - int i; - el_action_t *map = el->el_map.key; - el_action_t *alt = el->el_map.alt; - - for (i = 0; i <= 0377 && map[i] != EM_META_NEXT; i++) - continue; - - if (i > 0377) { - for (i = 0; i <= 0377 && alt[i] != EM_META_NEXT; i++) - continue; - if (i > 0377) { - i = 033; - if (el->el_map.type == MAP_VI) - map = alt; - } else - map = alt; - } - buf[0] = (wchar_t)i; - buf[2] = 0; - for (i = 0200; i <= 0377; i++) - switch (map[i]) { - case ED_INSERT: - case ED_UNASSIGNED: - case ED_SEQUENCE_LEAD_IN: - break; - default: - buf[1] = i & 0177; - keymacro_add(el, buf, keymacro_map_cmd(el, (int) map[i]), XK_CMD); - break; - } - map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN; -} - - -/* map_init_vi(): - * Initialize the vi bindings - */ -libedit_private void -map_init_vi(EditLine *el) -{ - int i; - el_action_t *key = el->el_map.key; - el_action_t *alt = el->el_map.alt; - const el_action_t *vii = el->el_map.vii; - const el_action_t *vic = el->el_map.vic; - - el->el_map.type = MAP_VI; - el->el_map.current = el->el_map.key; - - keymacro_reset(el); - - for (i = 0; i < N_KEYS; i++) { - key[i] = vii[i]; - alt[i] = vic[i]; - } - - map_init_meta(el); - map_init_nls(el); - - tty_bind_char(el, 1); - terminal_bind_arrow(el); -} - - -/* map_init_emacs(): - * Initialize the emacs bindings - */ -libedit_private void -map_init_emacs(EditLine *el) -{ - int i; - wchar_t buf[3]; - el_action_t *key = el->el_map.key; - el_action_t *alt = el->el_map.alt; - const el_action_t *emacs = el->el_map.emacs; - - el->el_map.type = MAP_EMACS; - el->el_map.current = el->el_map.key; - keymacro_reset(el); - - for (i = 0; i < N_KEYS; i++) { - key[i] = emacs[i]; - alt[i] = ED_UNASSIGNED; - } - - map_init_meta(el); - map_init_nls(el); - - buf[0] = CONTROL('X'); - buf[1] = CONTROL('X'); - buf[2] = 0; - keymacro_add(el, buf, keymacro_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD); - - tty_bind_char(el, 1); - terminal_bind_arrow(el); -} - - -/* map_set_editor(): - * Set the editor - */ -libedit_private int -map_set_editor(EditLine *el, wchar_t *editor) -{ - - if (wcscmp(editor, L"emacs") == 0) { - map_init_emacs(el); - return 0; - } - if (wcscmp(editor, L"vi") == 0) { - map_init_vi(el); - return 0; - } - return -1; -} - - -/* map_get_editor(): - * Retrieve the editor - */ -libedit_private int -map_get_editor(EditLine *el, const wchar_t **editor) -{ - - if (editor == NULL) - return -1; - switch (el->el_map.type) { - case MAP_EMACS: - *editor = L"emacs"; - return 0; - case MAP_VI: - *editor = L"vi"; - return 0; - } - return -1; -} - - -/* map_print_key(): - * Print the function description for 1 key - */ -static void -map_print_key(EditLine *el, el_action_t *map, const wchar_t *in) -{ - char outbuf[EL_BUFSIZ]; - el_bindings_t *bp, *ep; - - if (in[0] == '\0' || in[1] == '\0') { - (void) keymacro__decode_str(in, outbuf, sizeof(outbuf), ""); - ep = &el->el_map.help[el->el_map.nfunc]; - for (bp = el->el_map.help; bp < ep; bp++) - if (bp->func == map[(unsigned char) *in]) { - (void) fprintf(el->el_outfile, - "%s\t->\t%ls\n", outbuf, bp->name); - return; - } - } else - keymacro_print(el, in); -} - - -/* map_print_some_keys(): - * Print keys from first to last - */ -static void -map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last) -{ - el_bindings_t *bp, *ep; - wchar_t firstbuf[2], lastbuf[2]; - char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; - - firstbuf[0] = first; - firstbuf[1] = 0; - lastbuf[0] = last; - lastbuf[1] = 0; - if (map[first] == ED_UNASSIGNED) { - if (first == last) { - (void) keymacro__decode_str(firstbuf, unparsbuf, - sizeof(unparsbuf), STRQQ); - (void) fprintf(el->el_outfile, - "%-15s-> is undefined\n", unparsbuf); - } - return; - } - ep = &el->el_map.help[el->el_map.nfunc]; - for (bp = el->el_map.help; bp < ep; bp++) { - if (bp->func == map[first]) { - if (first == last) { - (void) keymacro__decode_str(firstbuf, unparsbuf, - sizeof(unparsbuf), STRQQ); - (void) fprintf(el->el_outfile, "%-15s-> %ls\n", - unparsbuf, bp->name); - } else { - (void) keymacro__decode_str(firstbuf, unparsbuf, - sizeof(unparsbuf), STRQQ); - (void) keymacro__decode_str(lastbuf, extrabuf, - sizeof(extrabuf), STRQQ); - (void) fprintf(el->el_outfile, - "%-4s to %-7s-> %ls\n", - unparsbuf, extrabuf, bp->name); - } - return; - } - } -#ifdef MAP_DEBUG - if (map == el->el_map.key) { - (void) keymacro__decode_str(firstbuf, unparsbuf, - sizeof(unparsbuf), STRQQ); - (void) fprintf(el->el_outfile, - "BUG!!! %s isn't bound to anything.\n", unparsbuf); - (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", - first, el->el_map.key[first]); - } else { - (void) keymacro__decode_str(firstbuf, unparsbuf, - sizeof(unparsbuf), STRQQ); - (void) fprintf(el->el_outfile, - "BUG!!! %s isn't bound to anything.\n", unparsbuf); - (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n", - first, el->el_map.alt[first]); - } -#endif - EL_ABORT((el->el_errfile, "Error printing keys\n")); -} - - -/* map_print_all_keys(): - * Print the function description for all keys. - */ -static void -map_print_all_keys(EditLine *el) -{ - int prev, i; - - (void) fprintf(el->el_outfile, "Standard key bindings\n"); - prev = 0; - for (i = 0; i < N_KEYS; i++) { - if (el->el_map.key[prev] == el->el_map.key[i]) - continue; - map_print_some_keys(el, el->el_map.key, prev, i - 1); - prev = i; - } - map_print_some_keys(el, el->el_map.key, prev, i - 1); - - (void) fprintf(el->el_outfile, "Alternative key bindings\n"); - prev = 0; - for (i = 0; i < N_KEYS; i++) { - if (el->el_map.alt[prev] == el->el_map.alt[i]) - continue; - map_print_some_keys(el, el->el_map.alt, prev, i - 1); - prev = i; - } - map_print_some_keys(el, el->el_map.alt, prev, i - 1); - - (void) fprintf(el->el_outfile, "Multi-character bindings\n"); - keymacro_print(el, L""); - (void) fprintf(el->el_outfile, "Arrow key bindings\n"); - terminal_print_arrow(el, L""); -} - - -/* map_bind(): - * Add/remove/change bindings - */ -libedit_private int -map_bind(EditLine *el, int argc, const wchar_t **argv) -{ - el_action_t *map; - int ntype, rem; - const wchar_t *p; - wchar_t inbuf[EL_BUFSIZ]; - wchar_t outbuf[EL_BUFSIZ]; - const wchar_t *in = NULL; - wchar_t *out; - el_bindings_t *bp, *ep; - int cmd; - int key; - - if (argv == NULL) - return -1; - - map = el->el_map.key; - ntype = XK_CMD; - key = rem = 0; - for (argc = 1; (p = argv[argc]) != NULL; argc++) - if (p[0] == '-') - switch (p[1]) { - case 'a': - map = el->el_map.alt; - break; - - case 's': - ntype = XK_STR; - break; - case 'k': - key = 1; - break; - - case 'r': - rem = 1; - break; - - case 'v': - map_init_vi(el); - return 0; - - case 'e': - map_init_emacs(el); - return 0; - - case 'l': - ep = &el->el_map.help[el->el_map.nfunc]; - for (bp = el->el_map.help; bp < ep; bp++) - (void) fprintf(el->el_outfile, - "%ls\n\t%ls\n", - bp->name, bp->description); - return 0; - default: - (void) fprintf(el->el_errfile, - "%ls: Invalid switch `%lc'.\n", - argv[0], (wint_t)p[1]); - } - else - break; - - if (argv[argc] == NULL) { - map_print_all_keys(el); - return 0; - } - if (key) - in = argv[argc++]; - else if ((in = parse__string(inbuf, argv[argc++])) == NULL) { - (void) fprintf(el->el_errfile, - "%ls: Invalid \\ or ^ in instring.\n", - argv[0]); - return -1; - } - if (rem) { - if (key) { - (void) terminal_clear_arrow(el, in); - return -1; - } - if (in[1]) - (void) keymacro_delete(el, in); - else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) - (void) keymacro_delete(el, in); - else - map[(unsigned char) *in] = ED_UNASSIGNED; - return 0; - } - if (argv[argc] == NULL) { - if (key) - terminal_print_arrow(el, in); - else - map_print_key(el, map, in); - return 0; - } -#ifdef notyet - if (argv[argc + 1] != NULL) { - bindkeymacro_usage(); - return -1; - } -#endif - - switch (ntype) { - case XK_STR: - if ((out = parse__string(outbuf, argv[argc])) == NULL) { - (void) fprintf(el->el_errfile, - "%ls: Invalid \\ or ^ in outstring.\n", argv[0]); - return -1; - } - if (key) - terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype); - else - keymacro_add(el, in, keymacro_map_str(el, out), ntype); - map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; - break; - - case XK_CMD: - if ((cmd = parse_cmd(el, argv[argc])) == -1) { - (void) fprintf(el->el_errfile, - "%ls: Invalid command `%ls'.\n", - argv[0], argv[argc]); - return -1; - } - if (key) - terminal_set_arrow(el, in, keymacro_map_cmd(el, cmd), ntype); - else { - if (in[1]) { - keymacro_add(el, in, keymacro_map_cmd(el, cmd), ntype); - map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; - } else { - keymacro_clear(el, map, in); - map[(unsigned char) *in] = (el_action_t)cmd; - } - } - break; - - /* coverity[dead_error_begin] */ - default: - EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); - break; - } - return 0; -} - - -/* map_addfunc(): - * add a user defined function - */ -libedit_private int -map_addfunc(EditLine *el, const wchar_t *name, const wchar_t *help, - el_func_t func) -{ - void *p; - size_t nf = el->el_map.nfunc + 1; - - if (name == NULL || help == NULL || func == NULL) - return -1; - - if ((p = el_realloc(el->el_map.func, nf * - sizeof(*el->el_map.func))) == NULL) - return -1; - el->el_map.func = p; - if ((p = el_realloc(el->el_map.help, nf * sizeof(*el->el_map.help))) - == NULL) - return -1; - el->el_map.help = p; - - nf = (size_t)el->el_map.nfunc; - el->el_map.func[nf] = func; - - el->el_map.help[nf].name = name; - el->el_map.help[nf].func = (int)nf; - el->el_map.help[nf].description = help; - el->el_map.nfunc++; - - return 0; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/map.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/map.h deleted file mode 100644 index b4e4e28..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/map.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: map.h,v 1.13 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)map.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.map.h: Editor maps - */ -#ifndef _h_el_map -#define _h_el_map - -typedef el_action_t (*el_func_t)(EditLine *, wint_t); - -typedef struct el_bindings_t { /* for the "bind" shell command */ - const wchar_t *name; /* function name for bind command */ - int func; /* function numeric value */ - const wchar_t *description; /* description of function */ -} el_bindings_t; - -typedef struct el_map_t { - el_action_t *alt; /* The current alternate key map */ - el_action_t *key; /* The current normal key map */ - el_action_t *current; /* The keymap we are using */ - const el_action_t *emacs; /* The default emacs key map */ - const el_action_t *vic; /* The vi command mode key map */ - const el_action_t *vii; /* The vi insert mode key map */ - int type; /* Emacs or vi */ - el_bindings_t *help; /* The help for the editor functions */ - el_func_t *func; /* List of available functions */ - size_t nfunc; /* The number of functions/help items */ -} el_map_t; - -#define MAP_EMACS 0 -#define MAP_VI 1 - -#define N_KEYS 256 - -libedit_private int map_bind(EditLine *, int, const wchar_t **); -libedit_private int map_init(EditLine *); -libedit_private void map_end(EditLine *); -libedit_private void map_init_vi(EditLine *); -libedit_private void map_init_emacs(EditLine *); -libedit_private int map_set_editor(EditLine *, wchar_t *); -libedit_private int map_get_editor(EditLine *, const wchar_t **); -libedit_private int map_addfunc(EditLine *, const wchar_t *, const wchar_t *, - el_func_t); - -#endif /* _h_el_map */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/parse.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/parse.c deleted file mode 100644 index fdd0d84..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/parse.c +++ /dev/null @@ -1,289 +0,0 @@ -/* $NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * parse.c: parse an editline extended command - * - * commands are: - * - * bind - * echotc - * edit - * gettc - * history - * settc - * setty - */ -#include -#include - -#include "el.h" -#include "parse.h" - -static const struct { - const wchar_t *name; - int (*func)(EditLine *, int, const wchar_t **); -} cmds[] = { - { L"bind", map_bind }, - { L"echotc", terminal_echotc }, - { L"edit", el_editmode }, - { L"history", hist_command }, - { L"telltc", terminal_telltc }, - { L"settc", terminal_settc }, - { L"setty", tty_stty }, - { NULL, NULL } -}; - - -/* parse_line(): - * Parse a line and dispatch it - */ -libedit_private int -parse_line(EditLine *el, const wchar_t *line) -{ - const wchar_t **argv; - int argc; - TokenizerW *tok; - - tok = tok_winit(NULL); - tok_wstr(tok, line, &argc, &argv); - argc = el_wparse(el, argc, argv); - tok_wend(tok); - return argc; -} - - -/* el_parse(): - * Command dispatcher - */ -int -el_wparse(EditLine *el, int argc, const wchar_t *argv[]) -{ - const wchar_t *ptr; - int i; - - if (argc < 1) - return -1; - ptr = wcschr(argv[0], L':'); - if (ptr != NULL) { - wchar_t *tprog; - size_t l; - - if (ptr == argv[0]) - return 0; - l = (size_t)(ptr - argv[0] - 1); - tprog = el_malloc((l + 1) * sizeof(*tprog)); - if (tprog == NULL) - return 0; - (void) wcsncpy(tprog, argv[0], l); - tprog[l] = '\0'; - ptr++; - l = (size_t)el_match(el->el_prog, tprog); - el_free(tprog); - if (!l) - return 0; - } else - ptr = argv[0]; - - for (i = 0; cmds[i].name != NULL; i++) - if (wcscmp(cmds[i].name, ptr) == 0) { - i = (*cmds[i].func) (el, argc, argv); - return -i; - } - return -1; -} - - -/* parse__escape(): - * Parse a string of the form ^ \ \ \U+xxxx and return - * the appropriate character or -1 if the escape is not valid - */ -libedit_private int -parse__escape(const wchar_t **ptr) -{ - const wchar_t *p; - wint_t c; - - p = *ptr; - - if (p[1] == 0) - return -1; - - if (*p == '\\') { - p++; - switch (*p) { - case 'a': - c = '\007'; /* Bell */ - break; - case 'b': - c = '\010'; /* Backspace */ - break; - case 't': - c = '\011'; /* Horizontal Tab */ - break; - case 'n': - c = '\012'; /* New Line */ - break; - case 'v': - c = '\013'; /* Vertical Tab */ - break; - case 'f': - c = '\014'; /* Form Feed */ - break; - case 'r': - c = '\015'; /* Carriage Return */ - break; - case 'e': - c = '\033'; /* Escape */ - break; - case 'U': /* Unicode \U+xxxx or \U+xxxxx format */ - { - int i; - const wchar_t hex[] = L"0123456789ABCDEF"; - const wchar_t *h; - ++p; - if (*p++ != '+') - return -1; - c = 0; - for (i = 0; i < 5; ++i) { - h = wcschr(hex, *p++); - if (!h && i < 4) - return -1; - else if (h) - c = (c << 4) | ((int)(h - hex)); - else - --p; - } - if (c > 0x10FFFF) /* outside valid character range */ - return -1; - break; - } - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - int cnt, ch; - - for (cnt = 0, c = 0; cnt < 3; cnt++) { - ch = *p++; - if (ch < '0' || ch > '7') { - p--; - break; - } - c = (c << 3) | (ch - '0'); - } - if ((c & (wint_t)0xffffff00) != (wint_t)0) - return -1; - --p; - break; - } - default: - c = *p; - break; - } - } else if (*p == '^') { - p++; - c = (*p == '?') ? '\177' : (*p & 0237); - } else - c = *p; - *ptr = ++p; - return c; -} - -/* parse__string(): - * Parse the escapes from in and put the raw string out - */ -libedit_private wchar_t * -parse__string(wchar_t *out, const wchar_t *in) -{ - wchar_t *rv = out; - int n; - - for (;;) - switch (*in) { - case '\0': - *out = '\0'; - return rv; - - case '\\': - case '^': - if ((n = parse__escape(&in)) == -1) - return NULL; - *out++ = (wchar_t)n; - break; - - case 'M': - if (in[1] == '-' && in[2] != '\0') { - *out++ = '\033'; - in += 2; - break; - } - /*FALLTHROUGH*/ - - default: - *out++ = *in++; - break; - } -} - - -/* parse_cmd(): - * Return the command number for the command string given - * or -1 if one is not found - */ -libedit_private int -parse_cmd(EditLine *el, const wchar_t *cmd) -{ - el_bindings_t *b = el->el_map.help; - size_t i; - - for (i = 0; i < el->el_map.nfunc; i++) - if (wcscmp(b[i].name, cmd) == 0) - return b[i].func; - return -1; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/parse.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/parse.h deleted file mode 100644 index fe8eb47..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/parse.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: parse.h,v 1.9 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)parse.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.parse.h: Parser functions - */ -#ifndef _h_el_parse -#define _h_el_parse - -libedit_private int parse_line(EditLine *, const wchar_t *); -libedit_private int parse__escape(const wchar_t **); -libedit_private wchar_t *parse__string(wchar_t *, const wchar_t *); -libedit_private int parse_cmd(EditLine *, const wchar_t *); - -#endif /* _h_el_parse */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/prompt.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/prompt.c deleted file mode 100644 index a3d9915..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/prompt.c +++ /dev/null @@ -1,199 +0,0 @@ -/* $NetBSD: prompt.c,v 1.26 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: prompt.c,v 1.26 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * prompt.c: Prompt printing functions - */ -#include -#include "el.h" - -static wchar_t *prompt_default(EditLine *); -static wchar_t *prompt_default_r(EditLine *); - -/* prompt_default(): - * Just a default prompt, in case the user did not provide one - */ -static wchar_t * -/*ARGSUSED*/ -prompt_default(EditLine *el __attribute__((__unused__))) -{ - static wchar_t a[3] = L"? "; - - return a; -} - - -/* prompt_default_r(): - * Just a default rprompt, in case the user did not provide one - */ -static wchar_t * -/*ARGSUSED*/ -prompt_default_r(EditLine *el __attribute__((__unused__))) -{ - static wchar_t a[1] = L""; - - return a; -} - - -/* prompt_print(): - * Print the prompt and update the prompt position. - */ -libedit_private void -prompt_print(EditLine *el, int op) -{ - el_prompt_t *elp; - wchar_t *p; - int ignore = 0; - - if (op == EL_PROMPT) - elp = &el->el_prompt; - else - elp = &el->el_rprompt; - - if (elp->p_wide) - p = (*elp->p_func)(el); - else - p = ct_decode_string((char *)(void *)(*elp->p_func)(el), - &el->el_scratch); - - for (; *p; p++) { - if (elp->p_ignore == *p) { - ignore = !ignore; - continue; - } - if (ignore) - terminal__putc(el, *p); - else - re_putc(el, *p, 1); - } - - elp->p_pos.v = el->el_refresh.r_cursor.v; - elp->p_pos.h = el->el_refresh.r_cursor.h; -} - - -/* prompt_init(): - * Initialize the prompt stuff - */ -libedit_private int -prompt_init(EditLine *el) -{ - - el->el_prompt.p_func = prompt_default; - el->el_prompt.p_pos.v = 0; - el->el_prompt.p_pos.h = 0; - el->el_prompt.p_ignore = '\0'; - el->el_rprompt.p_func = prompt_default_r; - el->el_rprompt.p_pos.v = 0; - el->el_rprompt.p_pos.h = 0; - el->el_rprompt.p_ignore = '\0'; - return 0; -} - - -/* prompt_end(): - * Clean up the prompt stuff - */ -libedit_private void -/*ARGSUSED*/ -prompt_end(EditLine *el __attribute__((__unused__))) -{ -} - - -/* prompt_set(): - * Install a prompt printing function - */ -libedit_private int -prompt_set(EditLine *el, el_pfunc_t prf, wchar_t c, int op, int wide) -{ - el_prompt_t *p; - - if (op == EL_PROMPT || op == EL_PROMPT_ESC) - p = &el->el_prompt; - else - p = &el->el_rprompt; - - if (prf == NULL) { - if (op == EL_PROMPT || op == EL_PROMPT_ESC) - p->p_func = prompt_default; - else - p->p_func = prompt_default_r; - } else { - p->p_func = prf; - } - - p->p_ignore = c; - - p->p_pos.v = 0; - p->p_pos.h = 0; - p->p_wide = wide; - - return 0; -} - - -/* prompt_get(): - * Retrieve the prompt printing function - */ -libedit_private int -prompt_get(EditLine *el, el_pfunc_t *prf, wchar_t *c, int op) -{ - el_prompt_t *p; - - if (prf == NULL) - return -1; - - if (op == EL_PROMPT) - p = &el->el_prompt; - else - p = &el->el_rprompt; - - if (prf) - *prf = p->p_func; - if (c) - *c = p->p_ignore; - - return 0; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/prompt.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/prompt.h deleted file mode 100644 index 2931428..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/prompt.h +++ /dev/null @@ -1,58 +0,0 @@ -/* $NetBSD: prompt.h,v 1.15 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)prompt.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.prompt.h: Prompt printing stuff - */ -#ifndef _h_el_prompt -#define _h_el_prompt - -typedef wchar_t *(*el_pfunc_t)(EditLine *); - -typedef struct el_prompt_t { - el_pfunc_t p_func; /* Function to return the prompt */ - coord_t p_pos; /* position in the line after prompt */ - wchar_t p_ignore; /* character to start/end literal */ - int p_wide; -} el_prompt_t; - -libedit_private void prompt_print(EditLine *, int); -libedit_private int prompt_set(EditLine *, el_pfunc_t, wchar_t, int, int); -libedit_private int prompt_get(EditLine *, el_pfunc_t *, wchar_t *, int); -libedit_private int prompt_init(EditLine *); -libedit_private void prompt_end(EditLine *); - -#endif /* _h_el_prompt */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/read.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/read.c deleted file mode 100644 index ec10be7..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/read.c +++ /dev/null @@ -1,629 +0,0 @@ -/* $NetBSD: read.c,v 1.102 2016/12/11 15:47:06 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: read.c,v 1.102 2016/12/11 15:47:06 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * read.c: Terminal read functions - */ -#include -#include -#include -#include -#include -#include -#include - -#include "el.h" -#include "fcns.h" -#include "read.h" - -#define EL_MAXMACRO 10 - -struct macros { - wchar_t **macro; - int level; - int offset; -}; - -struct el_read_t { - struct macros macros; - el_rfunc_t read_char; /* Function to read a character. */ - int read_errno; -}; - -static int read__fixio(int, int); -static int read_char(EditLine *, wchar_t *); -static int read_getcmd(EditLine *, el_action_t *, wchar_t *); -static void read_clearmacros(struct macros *); -static void read_pop(struct macros *); -static const wchar_t *noedit_wgets(EditLine *, int *); - -/* read_init(): - * Initialize the read stuff - */ -libedit_private int -read_init(EditLine *el) -{ - struct macros *ma; - - if ((el->el_read = el_malloc(sizeof(*el->el_read))) == NULL) - return -1; - - ma = &el->el_read->macros; - if ((ma->macro = el_malloc(EL_MAXMACRO * - sizeof(*ma->macro))) == NULL) { - free(el->el_read); - return -1; - } - ma->level = -1; - ma->offset = 0; - - /* builtin read_char */ - el->el_read->read_char = read_char; - return 0; -} - -/* el_read_end(): - * Free the data structures used by the read stuff. - */ -libedit_private void -read_end(struct el_read_t *el_read) -{ - read_clearmacros(&el_read->macros); - el_free(el_read->macros.macro); - el_read->macros.macro = NULL; - el_free(el_read); -} - -/* el_read_setfn(): - * Set the read char function to the one provided. - * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one. - */ -libedit_private int -el_read_setfn(struct el_read_t *el_read, el_rfunc_t rc) -{ - el_read->read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc; - return 0; -} - - -/* el_read_getfn(): - * return the current read char function, or EL_BUILTIN_GETCFN - * if it is the default one - */ -libedit_private el_rfunc_t -el_read_getfn(struct el_read_t *el_read) -{ - return el_read->read_char == read_char ? - EL_BUILTIN_GETCFN : el_read->read_char; -} - - -/* read__fixio(): - * Try to recover from a read error - */ -/* ARGSUSED */ -static int -read__fixio(int fd __attribute__((__unused__)), int e) -{ - - switch (e) { - case -1: /* Make sure that the code is reachable */ - -#ifdef EWOULDBLOCK - case EWOULDBLOCK: -#ifndef TRY_AGAIN -#define TRY_AGAIN -#endif -#endif /* EWOULDBLOCK */ - -#if defined(POSIX) && defined(EAGAIN) -#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EAGAIN: -#ifndef TRY_AGAIN -#define TRY_AGAIN -#endif -#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ -#endif /* POSIX && EAGAIN */ - - e = 0; -#ifdef TRY_AGAIN -#if defined(F_SETFL) && defined(O_NDELAY) - if ((e = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - - if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) - return -1; - else - e = 1; -#endif /* F_SETFL && O_NDELAY */ - -#ifdef FIONBIO - { - int zero = 0; - - if (ioctl(fd, FIONBIO, &zero) == -1) - return -1; - else - e = 1; - } -#endif /* FIONBIO */ - -#endif /* TRY_AGAIN */ - return e ? 0 : -1; - - case EINTR: - return 0; - - default: - return -1; - } -} - - -/* el_push(): - * Push a macro - */ -void -el_wpush(EditLine *el, const wchar_t *str) -{ - struct macros *ma = &el->el_read->macros; - - if (str != NULL && ma->level + 1 < EL_MAXMACRO) { - ma->level++; - if ((ma->macro[ma->level] = wcsdup(str)) != NULL) - return; - ma->level--; - } - terminal_beep(el); - terminal__flush(el); -} - - -/* read_getcmd(): - * Get next command from the input stream, - * return 0 on success or -1 on EOF or error. - * Character values > 255 are not looked up in the map, but inserted. - */ -static int -read_getcmd(EditLine *el, el_action_t *cmdnum, wchar_t *ch) -{ - static const wchar_t meta = (wchar_t)0x80; - el_action_t cmd; - int num; - - do { - if ((num = el_wgetc(el, ch)) != 1) - return -1; - -#ifdef KANJI - if ((*ch & meta)) { - el->el_state.metanext = 0; - cmd = CcViMap[' ']; - break; - } else -#endif /* KANJI */ - - if (el->el_state.metanext) { - el->el_state.metanext = 0; - *ch |= meta; - } - if (*ch >= N_KEYS) - cmd = ED_INSERT; - else - cmd = el->el_map.current[(unsigned char) *ch]; - if (cmd == ED_SEQUENCE_LEAD_IN) { - keymacro_value_t val; - switch (keymacro_get(el, ch, &val)) { - case XK_CMD: - cmd = val.cmd; - break; - case XK_STR: - el_wpush(el, val.str); - break; - case XK_NOD: - return -1; - default: - EL_ABORT((el->el_errfile, "Bad XK_ type \n")); - break; - } - } - } while (cmd == ED_SEQUENCE_LEAD_IN); - *cmdnum = cmd; - return 0; -} - -/* read_char(): - * Read a character from the tty. - */ -static int -read_char(EditLine *el, wchar_t *cp) -{ - ssize_t num_read; - int tried = 0; - char cbuf[MB_LEN_MAX]; - size_t cbp = 0; - int save_errno = errno; - - again: - el->el_signal->sig_no = 0; - while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) { - int e = errno; - switch (el->el_signal->sig_no) { - case SIGCONT: - el_wset(el, EL_REFRESH); - /*FALLTHROUGH*/ - case SIGWINCH: - sig_set(el); - goto again; - default: - break; - } - if (!tried && read__fixio(el->el_infd, e) == 0) { - errno = save_errno; - tried = 1; - } else { - errno = e; - *cp = L'\0'; - return -1; - } - } - - /* Test for EOF */ - if (num_read == 0) { - *cp = L'\0'; - return 0; - } - - for (;;) { - mbstate_t mbs; - - ++cbp; - /* This only works because UTF8 is stateless. */ - memset(&mbs, 0, sizeof(mbs)); - switch (mbrtowc(cp, cbuf, cbp, &mbs)) { - case (size_t)-1: - if (cbp > 1) { - /* - * Invalid sequence, discard all bytes - * except the last one. - */ - cbuf[0] = cbuf[cbp - 1]; - cbp = 0; - break; - } else { - /* Invalid byte, discard it. */ - cbp = 0; - goto again; - } - case (size_t)-2: - /* - * We don't support other multibyte charsets. - * The second condition shouldn't happen - * and is here merely for additional safety. - */ - if ((el->el_flags & CHARSET_IS_UTF8) == 0 || - cbp >= MB_LEN_MAX) { - errno = EILSEQ; - *cp = L'\0'; - return -1; - } - /* Incomplete sequence, read another byte. */ - goto again; - default: - /* Valid character, process it. */ - return 1; - } - } -} - -/* read_pop(): - * Pop a macro from the stack - */ -static void -read_pop(struct macros *ma) -{ - int i; - - el_free(ma->macro[0]); - for (i = 0; i < ma->level; i++) - ma->macro[i] = ma->macro[i + 1]; - ma->level--; - ma->offset = 0; -} - -static void -read_clearmacros(struct macros *ma) -{ - while (ma->level >= 0) - el_free(ma->macro[ma->level--]); - ma->offset = 0; -} - -/* el_wgetc(): - * Read a wide character - */ -int -el_wgetc(EditLine *el, wchar_t *cp) -{ - struct macros *ma = &el->el_read->macros; - int num_read; - - terminal__flush(el); - for (;;) { - if (ma->level < 0) - break; - - if (ma->macro[0][ma->offset] == '\0') { - read_pop(ma); - continue; - } - - *cp = ma->macro[0][ma->offset++]; - - if (ma->macro[0][ma->offset] == '\0') { - /* Needed for QuoteMode On */ - read_pop(ma); - } - - return 1; - } - - if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ - return 0; - - num_read = (*el->el_read->read_char)(el, cp); - - /* - * Remember the original reason of a read failure - * such that el_wgets() can restore it after doing - * various cleanup operation that might change errno. - */ - if (num_read < 0) - el->el_read->read_errno = errno; - - return num_read; -} - -libedit_private void -read_prepare(EditLine *el) -{ - if (el->el_flags & HANDLE_SIGNALS) - sig_set(el); - if (el->el_flags & NO_TTY) - return; - if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED) - tty_rawmode(el); - - /* This is relatively cheap, and things go terribly wrong if - we have the wrong size. */ - el_resize(el); - re_clear_display(el); /* reset the display stuff */ - ch_reset(el); - re_refresh(el); /* print the prompt */ - - if (el->el_flags & UNBUFFERED) - terminal__flush(el); -} - -libedit_private void -read_finish(EditLine *el) -{ - if ((el->el_flags & UNBUFFERED) == 0) - (void) tty_cookedmode(el); - if (el->el_flags & HANDLE_SIGNALS) - sig_clr(el); -} - -static const wchar_t * -noedit_wgets(EditLine *el, int *nread) -{ - el_line_t *lp = &el->el_line; - int num; - - while ((num = (*el->el_read->read_char)(el, lp->lastchar)) == 1) { - if (lp->lastchar + 1 >= lp->limit && - !ch_enlargebufs(el, (size_t)2)) - break; - lp->lastchar++; - if (el->el_flags & UNBUFFERED || - lp->lastchar[-1] == '\r' || - lp->lastchar[-1] == '\n') - break; - } - if (num == -1 && errno == EINTR) - lp->lastchar = lp->buffer; - lp->cursor = lp->lastchar; - *lp->lastchar = '\0'; - *nread = (int)(lp->lastchar - lp->buffer); - return *nread ? lp->buffer : NULL; -} - -const wchar_t * -el_wgets(EditLine *el, int *nread) -{ - int retval; - el_action_t cmdnum = 0; - int num; /* how many chars we have read at NL */ - wchar_t ch; - int nrb; - - if (nread == NULL) - nread = &nrb; - *nread = 0; - el->el_read->read_errno = 0; - - if (el->el_flags & NO_TTY) { - el->el_line.lastchar = el->el_line.buffer; - return noedit_wgets(el, nread); - } - -#ifdef FIONREAD - if (el->el_tty.t_mode == EX_IO && el->el_read->macros.level < 0) { - int chrs = 0; - - (void) ioctl(el->el_infd, FIONREAD, &chrs); - if (chrs == 0) { - if (tty_rawmode(el) < 0) { - errno = 0; - *nread = 0; - return NULL; - } - } - } -#endif /* FIONREAD */ - - if ((el->el_flags & UNBUFFERED) == 0) - read_prepare(el); - - if (el->el_flags & EDIT_DISABLED) { - if ((el->el_flags & UNBUFFERED) == 0) - el->el_line.lastchar = el->el_line.buffer; - terminal__flush(el); - return noedit_wgets(el, nread); - } - - for (num = -1; num == -1;) { /* while still editing this line */ - /* if EOF or error */ - if (read_getcmd(el, &cmdnum, &ch) == -1) - break; - if ((size_t)cmdnum >= el->el_map.nfunc) /* BUG CHECK command */ - continue; /* try again */ - /* now do the real command */ - /* vi redo needs these way down the levels... */ - el->el_state.thiscmd = cmdnum; - el->el_state.thisch = ch; - if (el->el_map.type == MAP_VI && - el->el_map.current == el->el_map.key && - el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { - if (cmdnum == VI_DELETE_PREV_CHAR && - el->el_chared.c_redo.pos != el->el_chared.c_redo.buf - && iswprint(el->el_chared.c_redo.pos[-1])) - el->el_chared.c_redo.pos--; - else - *el->el_chared.c_redo.pos++ = ch; - } - retval = (*el->el_map.func[cmdnum]) (el, ch); - - /* save the last command here */ - el->el_state.lastcmd = cmdnum; - - /* use any return value */ - switch (retval) { - case CC_CURSOR: - re_refresh_cursor(el); - break; - - case CC_REDISPLAY: - re_clear_lines(el); - re_clear_display(el); - /* FALLTHROUGH */ - - case CC_REFRESH: - re_refresh(el); - break; - - case CC_REFRESH_BEEP: - re_refresh(el); - terminal_beep(el); - break; - - case CC_NORM: /* normal char */ - break; - - case CC_ARGHACK: /* Suggested by Rich Salz */ - /* */ - continue; /* keep going... */ - - case CC_EOF: /* end of file typed */ - if ((el->el_flags & UNBUFFERED) == 0) - num = 0; - else if (num == -1) { - *el->el_line.lastchar++ = CONTROL('d'); - el->el_line.cursor = el->el_line.lastchar; - num = 1; - } - break; - - case CC_NEWLINE: /* normal end of line */ - num = (int)(el->el_line.lastchar - el->el_line.buffer); - break; - - case CC_FATAL: /* fatal error, reset to known state */ - /* put (real) cursor in a known place */ - re_clear_display(el); /* reset the display stuff */ - ch_reset(el); /* reset the input pointers */ - read_clearmacros(&el->el_read->macros); - re_refresh(el); /* print the prompt again */ - break; - - case CC_ERROR: - default: /* functions we don't know about */ - terminal_beep(el); - terminal__flush(el); - break; - } - el->el_state.argument = 1; - el->el_state.doingarg = 0; - el->el_chared.c_vcmd.action = NOP; - if (el->el_flags & UNBUFFERED) - break; - } - - terminal__flush(el); /* flush any buffered output */ - /* make sure the tty is set up correctly */ - if ((el->el_flags & UNBUFFERED) == 0) { - read_finish(el); - *nread = num != -1 ? num : 0; - } else - *nread = (int)(el->el_line.lastchar - el->el_line.buffer); - - if (*nread == 0) { - if (num == -1) { - *nread = -1; - if (el->el_read->read_errno) - errno = el->el_read->read_errno; - } - return NULL; - } else - return el->el_line.buffer; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/read.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/read.h deleted file mode 100644 index 1acf5d6..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/read.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $NetBSD: read.h,v 1.12 2016/05/22 19:44:26 christos Exp $ */ - -/*- - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Anthony Mallet. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* - * el.read.h: Character reading functions - */ -#ifndef _h_el_read -#define _h_el_read - -libedit_private int read_init(EditLine *); -libedit_private void read_end(struct el_read_t *); -libedit_private void read_prepare(EditLine *); -libedit_private void read_finish(EditLine *); -libedit_private int el_read_setfn(struct el_read_t *, el_rfunc_t); -libedit_private el_rfunc_t el_read_getfn(struct el_read_t *); - -#endif /* _h_el_read */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/readline.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/readline.c deleted file mode 100644 index 965dd88..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/readline.c +++ /dev/null @@ -1,2370 +0,0 @@ -/* $NetBSD: readline.c,v 1.140 2017/01/09 03:09:05 christos Exp $ */ - -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: readline.c,v 1.140 2017/01/09 03:09:05 christos Exp $"); -#endif /* not lint && not SCCSID */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "editline/readline.h" -#include "el.h" -#include "fcns.h" -#include "filecomplete.h" - -#if !defined(SIZE_T_MAX) -# define SIZE_T_MAX (size_t)(-1) -#endif - -#if !defined(PATH_MAX) -# define PATH_MAX 4096 -#endif - -void rl_prep_terminal(int); -void rl_deprep_terminal(void); - -/* for rl_complete() */ -#define TAB '\r' - -/* see comment at the #ifdef for sense of this */ -/* #define GDB_411_HACK */ - -/* readline compatibility stuff - look at readline sources/documentation */ -/* to see what these variables mean */ -const char *rl_library_version = "EditLine wrapper"; -int rl_readline_version = RL_READLINE_VERSION; -static char empty[] = { '\0' }; -static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; -static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', - '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; -char *rl_readline_name = empty; -FILE *rl_instream = NULL; -FILE *rl_outstream = NULL; -int rl_point = 0; -int rl_end = 0; -char *rl_line_buffer = NULL; -rl_vcpfunc_t *rl_linefunc = NULL; -int rl_done = 0; -VFunction *rl_event_hook = NULL; -KEYMAP_ENTRY_ARRAY emacs_standard_keymap, - emacs_meta_keymap, - emacs_ctlx_keymap; -/* - * The following is not implemented; we always catch signals in the - * libedit fashion: set handlers on entry to el_gets() and clear them - * on the way out. This simplistic approach works for most cases; if - * it does not work for your application, please let us know. - */ -int rl_catch_signals = 1; -int rl_catch_sigwinch = 1; - -int history_base = 1; /* probably never subject to change */ -int history_length = 0; -int history_offset = 0; -int max_input_history = 0; -char history_expansion_char = '!'; -char history_subst_char = '^'; -char *history_no_expand_chars = expand_chars; -Function *history_inhibit_expansion_function = NULL; -char *history_arg_extract(int start, int end, const char *str); - -int rl_inhibit_completion = 0; -int rl_attempted_completion_over = 0; -char *rl_basic_word_break_characters = break_chars; -char *rl_completer_word_break_characters = NULL; -char *rl_completer_quote_characters = NULL; -rl_compentry_func_t *rl_completion_entry_function = NULL; -char *(*rl_completion_word_break_hook)(void) = NULL; -rl_completion_func_t *rl_attempted_completion_function = NULL; -Function *rl_pre_input_hook = NULL; -Function *rl_startup1_hook = NULL; -int (*rl_getc_function)(FILE *) = NULL; -char *rl_terminal_name = NULL; -int rl_already_prompted = 0; -int rl_filename_completion_desired = 0; -int rl_ignore_completion_duplicates = 0; -int readline_echoing_p = 1; -int _rl_print_completions_horizontally = 0; -VFunction *rl_redisplay_function = NULL; -Function *rl_startup_hook = NULL; -VFunction *rl_completion_display_matches_hook = NULL; -VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; -VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; -KEYMAP_ENTRY_ARRAY emacs_meta_keymap; - -/* - * The current prompt string. - */ -char *rl_prompt = NULL; -/* - * This is set to character indicating type of completion being done by - * rl_complete_internal(); this is available for application completion - * functions. - */ -int rl_completion_type = 0; - -/* - * If more than this number of items results from query for possible - * completions, we ask user if they are sure to really display the list. - */ -int rl_completion_query_items = 100; - -/* - * List of characters which are word break characters, but should be left - * in the parsed text when it is passed to the completion function. - * Shell uses this to help determine what kind of completing to do. - */ -char *rl_special_prefixes = NULL; - -/* - * This is the character appended to the completed words if at the end of - * the line. Default is ' ' (a space). - */ -int rl_completion_append_character = ' '; - -/* stuff below is used internally by libedit for readline emulation */ - -static History *h = NULL; -static EditLine *e = NULL; -static rl_command_func_t *map[256]; -static jmp_buf topbuf; - -/* internal functions */ -static unsigned char _el_rl_complete(EditLine *, int); -static unsigned char _el_rl_tstp(EditLine *, int); -static char *_get_prompt(EditLine *); -static int _getc_function(EditLine *, wchar_t *); -static int _history_expand_command(const char *, size_t, size_t, - char **); -static char *_rl_compat_sub(const char *, const char *, - const char *, int); -static int _rl_event_read_char(EditLine *, wchar_t *); -static void _rl_update_pos(void); - -static HIST_ENTRY rl_he; - -/* ARGSUSED */ -static char * -_get_prompt(EditLine *el __attribute__((__unused__))) -{ - rl_already_prompted = 1; - return rl_prompt; -} - - -/* - * read one key from user defined input function - */ -static int -/*ARGSUSED*/ -_getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c) -{ - int i; - - i = (*rl_getc_function)(rl_instream); - if (i == -1) - return 0; - *c = (wchar_t)i; - return 1; -} - -static void -_resize_fun(EditLine *el, void *a) -{ - const LineInfo *li; - char **ap = a; - - li = el_line(el); - /* a cheesy way to get rid of const cast. */ - *ap = memchr(li->buffer, *li->buffer, (size_t)1); -} - -static const char * -_default_history_file(void) -{ - struct passwd *p; - static char *path; - size_t len; - - if (path) - return path; - - if ((p = getpwuid(getuid())) == NULL) - return NULL; - - len = strlen(p->pw_dir) + sizeof("/.history"); - if ((path = malloc(len)) == NULL) - return NULL; - - (void)snprintf(path, len, "%s/.history", p->pw_dir); - return path; -} - -/* - * READLINE compatibility stuff - */ - -/* - * Set the prompt - */ -int -rl_set_prompt(const char *prompt) -{ - char *p; - - if (!prompt) - prompt = ""; - if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) - return 0; - if (rl_prompt) - el_free(rl_prompt); - rl_prompt = strdup(prompt); - if (rl_prompt == NULL) - return -1; - - while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL) - *p = RL_PROMPT_START_IGNORE; - - return 0; -} - -/* - * initialize rl compat stuff - */ -int -rl_initialize(void) -{ - HistEvent ev; - int editmode = 1; - struct termios t; - - if (e != NULL) - el_end(e); - if (h != NULL) - history_end(h); - - if (!rl_instream) - rl_instream = stdin; - if (!rl_outstream) - rl_outstream = stdout; - - /* - * See if we don't really want to run the editor - */ - if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0) - editmode = 0; - - e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr); - - if (!editmode) - el_set(e, EL_EDITMODE, 0); - - h = history_init(); - if (!e || !h) - return -1; - - history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ - history_length = 0; - max_input_history = INT_MAX; - el_set(e, EL_HIST, history, h); - - /* Setup resize function */ - el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer); - - /* setup getc function if valid */ - if (rl_getc_function) - el_set(e, EL_GETCFN, _getc_function); - - /* for proper prompt printing in readline() */ - if (rl_set_prompt("") == -1) { - history_end(h); - el_end(e); - return -1; - } - el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE); - el_set(e, EL_SIGNAL, rl_catch_signals); - - /* set default mode to "emacs"-style and read setting afterwards */ - /* so this can be overridden */ - el_set(e, EL_EDITOR, "emacs"); - if (rl_terminal_name != NULL) - el_set(e, EL_TERMINAL, rl_terminal_name); - else - el_get(e, EL_TERMINAL, &rl_terminal_name); - - /* - * Word completion - this has to go AFTER rebinding keys - * to emacs-style. - */ - el_set(e, EL_ADDFN, "rl_complete", - "ReadLine compatible completion function", - _el_rl_complete); - el_set(e, EL_BIND, "^I", "rl_complete", NULL); - - /* - * Send TSTP when ^Z is pressed. - */ - el_set(e, EL_ADDFN, "rl_tstp", - "ReadLine compatible suspend function", - _el_rl_tstp); - el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); - - /* - * Set some readline compatible key-bindings. - */ - el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL); - - /* - * Allow the use of Home/End keys. - */ - el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL); - el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL); - el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL); - el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL); - el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL); - el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL); - - /* - * Allow the use of the Delete/Insert keys. - */ - el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL); - el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL); - - /* - * Ctrl-left-arrow and Ctrl-right-arrow for word moving. - */ - el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL); - el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL); - el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL); - el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL); - el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL); - el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); - - /* read settings from configuration file */ - el_source(e, NULL); - - /* - * Unfortunately, some applications really do use rl_point - * and rl_line_buffer directly. - */ - _resize_fun(e, &rl_line_buffer); - _rl_update_pos(); - - if (rl_startup_hook) - (*rl_startup_hook)(NULL, 0); - - return 0; -} - - -/* - * read one line from input stream and return it, chomping - * trailing newline (if there is any) - */ -char * -readline(const char *p) -{ - HistEvent ev; - const char * volatile prompt = p; - int count; - const char *ret; - char *buf; - static int used_event_hook; - - if (e == NULL || h == NULL) - rl_initialize(); - - rl_done = 0; - - (void)setjmp(topbuf); - - /* update prompt accordingly to what has been passed */ - if (rl_set_prompt(prompt) == -1) - return NULL; - - if (rl_pre_input_hook) - (*rl_pre_input_hook)(NULL, 0); - - if (rl_event_hook && !(e->el_flags&NO_TTY)) { - el_set(e, EL_GETCFN, _rl_event_read_char); - used_event_hook = 1; - } - - if (!rl_event_hook && used_event_hook) { - el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN); - used_event_hook = 0; - } - - rl_already_prompted = 0; - - /* get one line from input stream */ - ret = el_gets(e, &count); - - if (ret && count > 0) { - int lastidx; - - buf = strdup(ret); - if (buf == NULL) - return NULL; - lastidx = count - 1; - if (buf[lastidx] == '\n') - buf[lastidx] = '\0'; - } else - buf = NULL; - - history(h, &ev, H_GETSIZE); - history_length = ev.num; - - return buf; -} - -/* - * history functions - */ - -/* - * is normally called before application starts to use - * history expansion functions - */ -void -using_history(void) -{ - if (h == NULL || e == NULL) - rl_initialize(); - history_offset = history_length; -} - - -/* - * substitute ``what'' with ``with'', returning resulting string; if - * globally == 1, substitutes all occurrences of what, otherwise only the - * first one - */ -static char * -_rl_compat_sub(const char *str, const char *what, const char *with, - int globally) -{ - const char *s; - char *r, *result; - size_t len, with_len, what_len; - - len = strlen(str); - with_len = strlen(with); - what_len = strlen(what); - - /* calculate length we need for result */ - s = str; - while (*s) { - if (*s == *what && !strncmp(s, what, what_len)) { - len += with_len - what_len; - if (!globally) - break; - s += what_len; - } else - s++; - } - r = result = el_malloc((len + 1) * sizeof(*r)); - if (result == NULL) - return NULL; - s = str; - while (*s) { - if (*s == *what && !strncmp(s, what, what_len)) { - (void)strncpy(r, with, with_len); - r += with_len; - s += what_len; - if (!globally) { - (void)strcpy(r, s); - return result; - } - } else - *r++ = *s++; - } - *r = '\0'; - return result; -} - -static char *last_search_pat; /* last !?pat[?] search pattern */ -static char *last_search_match; /* last !?pat[?] that matched */ - -const char * -get_history_event(const char *cmd, int *cindex, int qchar) -{ - int idx, sign, sub, num, begin, ret; - size_t len; - char *pat; - const char *rptr; - HistEvent ev; - - idx = *cindex; - if (cmd[idx++] != history_expansion_char) - return NULL; - - /* find out which event to take */ - if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') { - if (history(h, &ev, H_FIRST) != 0) - return NULL; - *cindex = cmd[idx]? (idx + 1):idx; - return ev.str; - } - sign = 0; - if (cmd[idx] == '-') { - sign = 1; - idx++; - } - - if ('0' <= cmd[idx] && cmd[idx] <= '9') { - HIST_ENTRY *he; - - num = 0; - while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') { - num = num * 10 + cmd[idx] - '0'; - idx++; - } - if (sign) - num = history_length - num + history_base; - - if (!(he = history_get(num))) - return NULL; - - *cindex = idx; - return he->line; - } - sub = 0; - if (cmd[idx] == '?') { - sub = 1; - idx++; - } - begin = idx; - while (cmd[idx]) { - if (cmd[idx] == '\n') - break; - if (sub && cmd[idx] == '?') - break; - if (!sub && (cmd[idx] == ':' || cmd[idx] == ' ' - || cmd[idx] == '\t' || cmd[idx] == qchar)) - break; - idx++; - } - len = (size_t)idx - (size_t)begin; - if (sub && cmd[idx] == '?') - idx++; - if (sub && len == 0 && last_search_pat && *last_search_pat) - pat = last_search_pat; - else if (len == 0) - return NULL; - else { - if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL) - return NULL; - (void)strncpy(pat, cmd + begin, len); - pat[len] = '\0'; - } - - if (history(h, &ev, H_CURR) != 0) { - if (pat != last_search_pat) - el_free(pat); - return NULL; - } - num = ev.num; - - if (sub) { - if (pat != last_search_pat) { - if (last_search_pat) - el_free(last_search_pat); - last_search_pat = pat; - } - ret = history_search(pat, -1); - } else - ret = history_search_prefix(pat, -1); - - if (ret == -1) { - /* restore to end of list on failed search */ - history(h, &ev, H_FIRST); - (void)fprintf(rl_outstream, "%s: Event not found\n", pat); - if (pat != last_search_pat) - el_free(pat); - return NULL; - } - - if (sub && len) { - if (last_search_match && last_search_match != pat) - el_free(last_search_match); - last_search_match = pat; - } - - if (pat != last_search_pat) - el_free(pat); - - if (history(h, &ev, H_CURR) != 0) - return NULL; - *cindex = idx; - rptr = ev.str; - - /* roll back to original position */ - (void)history(h, &ev, H_SET, num); - - return rptr; -} - -/* - * the real function doing history expansion - takes as argument command - * to do and data upon which the command should be executed - * does expansion the way I've understood readline documentation - * - * returns 0 if data was not modified, 1 if it was and 2 if the string - * should be only printed and not executed; in case of error, - * returns -1 and *result points to NULL - * it's the caller's responsibility to free() the string returned in *result - */ -static int -_history_expand_command(const char *command, size_t offs, size_t cmdlen, - char **result) -{ - char *tmp, *search = NULL, *aptr; - const char *ptr, *cmd; - static char *from = NULL, *to = NULL; - int start, end, idx, has_mods = 0; - int p_on = 0, g_on = 0; - - *result = NULL; - aptr = NULL; - ptr = NULL; - - /* First get event specifier */ - idx = 0; - - if (strchr(":^*$", command[offs + 1])) { - char str[4]; - /* - * "!:" is shorthand for "!!:". - * "!^", "!*" and "!$" are shorthand for - * "!!:^", "!!:*" and "!!:$" respectively. - */ - str[0] = str[1] = '!'; - str[2] = '0'; - ptr = get_history_event(str, &idx, 0); - idx = (command[offs + 1] == ':')? 1:0; - has_mods = 1; - } else { - if (command[offs + 1] == '#') { - /* use command so far */ - if ((aptr = el_malloc((offs + 1) * sizeof(*aptr))) - == NULL) - return -1; - (void)strncpy(aptr, command, offs); - aptr[offs] = '\0'; - idx = 1; - } else { - int qchar; - - qchar = (offs > 0 && command[offs - 1] == '"')? '"':0; - ptr = get_history_event(command + offs, &idx, qchar); - } - has_mods = command[offs + (size_t)idx] == ':'; - } - - if (ptr == NULL && aptr == NULL) - return -1; - - if (!has_mods) { - *result = strdup(aptr ? aptr : ptr); - if (aptr) - el_free(aptr); - if (*result == NULL) - return -1; - return 1; - } - - cmd = command + offs + idx + 1; - - /* Now parse any word designators */ - - if (*cmd == '%') /* last word matched by ?pat? */ - tmp = strdup(last_search_match? last_search_match:""); - else if (strchr("^*$-0123456789", *cmd)) { - start = end = -1; - if (*cmd == '^') - start = end = 1, cmd++; - else if (*cmd == '$') - start = -1, cmd++; - else if (*cmd == '*') - start = 1, cmd++; - else if (*cmd == '-' || isdigit((unsigned char) *cmd)) { - start = 0; - while (*cmd && '0' <= *cmd && *cmd <= '9') - start = start * 10 + *cmd++ - '0'; - - if (*cmd == '-') { - if (isdigit((unsigned char) cmd[1])) { - cmd++; - end = 0; - while (*cmd && '0' <= *cmd && *cmd <= '9') - end = end * 10 + *cmd++ - '0'; - } else if (cmd[1] == '$') { - cmd += 2; - end = -1; - } else { - cmd++; - end = -2; - } - } else if (*cmd == '*') - end = -1, cmd++; - else - end = start; - } - tmp = history_arg_extract(start, end, aptr? aptr:ptr); - if (tmp == NULL) { - (void)fprintf(rl_outstream, "%s: Bad word specifier", - command + offs + idx); - if (aptr) - el_free(aptr); - return -1; - } - } else - tmp = strdup(aptr? aptr:ptr); - - if (aptr) - el_free(aptr); - - if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { - *result = tmp; - return 1; - } - - for (; *cmd; cmd++) { - if (*cmd == ':') - continue; - else if (*cmd == 'h') { /* remove trailing path */ - if ((aptr = strrchr(tmp, '/')) != NULL) - *aptr = '\0'; - } else if (*cmd == 't') { /* remove leading path */ - if ((aptr = strrchr(tmp, '/')) != NULL) { - aptr = strdup(aptr + 1); - el_free(tmp); - tmp = aptr; - } - } else if (*cmd == 'r') { /* remove trailing suffix */ - if ((aptr = strrchr(tmp, '.')) != NULL) - *aptr = '\0'; - } else if (*cmd == 'e') { /* remove all but suffix */ - if ((aptr = strrchr(tmp, '.')) != NULL) { - aptr = strdup(aptr); - el_free(tmp); - tmp = aptr; - } - } else if (*cmd == 'p') /* print only */ - p_on = 1; - else if (*cmd == 'g') - g_on = 2; - else if (*cmd == 's' || *cmd == '&') { - char *what, *with, delim; - size_t len, from_len; - size_t size; - - if (*cmd == '&' && (from == NULL || to == NULL)) - continue; - else if (*cmd == 's') { - delim = *(++cmd), cmd++; - size = 16; - what = el_realloc(from, size * sizeof(*what)); - if (what == NULL) { - el_free(from); - el_free(tmp); - return 0; - } - len = 0; - for (; *cmd && *cmd != delim; cmd++) { - if (*cmd == '\\' && cmd[1] == delim) - cmd++; - if (len >= size) { - char *nwhat; - nwhat = el_realloc(what, - (size <<= 1) * - sizeof(*nwhat)); - if (nwhat == NULL) { - el_free(what); - el_free(tmp); - return 0; - } - what = nwhat; - } - what[len++] = *cmd; - } - what[len] = '\0'; - from = what; - if (*what == '\0') { - el_free(what); - if (search) { - from = strdup(search); - if (from == NULL) { - el_free(tmp); - return 0; - } - } else { - from = NULL; - el_free(tmp); - return -1; - } - } - cmd++; /* shift after delim */ - if (!*cmd) - continue; - - size = 16; - with = el_realloc(to, size * sizeof(*with)); - if (with == NULL) { - el_free(to); - el_free(tmp); - return -1; - } - len = 0; - from_len = strlen(from); - for (; *cmd && *cmd != delim; cmd++) { - if (len + from_len + 1 >= size) { - char *nwith; - size += from_len + 1; - nwith = el_realloc(with, - size * sizeof(*nwith)); - if (nwith == NULL) { - el_free(with); - el_free(tmp); - return -1; - } - with = nwith; - } - if (*cmd == '&') { - /* safe */ - (void)strcpy(&with[len], from); - len += from_len; - continue; - } - if (*cmd == '\\' - && (*(cmd + 1) == delim - || *(cmd + 1) == '&')) - cmd++; - with[len++] = *cmd; - } - with[len] = '\0'; - to = with; - } - - aptr = _rl_compat_sub(tmp, from, to, g_on); - if (aptr) { - el_free(tmp); - tmp = aptr; - } - g_on = 0; - } - } - *result = tmp; - return p_on? 2:1; -} - - -/* - * csh-style history expansion - */ -int -history_expand(char *str, char **output) -{ - int ret = 0; - size_t idx, i, size; - char *tmp, *result; - - if (h == NULL || e == NULL) - rl_initialize(); - - if (history_expansion_char == 0) { - *output = strdup(str); - return 0; - } - - *output = NULL; - if (str[0] == history_subst_char) { - /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ - *output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output)); - if (*output == NULL) - return 0; - (*output)[0] = (*output)[1] = history_expansion_char; - (*output)[2] = ':'; - (*output)[3] = 's'; - (void)strcpy((*output) + 4, str); - str = *output; - } else { - *output = strdup(str); - if (*output == NULL) - return 0; - } - -#define ADD_STRING(what, len, fr) \ - { \ - if (idx + len + 1 > size) { \ - char *nresult = el_realloc(result, \ - (size += len + 1) * sizeof(*nresult)); \ - if (nresult == NULL) { \ - el_free(*output); \ - if (/*CONSTCOND*/fr) \ - el_free(tmp); \ - return 0; \ - } \ - result = nresult; \ - } \ - (void)strncpy(&result[idx], what, len); \ - idx += len; \ - result[idx] = '\0'; \ - } - - result = NULL; - size = idx = 0; - tmp = NULL; - for (i = 0; str[i];) { - int qchar, loop_again; - size_t len, start, j; - - qchar = 0; - loop_again = 1; - start = j = i; -loop: - for (; str[j]; j++) { - if (str[j] == '\\' && - str[j + 1] == history_expansion_char) { - len = strlen(&str[j + 1]) + 1; - memmove(&str[j], &str[j + 1], len); - continue; - } - if (!loop_again) { - if (isspace((unsigned char) str[j]) - || str[j] == qchar) - break; - } - if (str[j] == history_expansion_char - && !strchr(history_no_expand_chars, str[j + 1]) - && (!history_inhibit_expansion_function || - (*history_inhibit_expansion_function)(str, - (int)j) == 0)) - break; - } - - if (str[j] && loop_again) { - i = j; - qchar = (j > 0 && str[j - 1] == '"' )? '"':0; - j++; - if (str[j] == history_expansion_char) - j++; - loop_again = 0; - goto loop; - } - len = i - start; - ADD_STRING(&str[start], len, 0); - - if (str[i] == '\0' || str[i] != history_expansion_char) { - len = j - i; - ADD_STRING(&str[i], len, 0); - if (start == 0) - ret = 0; - else - ret = 1; - break; - } - ret = _history_expand_command (str, i, (j - i), &tmp); - if (ret > 0 && tmp) { - len = strlen(tmp); - ADD_STRING(tmp, len, 1); - } - if (tmp) { - el_free(tmp); - tmp = NULL; - } - i = j; - } - - /* ret is 2 for "print only" option */ - if (ret == 2) { - add_history(result); -#ifdef GDB_411_HACK - /* gdb 4.11 has been shipped with readline, where */ - /* history_expand() returned -1 when the line */ - /* should not be executed; in readline 2.1+ */ - /* it should return 2 in such a case */ - ret = -1; -#endif - } - el_free(*output); - *output = result; - - return ret; -} - -/* -* Return a string consisting of arguments of "str" from "start" to "end". -*/ -char * -history_arg_extract(int start, int end, const char *str) -{ - size_t i, len, max; - char **arr, *result = NULL; - - arr = history_tokenize(str); - if (!arr) - return NULL; - if (arr && *arr == NULL) - goto out; - - for (max = 0; arr[max]; max++) - continue; - max--; - - if (start == '$') - start = (int)max; - if (end == '$') - end = (int)max; - if (end < 0) - end = (int)max + end + 1; - if (start < 0) - start = end; - - if (start < 0 || end < 0 || (size_t)start > max || - (size_t)end > max || start > end) - goto out; - - for (i = (size_t)start, len = 0; i <= (size_t)end; i++) - len += strlen(arr[i]) + 1; - len++; - result = el_malloc(len * sizeof(*result)); - if (result == NULL) - goto out; - - for (i = (size_t)start, len = 0; i <= (size_t)end; i++) { - (void)strcpy(result + len, arr[i]); - len += strlen(arr[i]); - if (i < (size_t)end) - result[len++] = ' '; - } - result[len] = '\0'; - -out: - for (i = 0; arr[i]; i++) - el_free(arr[i]); - el_free(arr); - - return result; -} - -/* - * Parse the string into individual tokens, - * similar to how shell would do it. - */ -char ** -history_tokenize(const char *str) -{ - int size = 1, idx = 0, i, start; - size_t len; - char **result = NULL, *temp, delim = '\0'; - - for (i = 0; str[i];) { - while (isspace((unsigned char) str[i])) - i++; - start = i; - for (; str[i];) { - if (str[i] == '\\') { - if (str[i+1] != '\0') - i++; - } else if (str[i] == delim) - delim = '\0'; - else if (!delim && - (isspace((unsigned char) str[i]) || - strchr("()<>;&|$", str[i]))) - break; - else if (!delim && strchr("'`\"", str[i])) - delim = str[i]; - if (str[i]) - i++; - } - - if (idx + 2 >= size) { - char **nresult; - size <<= 1; - nresult = el_realloc(result, (size_t)size * sizeof(*nresult)); - if (nresult == NULL) { - el_free(result); - return NULL; - } - result = nresult; - } - len = (size_t)i - (size_t)start; - temp = el_malloc((size_t)(len + 1) * sizeof(*temp)); - if (temp == NULL) { - for (i = 0; i < idx; i++) - el_free(result[i]); - el_free(result); - return NULL; - } - (void)strncpy(temp, &str[start], len); - temp[len] = '\0'; - result[idx++] = temp; - result[idx] = NULL; - if (str[i]) - i++; - } - return result; -} - - -/* - * limit size of history record to ``max'' events - */ -void -stifle_history(int max) -{ - HistEvent ev; - HIST_ENTRY *he; - - if (h == NULL || e == NULL) - rl_initialize(); - - if (history(h, &ev, H_SETSIZE, max) == 0) { - max_input_history = max; - if (history_length > max) - history_base = history_length - max; - while (history_length > max) { - he = remove_history(0); - el_free(he->data); - el_free((void *)(unsigned long)he->line); - el_free(he); - } - } -} - - -/* - * "unlimit" size of history - set the limit to maximum allowed int value - */ -int -unstifle_history(void) -{ - HistEvent ev; - int omax; - - history(h, &ev, H_SETSIZE, INT_MAX); - omax = max_input_history; - max_input_history = INT_MAX; - return omax; /* some value _must_ be returned */ -} - - -int -history_is_stifled(void) -{ - - /* cannot return true answer */ - return max_input_history != INT_MAX; -} - -static const char _history_tmp_template[] = "/tmp/.historyXXXXXX"; - -int -history_truncate_file (const char *filename, int nlines) -{ - int ret = 0; - FILE *fp, *tp; - char template[sizeof(_history_tmp_template)]; - char buf[4096]; - int fd; - char *cp; - off_t off; - int count = 0; - ssize_t left = 0; - - if (filename == NULL && (filename = _default_history_file()) == NULL) - return errno; - if ((fp = fopen(filename, "r+")) == NULL) - return errno; - strcpy(template, _history_tmp_template); - if ((fd = mkstemp(template)) == -1) { - ret = errno; - goto out1; - } - - if ((tp = fdopen(fd, "r+")) == NULL) { - close(fd); - ret = errno; - goto out2; - } - - for(;;) { - if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) { - if (ferror(fp)) { - ret = errno; - break; - } - if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) == - (off_t)-1) { - ret = errno; - break; - } - left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp); - if (ferror(fp)) { - ret = errno; - break; - } - if (left == 0) { - count--; - left = sizeof(buf); - } else if (fwrite(buf, (size_t)left, (size_t)1, tp) - != 1) { - ret = errno; - break; - } - fflush(tp); - break; - } - if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) { - ret = errno; - break; - } - count++; - } - if (ret) - goto out3; - cp = buf + left - 1; - if(*cp != '\n') - cp++; - for(;;) { - while (--cp >= buf) { - if (*cp == '\n') { - if (--nlines == 0) { - if (++cp >= buf + sizeof(buf)) { - count++; - cp = buf; - } - break; - } - } - } - if (nlines <= 0 || count == 0) - break; - count--; - if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) { - ret = errno; - break; - } - if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) { - if (ferror(tp)) { - ret = errno; - break; - } - ret = EAGAIN; - break; - } - cp = buf + sizeof(buf); - } - - if (ret || nlines > 0) - goto out3; - - if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) { - ret = errno; - goto out3; - } - - if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) == - (off_t)-1) { - ret = errno; - goto out3; - } - - for(;;) { - if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) { - if (ferror(fp)) - ret = errno; - break; - } - if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) { - ret = errno; - break; - } - } - fflush(fp); - if((off = ftello(fp)) > 0) - (void)ftruncate(fileno(fp), off); -out3: - fclose(tp); -out2: - unlink(template); -out1: - fclose(fp); - - return ret; -} - - -/* - * read history from a file given - */ -int -read_history(const char *filename) -{ - HistEvent ev; - - if (h == NULL || e == NULL) - rl_initialize(); - if (filename == NULL && (filename = _default_history_file()) == NULL) - return errno; - return history(h, &ev, H_LOAD, filename) == -1 ? - (errno ? errno : EINVAL) : 0; -} - - -/* - * write history to a file given - */ -int -write_history(const char *filename) -{ - HistEvent ev; - - if (h == NULL || e == NULL) - rl_initialize(); - if (filename == NULL && (filename = _default_history_file()) == NULL) - return errno; - return history(h, &ev, H_SAVE, filename) == -1 ? - (errno ? errno : EINVAL) : 0; -} - - -/* - * returns history ``num''th event - * - * returned pointer points to static variable - */ -HIST_ENTRY * -history_get(int num) -{ - static HIST_ENTRY she; - HistEvent ev; - int curr_num; - - if (h == NULL || e == NULL) - rl_initialize(); - - if (num < history_base) - return NULL; - - /* save current position */ - if (history(h, &ev, H_CURR) != 0) - return NULL; - curr_num = ev.num; - - /* - * use H_DELDATA to set to nth history (without delete) by passing - * (void **)-1 -- as in history_set_pos - */ - if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0) - goto out; - - /* get current entry */ - if (history(h, &ev, H_CURR) != 0) - goto out; - if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0) - goto out; - she.line = ev.str; - - /* restore pointer to where it was */ - (void)history(h, &ev, H_SET, curr_num); - - return &she; - -out: - /* restore pointer to where it was */ - (void)history(h, &ev, H_SET, curr_num); - return NULL; -} - - -/* - * add the line to history table - */ -int -add_history(const char *line) -{ - HistEvent ev; - - if (h == NULL || e == NULL) - rl_initialize(); - - if (history(h, &ev, H_ENTER, line) == -1) - return 0; - - (void)history(h, &ev, H_GETSIZE); - if (ev.num == history_length) - history_base++; - else - history_length = ev.num; - return 0; -} - - -/* - * remove the specified entry from the history list and return it. - */ -HIST_ENTRY * -remove_history(int num) -{ - HIST_ENTRY *he; - HistEvent ev; - - if (h == NULL || e == NULL) - rl_initialize(); - - if ((he = el_malloc(sizeof(*he))) == NULL) - return NULL; - - if (history(h, &ev, H_DELDATA, num, &he->data) != 0) { - el_free(he); - return NULL; - } - - he->line = ev.str; - if (history(h, &ev, H_GETSIZE) == 0) - history_length = ev.num; - - return he; -} - - -/* - * replace the line and data of the num-th entry - */ -HIST_ENTRY * -replace_history_entry(int num, const char *line, histdata_t data) -{ - HIST_ENTRY *he; - HistEvent ev; - int curr_num; - - if (h == NULL || e == NULL) - rl_initialize(); - - /* save current position */ - if (history(h, &ev, H_CURR) != 0) - return NULL; - curr_num = ev.num; - - /* start from the oldest */ - if (history(h, &ev, H_LAST) != 0) - return NULL; /* error */ - - if ((he = el_malloc(sizeof(*he))) == NULL) - return NULL; - - /* look forwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVDATA, num, &he->data)) - goto out; - - he->line = strdup(ev.str); - if (he->line == NULL) - goto out; - - if (history(h, &ev, H_REPLACE, line, data)) - goto out; - - /* restore pointer to where it was */ - if (history(h, &ev, H_SET, curr_num)) - goto out; - - return he; -out: - el_free(he); - return NULL; -} - -/* - * clear the history list - delete all entries - */ -void -clear_history(void) -{ - HistEvent ev; - - if (h == NULL || e == NULL) - rl_initialize(); - - (void)history(h, &ev, H_CLEAR); - history_offset = history_length = 0; -} - - -/* - * returns offset of the current history event - */ -int -where_history(void) -{ - return history_offset; -} - -static HIST_ENTRY **_history_listp; -static HIST_ENTRY *_history_list; - -HIST_ENTRY ** -history_list(void) -{ - HistEvent ev; - HIST_ENTRY **nlp, *nl; - int i; - - if (history(h, &ev, H_LAST) != 0) - return NULL; - - if ((nlp = el_realloc(_history_listp, - (size_t)history_length * sizeof(*nlp))) == NULL) - return NULL; - _history_listp = nlp; - - if ((nl = el_realloc(_history_list, - (size_t)history_length * sizeof(*nl))) == NULL) - return NULL; - _history_list = nl; - - i = 0; - do { - _history_listp[i] = &_history_list[i]; - _history_list[i].line = ev.str; - _history_list[i].data = NULL; - if (i++ == history_length) - abort(); - } while (history(h, &ev, H_PREV) == 0); - return _history_listp; -} - -/* - * returns current history event or NULL if there is no such event - */ -HIST_ENTRY * -current_history(void) -{ - HistEvent ev; - - if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0) - return NULL; - - rl_he.line = ev.str; - rl_he.data = NULL; - return &rl_he; -} - - -/* - * returns total number of bytes history events' data are using - */ -int -history_total_bytes(void) -{ - HistEvent ev; - int curr_num; - size_t size; - - if (history(h, &ev, H_CURR) != 0) - return -1; - curr_num = ev.num; - - (void)history(h, &ev, H_FIRST); - size = 0; - do - size += strlen(ev.str) * sizeof(*ev.str); - while (history(h, &ev, H_NEXT) == 0); - - /* get to the same position as before */ - history(h, &ev, H_PREV_EVENT, curr_num); - - return (int)size; -} - - -/* - * sets the position in the history list to ``pos'' - */ -int -history_set_pos(int pos) -{ - if (pos >= history_length || pos < 0) - return 0; - - history_offset = pos; - return 1; -} - - -/* - * returns previous event in history and shifts pointer accordingly - * Note that readline and editline define directions in opposite ways. - */ -HIST_ENTRY * -previous_history(void) -{ - HistEvent ev; - - if (history_offset == 0) - return NULL; - - if (history(h, &ev, H_LAST) != 0) - return NULL; - - history_offset--; - return current_history(); -} - - -/* - * returns next event in history and shifts pointer accordingly - */ -HIST_ENTRY * -next_history(void) -{ - HistEvent ev; - - if (history_offset >= history_length) - return NULL; - - if (history(h, &ev, H_LAST) != 0) - return NULL; - - history_offset++; - return current_history(); -} - - -/* - * searches for first history event containing the str - */ -int -history_search(const char *str, int direction) -{ - HistEvent ev; - const char *strp; - int curr_num; - - if (history(h, &ev, H_CURR) != 0) - return -1; - curr_num = ev.num; - - for (;;) { - if ((strp = strstr(ev.str, str)) != NULL) - return (int)(strp - ev.str); - if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) - break; - } - (void)history(h, &ev, H_SET, curr_num); - return -1; -} - - -/* - * searches for first history event beginning with str - */ -int -history_search_prefix(const char *str, int direction) -{ - HistEvent ev; - - return (history(h, &ev, direction < 0 ? - H_PREV_STR : H_NEXT_STR, str)); -} - - -/* - * search for event in history containing str, starting at offset - * abs(pos); continue backward, if pos<0, forward otherwise - */ -/* ARGSUSED */ -int -history_search_pos(const char *str, - int direction __attribute__((__unused__)), int pos) -{ - HistEvent ev; - int curr_num, off; - - off = (pos > 0) ? pos : -pos; - pos = (pos > 0) ? 1 : -1; - - if (history(h, &ev, H_CURR) != 0) - return -1; - curr_num = ev.num; - - if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0) - return -1; - - for (;;) { - if (strstr(ev.str, str)) - return off; - if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) - break; - } - - /* set "current" pointer back to previous state */ - (void)history(h, &ev, - pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); - - return -1; -} - - -/********************************/ -/* completion functions */ - -char * -tilde_expand(char *name) -{ - return fn_tilde_expand(name); -} - -char * -filename_completion_function(const char *name, int state) -{ - return fn_filename_completion_function(name, state); -} - -/* - * a completion generator for usernames; returns _first_ username - * which starts with supplied text - * text contains a partial username preceded by random character - * (usually '~'); state resets search from start (??? should we do that anyway) - * it's the caller's responsibility to free the returned value - */ -char * -username_completion_function(const char *text, int state) -{ - struct passwd *pass = NULL; - - if (text[0] == '\0') - return NULL; - - if (*text == '~') - text++; - - if (state == 0) - setpwent(); - - while ( - (pass = getpwent()) != NULL - && text[0] == pass->pw_name[0] - && strcmp(text, pass->pw_name) == 0) - continue; - - if (pass == NULL) { - endpwent(); - return NULL; - } - return strdup(pass->pw_name); -} - - -/* - * el-compatible wrapper to send TSTP on ^Z - */ -/* ARGSUSED */ -static unsigned char -_el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__))) -{ - (void)kill(0, SIGTSTP); - return CC_NORM; -} - -/* - * Display list of strings in columnar format on readline's output stream. - * 'matches' is list of strings, 'len' is number of strings in 'matches', - * 'max' is maximum length of string in 'matches'. - */ -void -rl_display_match_list(char **matches, int len, int max) -{ - - fn_display_match_list(e, matches, (size_t)len, (size_t)max); -} - -static const char * -/*ARGSUSED*/ -_rl_completion_append_character_function(const char *dummy - __attribute__((__unused__))) -{ - static char buf[2]; - buf[0] = (char)rl_completion_append_character; - buf[1] = '\0'; - return buf; -} - - -/* - * complete word at current point - */ -/* ARGSUSED */ -int -rl_complete(int ignore __attribute__((__unused__)), int invoking_key) -{ - static ct_buffer_t wbreak_conv, sprefix_conv; - char *breakchars; - - if (h == NULL || e == NULL) - rl_initialize(); - - if (rl_inhibit_completion) { - char arr[2]; - arr[0] = (char)invoking_key; - arr[1] = '\0'; - el_insertstr(e, arr); - return CC_REFRESH; - } - - if (rl_completion_word_break_hook != NULL) - breakchars = (*rl_completion_word_break_hook)(); - else - breakchars = rl_basic_word_break_characters; - - _rl_update_pos(); - - /* Just look at how many global variables modify this operation! */ - return fn_complete(e, - (rl_compentry_func_t *)rl_completion_entry_function, - rl_attempted_completion_function, - ct_decode_string(rl_basic_word_break_characters, &wbreak_conv), - ct_decode_string(breakchars, &sprefix_conv), - _rl_completion_append_character_function, - (size_t)rl_completion_query_items, - &rl_completion_type, &rl_attempted_completion_over, - &rl_point, &rl_end, NULL, NULL, NULL); - - -} - - -/* ARGSUSED */ -static unsigned char -_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) -{ - return (unsigned char)rl_complete(0, ch); -} - -/* - * misc other functions - */ - -/* - * bind key c to readline-type function func - */ -int -rl_bind_key(int c, rl_command_func_t *func) -{ - int retval = -1; - - if (h == NULL || e == NULL) - rl_initialize(); - - if (func == rl_insert) { - /* XXX notice there is no range checking of ``c'' */ - e->el_map.key[c] = ED_INSERT; - retval = 0; - } - return retval; -} - - -/* - * read one key from input - handles chars pushed back - * to input stream also - */ -int -rl_read_key(void) -{ - char fooarr[2 * sizeof(int)]; - - if (e == NULL || h == NULL) - rl_initialize(); - - return el_getc(e, fooarr); -} - - -/* - * reset the terminal - */ -/* ARGSUSED */ -void -rl_reset_terminal(const char *p __attribute__((__unused__))) -{ - - if (h == NULL || e == NULL) - rl_initialize(); - el_reset(e); -} - - -/* - * insert character ``c'' back into input stream, ``count'' times - */ -int -rl_insert(int count, int c) -{ - char arr[2]; - - if (h == NULL || e == NULL) - rl_initialize(); - - /* XXX - int -> char conversion can lose on multichars */ - arr[0] = (char)c; - arr[1] = '\0'; - - for (; count > 0; count--) - el_push(e, arr); - - return 0; -} - -int -rl_insert_text(const char *text) -{ - if (!text || *text == 0) - return 0; - - if (h == NULL || e == NULL) - rl_initialize(); - - if (el_insertstr(e, text) < 0) - return 0; - return (int)strlen(text); -} - -/*ARGSUSED*/ -int -rl_newline(int count __attribute__((__unused__)), - int c __attribute__((__unused__))) -{ - /* - * Readline-4.0 appears to ignore the args. - */ - return rl_insert(1, '\n'); -} - -/*ARGSUSED*/ -static unsigned char -rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c) -{ - if (map[c] == NULL) - return CC_ERROR; - - _rl_update_pos(); - - (*map[c])(1, c); - - /* If rl_done was set by the above call, deal with it here */ - if (rl_done) - return CC_EOF; - - return CC_NORM; -} - -int -rl_add_defun(const char *name, rl_command_func_t *fun, int c) -{ - char dest[8]; - if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0) - return -1; - map[(unsigned char)c] = fun; - el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); - vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0); - el_set(e, EL_BIND, dest, name, NULL); - return 0; -} - -void -rl_callback_read_char(void) -{ - int count = 0, done = 0; - const char *buf = el_gets(e, &count); - char *wbuf; - - if (buf == NULL || count-- <= 0) - return; - if (count == 0 && buf[0] == e->el_tty.t_c[TS_IO][C_EOF]) - done = 1; - if (buf[count] == '\n' || buf[count] == '\r') - done = 2; - - if (done && rl_linefunc != NULL) { - el_set(e, EL_UNBUFFERED, 0); - if (done == 2) { - if ((wbuf = strdup(buf)) != NULL) - wbuf[count] = '\0'; - } else - wbuf = NULL; - (*(void (*)(const char *))rl_linefunc)(wbuf); - el_set(e, EL_UNBUFFERED, 1); - } -} - -void -rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc) -{ - if (e == NULL) { - rl_initialize(); - } - (void)rl_set_prompt(prompt); - rl_linefunc = linefunc; - el_set(e, EL_UNBUFFERED, 1); -} - -void -rl_callback_handler_remove(void) -{ - el_set(e, EL_UNBUFFERED, 0); - rl_linefunc = NULL; -} - -void -rl_redisplay(void) -{ - char a[2]; - a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT]; - a[1] = '\0'; - el_push(e, a); -} - -int -rl_get_previous_history(int count, int key) -{ - char a[2]; - a[0] = (char)key; - a[1] = '\0'; - while (count--) - el_push(e, a); - return 0; -} - -void -/*ARGSUSED*/ -rl_prep_terminal(int meta_flag __attribute__((__unused__))) -{ - el_set(e, EL_PREP_TERM, 1); -} - -void -rl_deprep_terminal(void) -{ - el_set(e, EL_PREP_TERM, 0); -} - -int -rl_read_init_file(const char *s) -{ - return el_source(e, s); -} - -int -rl_parse_and_bind(const char *line) -{ - const char **argv; - int argc; - Tokenizer *tok; - - tok = tok_init(NULL); - tok_str(tok, line, &argc, &argv); - argc = el_parse(e, argc, argv); - tok_end(tok); - return argc ? 1 : 0; -} - -int -rl_variable_bind(const char *var, const char *value) -{ - /* - * The proper return value is undocument, but this is what the - * readline source seems to do. - */ - return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0; -} - -void -rl_stuff_char(int c) -{ - char buf[2]; - - buf[0] = (char)c; - buf[1] = '\0'; - el_insertstr(e, buf); -} - -static int -_rl_event_read_char(EditLine *el, wchar_t *wc) -{ - char ch; - int n; - ssize_t num_read = 0; - - ch = '\0'; - *wc = L'\0'; - while (rl_event_hook) { - - (*rl_event_hook)(); - -#if defined(FIONREAD) - if (ioctl(el->el_infd, FIONREAD, &n) < 0) - return -1; - if (n) - num_read = read(el->el_infd, &ch, (size_t)1); - else - num_read = 0; -#elif defined(F_SETFL) && defined(O_NDELAY) - if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0) - return -1; - if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0) - return -1; - num_read = read(el->el_infd, &ch, 1); - if (fcntl(el->el_infd, F_SETFL, n)) - return -1; -#else - /* not non-blocking, but what you gonna do? */ - num_read = read(el->el_infd, &ch, 1); - return -1; -#endif - - if (num_read < 0 && errno == EAGAIN) - continue; - if (num_read == 0) - continue; - break; - } - if (!rl_event_hook) - el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); - *wc = (wchar_t)ch; - return (int)num_read; -} - -static void -_rl_update_pos(void) -{ - const LineInfo *li = el_line(e); - - rl_point = (int)(li->cursor - li->buffer); - rl_end = (int)(li->lastchar - li->buffer); -} - -void -rl_get_screen_size(int *rows, int *cols) -{ - if (rows) - el_get(e, EL_GETTC, "li", rows, (void *)0); - if (cols) - el_get(e, EL_GETTC, "co", cols, (void *)0); -} - -void -rl_set_screen_size(int rows, int cols) -{ - char buf[64]; - (void)snprintf(buf, sizeof(buf), "%d", rows); - el_set(e, EL_SETTC, "li", buf, NULL); - (void)snprintf(buf, sizeof(buf), "%d", cols); - el_set(e, EL_SETTC, "co", buf, NULL); -} - -char ** -rl_completion_matches(const char *str, rl_compentry_func_t *fun) -{ - size_t len, max, i, j, min; - char **list, *match, *a, *b; - - len = 1; - max = 10; - if ((list = el_malloc(max * sizeof(*list))) == NULL) - return NULL; - - while ((match = (*fun)(str, (int)(len - 1))) != NULL) { - list[len++] = match; - if (len == max) { - char **nl; - max += 10; - if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL) - goto out; - list = nl; - } - } - if (len == 1) - goto out; - list[len] = NULL; - if (len == 2) { - if ((list[0] = strdup(list[1])) == NULL) - goto out; - return list; - } - qsort(&list[1], len - 1, sizeof(*list), - (int (*)(const void *, const void *)) strcmp); - min = SIZE_MAX; - for (i = 1, a = list[i]; i < len - 1; i++, a = b) { - b = list[i + 1]; - for (j = 0; a[j] && a[j] == b[j]; j++) - continue; - if (min > j) - min = j; - } - if (min == 0 && *str) { - if ((list[0] = strdup(str)) == NULL) - goto out; - } else { - if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL) - goto out; - (void)memcpy(list[0], list[1], min); - list[0][min] = '\0'; - } - return list; - -out: - el_free(list); - return NULL; -} - -char * -rl_filename_completion_function (const char *text, int state) -{ - return fn_filename_completion_function(text, state); -} - -void -rl_forced_update_display(void) -{ - el_set(e, EL_REFRESH); -} - -int -_rl_abort_internal(void) -{ - el_beep(e); - longjmp(topbuf, 1); - /*NOTREACHED*/ -} - -int -_rl_qsort_string_compare(char **s1, char **s2) -{ - return strcoll(*s1, *s2); -} - -HISTORY_STATE * -history_get_history_state(void) -{ - HISTORY_STATE *hs; - - if ((hs = el_malloc(sizeof(*hs))) == NULL) - return NULL; - hs->length = history_length; - return hs; -} - -int -/*ARGSUSED*/ -rl_kill_text(int from __attribute__((__unused__)), - int to __attribute__((__unused__))) -{ - return 0; -} - -Keymap -rl_make_bare_keymap(void) -{ - return NULL; -} - -Keymap -rl_get_keymap(void) -{ - return NULL; -} - -void -/*ARGSUSED*/ -rl_set_keymap(Keymap k __attribute__((__unused__))) -{ -} - -int -/*ARGSUSED*/ -rl_generic_bind(int type __attribute__((__unused__)), - const char * keyseq __attribute__((__unused__)), - const char * data __attribute__((__unused__)), - Keymap k __attribute__((__unused__))) -{ - return 0; -} - -int -/*ARGSUSED*/ -rl_bind_key_in_map(int key __attribute__((__unused__)), - rl_command_func_t *fun __attribute__((__unused__)), - Keymap k __attribute__((__unused__))) -{ - return 0; -} - -/* unsupported, but needed by python */ -void -rl_cleanup_after_signal(void) -{ -} - -int -rl_on_new_line(void) -{ - return 0; -} - -void -rl_free_line_state(void) -{ -} - -int -/*ARGSUSED*/ -rl_set_keyboard_input_timeout(int u __attribute__((__unused__))) -{ - return 0; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/refresh.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/refresh.c deleted file mode 100644 index e7775b0..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/refresh.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* $NetBSD: refresh.c,v 1.51 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: refresh.c,v 1.51 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * refresh.c: Lower level screen refreshing functions - */ -#include -#include -#include - -#include "el.h" - -static void re_nextline(EditLine *); -static void re_addc(EditLine *, wint_t); -static void re_update_line(EditLine *, wchar_t *, wchar_t *, int); -static void re_insert (EditLine *, wchar_t *, int, int, wchar_t *, int); -static void re_delete(EditLine *, wchar_t *, int, int, int); -static void re_fastputc(EditLine *, wint_t); -static void re_clear_eol(EditLine *, int, int, int); -static void re__strncopy(wchar_t *, wchar_t *, size_t); -static void re__copy_and_pad(wchar_t *, const wchar_t *, size_t); - -#ifdef DEBUG_REFRESH -static void re_printstr(EditLine *, const char *, wchar_t *, wchar_t *); -#define __F el->el_errfile -#define ELRE_ASSERT(a, b, c) do \ - if (/*CONSTCOND*/ a) { \ - (void) fprintf b; \ - c; \ - } \ - while (/*CONSTCOND*/0) -#define ELRE_DEBUG(a, b) ELRE_ASSERT(a,b,;) - -/* re_printstr(): - * Print a string on the debugging pty - */ -static void -re_printstr(EditLine *el, const char *str, wchar_t *f, wchar_t *t) -{ - - ELRE_DEBUG(1, (__F, "%s:\"", str)); - while (f < t) - ELRE_DEBUG(1, (__F, "%c", *f++ & 0177)); - ELRE_DEBUG(1, (__F, "\"\r\n")); -} -#else -#define ELRE_ASSERT(a, b, c) -#define ELRE_DEBUG(a, b) -#endif - -/* re_nextline(): - * Move to the next line or scroll - */ -static void -re_nextline(EditLine *el) -{ - el->el_refresh.r_cursor.h = 0; /* reset it. */ - - /* - * If we would overflow (input is longer than terminal size), - * emulate scroll by dropping first line and shuffling the rest. - * We do this via pointer shuffling - it's safe in this case - * and we avoid memcpy(). - */ - if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) { - int i, lins = el->el_terminal.t_size.v; - wchar_t *firstline = el->el_vdisplay[0]; - - for(i = 1; i < lins; i++) - el->el_vdisplay[i - 1] = el->el_vdisplay[i]; - - firstline[0] = '\0'; /* empty the string */ - el->el_vdisplay[i - 1] = firstline; - } else - el->el_refresh.r_cursor.v++; - - ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v, - (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n", - el->el_refresh.r_cursor.v, el->el_terminal.t_size.v), - abort()); -} - -/* re_addc(): - * Draw c, expanding tabs, control chars etc. - */ -static void -re_addc(EditLine *el, wint_t c) -{ - switch (ct_chr_class(c)) { - case CHTYPE_TAB: /* expand the tab */ - for (;;) { - re_putc(el, ' ', 1); - if ((el->el_refresh.r_cursor.h & 07) == 0) - break; /* go until tab stop */ - } - break; - case CHTYPE_NL: { - int oldv = el->el_refresh.r_cursor.v; - re_putc(el, '\0', 0); /* assure end of line */ - if (oldv == el->el_refresh.r_cursor.v) /* XXX */ - re_nextline(el); - break; - } - case CHTYPE_PRINT: - re_putc(el, c, 1); - break; - default: { - wchar_t visbuf[VISUAL_WIDTH_MAX]; - ssize_t i, n = - ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c); - for (i = 0; n-- > 0; ++i) - re_putc(el, visbuf[i], 1); - break; - } - } -} - - -/* re_putc(): - * Draw the character given - */ -libedit_private void -re_putc(EditLine *el, wint_t c, int shift) -{ - int i, w = wcwidth(c); - ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c)); - if (w == -1) - w = 0; - - while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h)) - re_putc(el, ' ', 1); - - el->el_vdisplay[el->el_refresh.r_cursor.v] - [el->el_refresh.r_cursor.h] = c; - /* assumes !shift is only used for single-column chars */ - i = w; - while (--i > 0) - el->el_vdisplay[el->el_refresh.r_cursor.v] - [el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR; - - if (!shift) - return; - - el->el_refresh.r_cursor.h += w; /* advance to next place */ - if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) { - /* assure end of line */ - el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h] - = '\0'; - re_nextline(el); - } -} - - -/* re_refresh(): - * draws the new virtual screen image from the current input - * line, then goes line-by-line changing the real image to the new - * virtual image. The routine to re-draw a line can be replaced - * easily in hopes of a smarter one being placed there. - */ -libedit_private void -re_refresh(EditLine *el) -{ - int i, rhdiff; - wchar_t *cp, *st; - coord_t cur; -#ifdef notyet - size_t termsz; -#endif - - ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%ls:\r\n", - el->el_line.buffer)); - - /* reset the Drawing cursor */ - el->el_refresh.r_cursor.h = 0; - el->el_refresh.r_cursor.v = 0; - - /* temporarily draw rprompt to calculate its size */ - prompt_print(el, EL_RPROMPT); - - /* reset the Drawing cursor */ - el->el_refresh.r_cursor.h = 0; - el->el_refresh.r_cursor.v = 0; - - if (el->el_line.cursor >= el->el_line.lastchar) { - if (el->el_map.current == el->el_map.alt - && el->el_line.lastchar != el->el_line.buffer) - el->el_line.cursor = el->el_line.lastchar - 1; - else - el->el_line.cursor = el->el_line.lastchar; - } - - cur.h = -1; /* set flag in case I'm not set */ - cur.v = 0; - - prompt_print(el, EL_PROMPT); - - /* draw the current input buffer */ -#if notyet - termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v; - if (el->el_line.lastchar - el->el_line.buffer > termsz) { - /* - * If line is longer than terminal, process only part - * of line which would influence display. - */ - size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz; - - st = el->el_line.lastchar - rem - - (termsz - (((rem / el->el_terminal.t_size.v) - 1) - * el->el_terminal.t_size.v)); - } else -#endif - st = el->el_line.buffer; - - for (cp = st; cp < el->el_line.lastchar; cp++) { - if (cp == el->el_line.cursor) { - int w = wcwidth(*cp); - /* save for later */ - cur.h = el->el_refresh.r_cursor.h; - cur.v = el->el_refresh.r_cursor.v; - /* handle being at a linebroken doublewidth char */ - if (w > 1 && el->el_refresh.r_cursor.h + w > - el->el_terminal.t_size.h) { - cur.h = 0; - cur.v++; - } - } - re_addc(el, *cp); - } - - if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */ - cur.h = el->el_refresh.r_cursor.h; - cur.v = el->el_refresh.r_cursor.v; - } - rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h - - el->el_rprompt.p_pos.h; - if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v && - !el->el_refresh.r_cursor.v && rhdiff > 1) { - /* - * have a right-hand side prompt that will fit - * on the end of the first line with at least - * one character gap to the input buffer. - */ - while (--rhdiff > 0) /* pad out with spaces */ - re_putc(el, ' ', 1); - prompt_print(el, EL_RPROMPT); - } else { - el->el_rprompt.p_pos.h = 0; /* flag "not using rprompt" */ - el->el_rprompt.p_pos.v = 0; - } - - re_putc(el, '\0', 0); /* make line ended with NUL, no cursor shift */ - - el->el_refresh.r_newcv = el->el_refresh.r_cursor.v; - - ELRE_DEBUG(1, (__F, - "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n", - el->el_terminal.t_size.h, el->el_refresh.r_cursor.h, - el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0], - &el->el_scratch))); - - ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv)); - for (i = 0; i <= el->el_refresh.r_newcv; i++) { - /* NOTE THAT re_update_line MAY CHANGE el_display[i] */ - re_update_line(el, el->el_display[i], el->el_vdisplay[i], i); - - /* - * Copy the new line to be the current one, and pad out with - * spaces to the full width of the terminal so that if we try - * moving the cursor by writing the character that is at the - * end of the screen line, it won't be a NUL or some old - * leftover stuff. - */ - re__copy_and_pad(el->el_display[i], el->el_vdisplay[i], - (size_t) el->el_terminal.t_size.h); - } - ELRE_DEBUG(1, (__F, - "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n", - el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i)); - - if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv) - for (; i <= el->el_refresh.r_oldcv; i++) { - terminal_move_to_line(el, i); - terminal_move_to_char(el, 0); - /* This wcslen should be safe even with MB_FILL_CHARs */ - terminal_clear_EOL(el, (int) wcslen(el->el_display[i])); -#ifdef DEBUG_REFRESH - terminal_overwrite(el, L"C\b", 2); -#endif /* DEBUG_REFRESH */ - el->el_display[i][0] = '\0'; - } - - el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */ - ELRE_DEBUG(1, (__F, - "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n", - el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v, - cur.h, cur.v)); - terminal_move_to_line(el, cur.v); /* go to where the cursor is */ - terminal_move_to_char(el, cur.h); -} - - -/* re_goto_bottom(): - * used to go to last used screen line - */ -libedit_private void -re_goto_bottom(EditLine *el) -{ - - terminal_move_to_line(el, el->el_refresh.r_oldcv); - terminal__putc(el, '\n'); - re_clear_display(el); - terminal__flush(el); -} - - -/* re_insert(): - * insert num characters of s into d (in front of the character) - * at dat, maximum length of d is dlen - */ -static void -/*ARGSUSED*/ -re_insert(EditLine *el __attribute__((__unused__)), - wchar_t *d, int dat, int dlen, wchar_t *s, int num) -{ - wchar_t *a, *b; - - if (num <= 0) - return; - if (num > dlen - dat) - num = dlen - dat; - - ELRE_DEBUG(1, - (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, ct_encode_string(d, &el->el_scratch))); - ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s, - &el->el_scratch))); - - /* open up the space for num chars */ - if (num > 0) { - b = d + dlen - 1; - a = b - num; - while (a >= &d[dat]) - *b-- = *a--; - d[dlen] = '\0'; /* just in case */ - } - - ELRE_DEBUG(1, (__F, - "re_insert() after insert: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, ct_encode_string(d, &el->el_scratch))); - ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s, - &el->el_scratch))); - - /* copy the characters */ - for (a = d + dat; (a < d + dlen) && (num > 0); num--) - *a++ = *s++; - -#ifdef notyet - /* ct_encode_string() uses a static buffer, so we can't conveniently - * encode both d & s here */ - ELRE_DEBUG(1, - (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", - num, dat, dlen, d, s)); - ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); -#endif -} - - -/* re_delete(): - * delete num characters d at dat, maximum length of d is dlen - */ -static void -/*ARGSUSED*/ -re_delete(EditLine *el __attribute__((__unused__)), - wchar_t *d, int dat, int dlen, int num) -{ - wchar_t *a, *b; - - if (num <= 0) - return; - if (dat + num >= dlen) { - d[dat] = '\0'; - return; - } - ELRE_DEBUG(1, - (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, ct_encode_string(d, &el->el_scratch))); - - /* open up the space for num chars */ - if (num > 0) { - b = d + dat; - a = b + num; - while (a < &d[dlen]) - *b++ = *a++; - d[dlen] = '\0'; /* just in case */ - } - ELRE_DEBUG(1, - (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, ct_encode_string(d, &el->el_scratch))); -} - - -/* re__strncopy(): - * Like strncpy without padding. - */ -static void -re__strncopy(wchar_t *a, wchar_t *b, size_t n) -{ - - while (n-- && *b) - *a++ = *b++; -} - -/* re_clear_eol(): - * Find the number of characters we need to clear till the end of line - * in order to make sure that we have cleared the previous contents of - * the line. fx and sx is the number of characters inserted or deleted - * in the first or second diff, diff is the difference between the - * number of characters between the new and old line. - */ -static void -re_clear_eol(EditLine *el, int fx, int sx, int diff) -{ - - ELRE_DEBUG(1, (__F, "re_clear_eol sx %d, fx %d, diff %d\n", - sx, fx, diff)); - - if (fx < 0) - fx = -fx; - if (sx < 0) - sx = -sx; - if (fx > diff) - diff = fx; - if (sx > diff) - diff = sx; - - ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff)); - terminal_clear_EOL(el, diff); -} - -/***************************************************************** - re_update_line() is based on finding the middle difference of each line - on the screen; vis: - - /old first difference - /beginning of line | /old last same /old EOL - v v v v -old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as -new: eddie> Oh, my little buggy says to me, as lurgid as - ^ ^ ^ ^ - \beginning of line | \new last same \new end of line - \new first difference - - all are character pointers for the sake of speed. Special cases for - no differences, as well as for end of line additions must be handled. -**************************************************************** */ - -/* Minimum at which doing an insert it "worth it". This should be about - * half the "cost" of going into insert mode, inserting a character, and - * going back out. This should really be calculated from the termcap - * data... For the moment, a good number for ANSI terminals. - */ -#define MIN_END_KEEP 4 - -static void -re_update_line(EditLine *el, wchar_t *old, wchar_t *new, int i) -{ - wchar_t *o, *n, *p, c; - wchar_t *ofd, *ols, *oe, *nfd, *nls, *ne; - wchar_t *osb, *ose, *nsb, *nse; - int fx, sx; - size_t len; - - /* - * find first diff - */ - for (o = old, n = new; *o && (*o == *n); o++, n++) - continue; - ofd = o; - nfd = n; - - /* - * Find the end of both old and new - */ - while (*o) - o++; - /* - * Remove any trailing blanks off of the end, being careful not to - * back up past the beginning. - */ - while (ofd < o) { - if (o[-1] != ' ') - break; - o--; - } - oe = o; - *oe = '\0'; - - while (*n) - n++; - - /* remove blanks from end of new */ - while (nfd < n) { - if (n[-1] != ' ') - break; - n--; - } - ne = n; - *ne = '\0'; - - /* - * if no diff, continue to next line of redraw - */ - if (*ofd == '\0' && *nfd == '\0') { - ELRE_DEBUG(1, (__F, "no difference.\r\n")); - return; - } - /* - * find last same pointer - */ - while ((o > ofd) && (n > nfd) && (*--o == *--n)) - continue; - ols = ++o; - nls = ++n; - - /* - * find same beginning and same end - */ - osb = ols; - nsb = nls; - ose = ols; - nse = nls; - - /* - * case 1: insert: scan from nfd to nls looking for *ofd - */ - if (*ofd) { - for (c = *ofd, n = nfd; n < nls; n++) { - if (c == *n) { - for (o = ofd, p = n; - p < nls && o < ols && *o == *p; - o++, p++) - continue; - /* - * if the new match is longer and it's worth - * keeping, then we take it - */ - if (((nse - nsb) < (p - n)) && - (2 * (p - n) > n - nfd)) { - nsb = n; - nse = p; - osb = ofd; - ose = o; - } - } - } - } - /* - * case 2: delete: scan from ofd to ols looking for *nfd - */ - if (*nfd) { - for (c = *nfd, o = ofd; o < ols; o++) { - if (c == *o) { - for (n = nfd, p = o; - p < ols && n < nls && *p == *n; - p++, n++) - continue; - /* - * if the new match is longer and it's worth - * keeping, then we take it - */ - if (((ose - osb) < (p - o)) && - (2 * (p - o) > o - ofd)) { - nsb = nfd; - nse = n; - osb = o; - ose = p; - } - } - } - } - /* - * Pragmatics I: If old trailing whitespace or not enough characters to - * save to be worth it, then don't save the last same info. - */ - if ((oe - ols) < MIN_END_KEEP) { - ols = oe; - nls = ne; - } - /* - * Pragmatics II: if the terminal isn't smart enough, make the data - * dumber so the smart update doesn't try anything fancy - */ - - /* - * fx is the number of characters we need to insert/delete: in the - * beginning to bring the two same begins together - */ - fx = (int)((nsb - nfd) - (osb - ofd)); - /* - * sx is the number of characters we need to insert/delete: in the - * end to bring the two same last parts together - */ - sx = (int)((nls - nse) - (ols - ose)); - - if (!EL_CAN_INSERT) { - if (fx > 0) { - osb = ols; - ose = ols; - nsb = nls; - nse = nls; - } - if (sx > 0) { - ols = oe; - nls = ne; - } - if ((ols - ofd) < (nls - nfd)) { - ols = oe; - nls = ne; - } - } - if (!EL_CAN_DELETE) { - if (fx < 0) { - osb = ols; - ose = ols; - nsb = nls; - nse = nls; - } - if (sx < 0) { - ols = oe; - nls = ne; - } - if ((ols - ofd) > (nls - nfd)) { - ols = oe; - nls = ne; - } - } - /* - * Pragmatics III: make sure the middle shifted pointers are correct if - * they don't point to anything (we may have moved ols or nls). - */ - /* if the change isn't worth it, don't bother */ - /* was: if (osb == ose) */ - if ((ose - osb) < MIN_END_KEEP) { - osb = ols; - ose = ols; - nsb = nls; - nse = nls; - } - /* - * Now that we are done with pragmatics we recompute fx, sx - */ - fx = (int)((nsb - nfd) - (osb - ofd)); - sx = (int)((nls - nse) - (ols - ose)); - - ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx)); - ELRE_DEBUG(1, (__F, "ofd %td, osb %td, ose %td, ols %td, oe %td\n", - ofd - old, osb - old, ose - old, ols - old, oe - old)); - ELRE_DEBUG(1, (__F, "nfd %td, nsb %td, nse %td, nls %td, ne %td\n", - nfd - new, nsb - new, nse - new, nls - new, ne - new)); - ELRE_DEBUG(1, (__F, - "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n")); - ELRE_DEBUG(1, (__F, - "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n")); -#ifdef DEBUG_REFRESH - re_printstr(el, "old- oe", old, oe); - re_printstr(el, "new- ne", new, ne); - re_printstr(el, "old-ofd", old, ofd); - re_printstr(el, "new-nfd", new, nfd); - re_printstr(el, "ofd-osb", ofd, osb); - re_printstr(el, "nfd-nsb", nfd, nsb); - re_printstr(el, "osb-ose", osb, ose); - re_printstr(el, "nsb-nse", nsb, nse); - re_printstr(el, "ose-ols", ose, ols); - re_printstr(el, "nse-nls", nse, nls); - re_printstr(el, "ols- oe", ols, oe); - re_printstr(el, "nls- ne", nls, ne); -#endif /* DEBUG_REFRESH */ - - /* - * el_cursor.v to this line i MUST be in this routine so that if we - * don't have to change the line, we don't move to it. el_cursor.h to - * first diff char - */ - terminal_move_to_line(el, i); - - /* - * at this point we have something like this: - * - * /old /ofd /osb /ose /ols /oe - * v.....................v v..................v v........v - * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as - * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as - * ^.....................^ ^..................^ ^........^ - * \new \nfd \nsb \nse \nls \ne - * - * fx is the difference in length between the chars between nfd and - * nsb, and the chars between ofd and osb, and is thus the number of - * characters to delete if < 0 (new is shorter than old, as above), - * or insert (new is longer than short). - * - * sx is the same for the second differences. - */ - - /* - * if we have a net insert on the first difference, AND inserting the - * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful - * character (which is ne if nls != ne, otherwise is nse) off the edge - * of the screen (el->el_terminal.t_size.h) else we do the deletes first - * so that we keep everything we need to. - */ - - /* - * if the last same is the same like the end, there is no last same - * part, otherwise we want to keep the last same part set p to the - * last useful old character - */ - p = (ols != oe) ? oe : ose; - - /* - * if (There is a diffence in the beginning) && (we need to insert - * characters) && (the number of characters to insert is less than - * the term width) - * We need to do an insert! - * else if (we need to delete characters) - * We need to delete characters! - * else - * No insert or delete - */ - if ((nsb != nfd) && fx > 0 && - ((p - old) + fx <= el->el_terminal.t_size.h)) { - ELRE_DEBUG(1, - (__F, "first diff insert at %td...\r\n", nfd - new)); - /* - * Move to the first char to insert, where the first diff is. - */ - terminal_move_to_char(el, (int)(nfd - new)); - /* - * Check if we have stuff to keep at end - */ - if (nsb != ne) { - ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); - /* - * insert fx chars of new starting at nfd - */ - if (fx > 0) { - ELRE_DEBUG(!EL_CAN_INSERT, (__F, - "ERROR: cannot insert in early first diff\n")); - terminal_insertwrite(el, nfd, fx); - re_insert(el, old, (int)(ofd - old), - el->el_terminal.t_size.h, nfd, fx); - } - /* - * write (nsb-nfd) - fx chars of new starting at - * (nfd + fx) - */ - len = (size_t) ((nsb - nfd) - fx); - terminal_overwrite(el, (nfd + fx), len); - re__strncopy(ofd + fx, nfd + fx, len); - } else { - ELRE_DEBUG(1, (__F, "without anything to save\r\n")); - len = (size_t)(nsb - nfd); - terminal_overwrite(el, nfd, len); - re__strncopy(ofd, nfd, len); - /* - * Done - */ - return; - } - } else if (fx < 0) { - ELRE_DEBUG(1, - (__F, "first diff delete at %td...\r\n", ofd - old)); - /* - * move to the first char to delete where the first diff is - */ - terminal_move_to_char(el, (int)(ofd - old)); - /* - * Check if we have stuff to save - */ - if (osb != oe) { - ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n")); - /* - * fx is less than zero *always* here but we check - * for code symmetry - */ - if (fx < 0) { - ELRE_DEBUG(!EL_CAN_DELETE, (__F, - "ERROR: cannot delete in first diff\n")); - terminal_deletechars(el, -fx); - re_delete(el, old, (int)(ofd - old), - el->el_terminal.t_size.h, -fx); - } - /* - * write (nsb-nfd) chars of new starting at nfd - */ - len = (size_t) (nsb - nfd); - terminal_overwrite(el, nfd, len); - re__strncopy(ofd, nfd, len); - - } else { - ELRE_DEBUG(1, (__F, - "but with nothing left to save\r\n")); - /* - * write (nsb-nfd) chars of new starting at nfd - */ - terminal_overwrite(el, nfd, (size_t)(nsb - nfd)); - re_clear_eol(el, fx, sx, - (int)((oe - old) - (ne - new))); - /* - * Done - */ - return; - } - } else - fx = 0; - - if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) { - ELRE_DEBUG(1, (__F, - "second diff delete at %td...\r\n", (ose - old) + fx)); - /* - * Check if we have stuff to delete - */ - /* - * fx is the number of characters inserted (+) or deleted (-) - */ - - terminal_move_to_char(el, (int)((ose - old) + fx)); - /* - * Check if we have stuff to save - */ - if (ols != oe) { - ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n")); - /* - * Again a duplicate test. - */ - if (sx < 0) { - ELRE_DEBUG(!EL_CAN_DELETE, (__F, - "ERROR: cannot delete in second diff\n")); - terminal_deletechars(el, -sx); - } - /* - * write (nls-nse) chars of new starting at nse - */ - terminal_overwrite(el, nse, (size_t)(nls - nse)); - } else { - ELRE_DEBUG(1, (__F, - "but with nothing left to save\r\n")); - terminal_overwrite(el, nse, (size_t)(nls - nse)); - re_clear_eol(el, fx, sx, - (int)((oe - old) - (ne - new))); - } - } - /* - * if we have a first insert AND WE HAVEN'T ALREADY DONE IT... - */ - if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) { - ELRE_DEBUG(1, (__F, "late first diff insert at %td...\r\n", - nfd - new)); - - terminal_move_to_char(el, (int)(nfd - new)); - /* - * Check if we have stuff to keep at the end - */ - if (nsb != ne) { - ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); - /* - * We have to recalculate fx here because we set it - * to zero above as a flag saying that we hadn't done - * an early first insert. - */ - fx = (int)((nsb - nfd) - (osb - ofd)); - if (fx > 0) { - /* - * insert fx chars of new starting at nfd - */ - ELRE_DEBUG(!EL_CAN_INSERT, (__F, - "ERROR: cannot insert in late first diff\n")); - terminal_insertwrite(el, nfd, fx); - re_insert(el, old, (int)(ofd - old), - el->el_terminal.t_size.h, nfd, fx); - } - /* - * write (nsb-nfd) - fx chars of new starting at - * (nfd + fx) - */ - len = (size_t) ((nsb - nfd) - fx); - terminal_overwrite(el, (nfd + fx), len); - re__strncopy(ofd + fx, nfd + fx, len); - } else { - ELRE_DEBUG(1, (__F, "without anything to save\r\n")); - len = (size_t) (nsb - nfd); - terminal_overwrite(el, nfd, len); - re__strncopy(ofd, nfd, len); - } - } - /* - * line is now NEW up to nse - */ - if (sx >= 0) { - ELRE_DEBUG(1, (__F, - "second diff insert at %d...\r\n", (int)(nse - new))); - terminal_move_to_char(el, (int)(nse - new)); - if (ols != oe) { - ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); - if (sx > 0) { - /* insert sx chars of new starting at nse */ - ELRE_DEBUG(!EL_CAN_INSERT, (__F, - "ERROR: cannot insert in second diff\n")); - terminal_insertwrite(el, nse, sx); - } - /* - * write (nls-nse) - sx chars of new starting at - * (nse + sx) - */ - terminal_overwrite(el, (nse + sx), - (size_t)((nls - nse) - sx)); - } else { - ELRE_DEBUG(1, (__F, "without anything to save\r\n")); - terminal_overwrite(el, nse, (size_t)(nls - nse)); - - /* - * No need to do a clear-to-end here because we were - * doing a second insert, so we will have over - * written all of the old string. - */ - } - } - ELRE_DEBUG(1, (__F, "done.\r\n")); -} - - -/* re__copy_and_pad(): - * Copy string and pad with spaces - */ -static void -re__copy_and_pad(wchar_t *dst, const wchar_t *src, size_t width) -{ - size_t i; - - for (i = 0; i < width; i++) { - if (*src == '\0') - break; - *dst++ = *src++; - } - - for (; i < width; i++) - *dst++ = ' '; - - *dst = '\0'; -} - - -/* re_refresh_cursor(): - * Move to the new cursor position - */ -libedit_private void -re_refresh_cursor(EditLine *el) -{ - wchar_t *cp; - int h, v, th, w; - - if (el->el_line.cursor >= el->el_line.lastchar) { - if (el->el_map.current == el->el_map.alt - && el->el_line.lastchar != el->el_line.buffer) - el->el_line.cursor = el->el_line.lastchar - 1; - else - el->el_line.cursor = el->el_line.lastchar; - } - - /* first we must find where the cursor is... */ - h = el->el_prompt.p_pos.h; - v = el->el_prompt.p_pos.v; - th = el->el_terminal.t_size.h; /* optimize for speed */ - - /* do input buffer to el->el_line.cursor */ - for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) { - switch (ct_chr_class(*cp)) { - case CHTYPE_NL: /* handle newline in data part too */ - h = 0; - v++; - break; - case CHTYPE_TAB: /* if a tab, to next tab stop */ - while (++h & 07) - continue; - break; - default: - w = wcwidth(*cp); - if (w > 1 && h + w > th) { /* won't fit on line */ - h = 0; - v++; - } - h += ct_visual_width(*cp); - break; - } - - if (h >= th) { /* check, extra long tabs picked up here also */ - h -= th; - v++; - } - } - /* if we have a next character, and it's a doublewidth one, we need to - * check whether we need to linebreak for it to fit */ - if (cp < el->el_line.lastchar && (w = wcwidth(*cp)) > 1) - if (h + w > th) { - h = 0; - v++; - } - - /* now go there */ - terminal_move_to_line(el, v); - terminal_move_to_char(el, h); - terminal__flush(el); -} - - -/* re_fastputc(): - * Add a character fast. - */ -static void -re_fastputc(EditLine *el, wint_t c) -{ - int w = wcwidth(c); - while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h) - re_fastputc(el, ' '); - - terminal__putc(el, c); - el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; - while (--w > 0) - el->el_display[el->el_cursor.v][el->el_cursor.h++] - = MB_FILL_CHAR; - - if (el->el_cursor.h >= el->el_terminal.t_size.h) { - /* if we must overflow */ - el->el_cursor.h = 0; - - /* - * If we would overflow (input is longer than terminal size), - * emulate scroll by dropping first line and shuffling the rest. - * We do this via pointer shuffling - it's safe in this case - * and we avoid memcpy(). - */ - if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) { - int i, lins = el->el_terminal.t_size.v; - wchar_t *firstline = el->el_display[0]; - - for(i = 1; i < lins; i++) - el->el_display[i - 1] = el->el_display[i]; - - re__copy_and_pad(firstline, L"", (size_t)0); - el->el_display[i - 1] = firstline; - } else { - el->el_cursor.v++; - el->el_refresh.r_oldcv++; - } - if (EL_HAS_AUTO_MARGINS) { - if (EL_HAS_MAGIC_MARGINS) { - terminal__putc(el, ' '); - terminal__putc(el, '\b'); - } - } else { - terminal__putc(el, '\r'); - terminal__putc(el, '\n'); - } - } -} - - -/* re_fastaddc(): - * we added just one char, handle it fast. - * Assumes that screen cursor == real cursor - */ -libedit_private void -re_fastaddc(EditLine *el) -{ - wchar_t c; - int rhdiff; - - c = el->el_line.cursor[-1]; - - if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) { - re_refresh(el); /* too hard to handle */ - return; - } - rhdiff = el->el_terminal.t_size.h - el->el_cursor.h - - el->el_rprompt.p_pos.h; - if (el->el_rprompt.p_pos.h && rhdiff < 3) { - re_refresh(el); /* clear out rprompt if less than 1 char gap */ - return; - } /* else (only do at end of line, no TAB) */ - switch (ct_chr_class(c)) { - case CHTYPE_TAB: /* already handled, should never happen here */ - break; - case CHTYPE_NL: - case CHTYPE_PRINT: - re_fastputc(el, c); - break; - case CHTYPE_ASCIICTL: - case CHTYPE_NONPRINT: { - wchar_t visbuf[VISUAL_WIDTH_MAX]; - ssize_t i, n = - ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c); - for (i = 0; n-- > 0; ++i) - re_fastputc(el, visbuf[i]); - break; - } - } - terminal__flush(el); -} - - -/* re_clear_display(): - * clear the screen buffers so that new new prompt starts fresh. - */ -libedit_private void -re_clear_display(EditLine *el) -{ - int i; - - el->el_cursor.v = 0; - el->el_cursor.h = 0; - for (i = 0; i < el->el_terminal.t_size.v; i++) - el->el_display[i][0] = '\0'; - el->el_refresh.r_oldcv = 0; -} - - -/* re_clear_lines(): - * Make sure all lines are *really* blank - */ -libedit_private void -re_clear_lines(EditLine *el) -{ - - if (EL_CAN_CEOL) { - int i; - for (i = el->el_refresh.r_oldcv; i >= 0; i--) { - /* for each line on the screen */ - terminal_move_to_line(el, i); - terminal_move_to_char(el, 0); - terminal_clear_EOL(el, el->el_terminal.t_size.h); - } - } else { - terminal_move_to_line(el, el->el_refresh.r_oldcv); - /* go to last line */ - terminal__putc(el, '\r'); /* go to BOL */ - terminal__putc(el, '\n'); /* go to new line */ - } -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/refresh.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/refresh.h deleted file mode 100644 index 621c569..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/refresh.h +++ /dev/null @@ -1,57 +0,0 @@ -/* $NetBSD: refresh.h,v 1.10 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)refresh.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.refresh.h: Screen refresh functions - */ -#ifndef _h_el_refresh -#define _h_el_refresh - -typedef struct { - coord_t r_cursor; /* Refresh cursor position */ - int r_oldcv; /* Vertical locations */ - int r_newcv; -} el_refresh_t; - -libedit_private void re_putc(EditLine *, wint_t, int); -libedit_private void re_clear_lines(EditLine *); -libedit_private void re_clear_display(EditLine *); -libedit_private void re_refresh(EditLine *); -libedit_private void re_refresh_cursor(EditLine *); -libedit_private void re_fastaddc(EditLine *); -libedit_private void re_goto_bottom(EditLine *); - -#endif /* _h_el_refresh */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/search.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/search.c deleted file mode 100644 index 3141629..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/search.c +++ /dev/null @@ -1,642 +0,0 @@ -/* $NetBSD: search.c,v 1.47 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: search.c,v 1.47 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * search.c: History and character search functions - */ -#include -#include -#include -#if defined(REGEX) -#include -#elif defined(REGEXP) -#include -#endif - -#include "el.h" -#include "common.h" -#include "fcns.h" - -/* - * Adjust cursor in vi mode to include the character under it - */ -#define EL_CURSOR(el) \ - ((el)->el_line.cursor + (((el)->el_map.type == MAP_VI) && \ - ((el)->el_map.current == (el)->el_map.alt))) - -/* search_init(): - * Initialize the search stuff - */ -libedit_private int -search_init(EditLine *el) -{ - - el->el_search.patbuf = el_malloc(EL_BUFSIZ * - sizeof(*el->el_search.patbuf)); - if (el->el_search.patbuf == NULL) - return -1; - el->el_search.patbuf[0] = L'\0'; - el->el_search.patlen = 0; - el->el_search.patdir = -1; - el->el_search.chacha = L'\0'; - el->el_search.chadir = CHAR_FWD; - el->el_search.chatflg = 0; - return 0; -} - - -/* search_end(): - * Initialize the search stuff - */ -libedit_private void -search_end(EditLine *el) -{ - - el_free(el->el_search.patbuf); - el->el_search.patbuf = NULL; -} - - -#ifdef REGEXP -/* regerror(): - * Handle regular expression errors - */ -void -/*ARGSUSED*/ -regerror(const char *msg) -{ -} -#endif - - -/* el_match(): - * Return if string matches pattern - */ -libedit_private int -el_match(const wchar_t *str, const wchar_t *pat) -{ - static ct_buffer_t conv; -#if defined (REGEX) - regex_t re; - int rv; -#elif defined (REGEXP) - regexp *rp; - int rv; -#else - extern char *re_comp(const char *); - extern int re_exec(const char *); -#endif - - if (wcsstr(str, pat) != 0) - return 1; - -#if defined(REGEX) - if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) { - rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL, - 0) == 0; - regfree(&re); - } else { - rv = 0; - } - return rv; -#elif defined(REGEXP) - if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) { - rv = regexec(re, ct_encode_string(str, &conv)); - el_free(re); - } else { - rv = 0; - } - return rv; -#else - if (re_comp(ct_encode_string(pat, &conv)) != NULL) - return 0; - else - return re_exec(ct_encode_string(str, &conv)) == 1; -#endif -} - - -/* c_hmatch(): - * return True if the pattern matches the prefix - */ -libedit_private int -c_hmatch(EditLine *el, const wchar_t *str) -{ -#ifdef SDEBUG - (void) fprintf(el->el_errfile, "match `%s' with `%s'\n", - el->el_search.patbuf, str); -#endif /* SDEBUG */ - - return el_match(str, el->el_search.patbuf); -} - - -/* c_setpat(): - * Set the history seatch pattern - */ -libedit_private void -c_setpat(EditLine *el) -{ - if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY && - el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) { - el->el_search.patlen = - (size_t)(EL_CURSOR(el) - el->el_line.buffer); - if (el->el_search.patlen >= EL_BUFSIZ) - el->el_search.patlen = EL_BUFSIZ - 1; - if (el->el_search.patlen != 0) { - (void) wcsncpy(el->el_search.patbuf, el->el_line.buffer, - el->el_search.patlen); - el->el_search.patbuf[el->el_search.patlen] = '\0'; - } else - el->el_search.patlen = wcslen(el->el_search.patbuf); - } -#ifdef SDEBUG - (void) fprintf(el->el_errfile, "\neventno = %d\n", - el->el_history.eventno); - (void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen); - (void) fprintf(el->el_errfile, "patbuf = \"%s\"\n", - el->el_search.patbuf); - (void) fprintf(el->el_errfile, "cursor %d lastchar %d\n", - EL_CURSOR(el) - el->el_line.buffer, - el->el_line.lastchar - el->el_line.buffer); -#endif -} - - -/* ce_inc_search(): - * Emacs incremental search - */ -libedit_private el_action_t -ce_inc_search(EditLine *el, int dir) -{ - static const wchar_t STRfwd[] = L"fwd", STRbck[] = L"bck"; - static wchar_t pchar = L':'; /* ':' = normal, '?' = failed */ - static wchar_t endcmd[2] = {'\0', '\0'}; - wchar_t *ocursor = el->el_line.cursor, oldpchar = pchar, ch; - const wchar_t *cp; - - el_action_t ret = CC_NORM; - - int ohisteventno = el->el_history.eventno; - size_t oldpatlen = el->el_search.patlen; - int newdir = dir; - int done, redo; - - if (el->el_line.lastchar + sizeof(STRfwd) / - sizeof(*el->el_line.lastchar) + 2 + - el->el_search.patlen >= el->el_line.limit) - return CC_ERROR; - - for (;;) { - - if (el->el_search.patlen == 0) { /* first round */ - pchar = ':'; -#ifdef ANCHOR -#define LEN 2 - el->el_search.patbuf[el->el_search.patlen++] = '.'; - el->el_search.patbuf[el->el_search.patlen++] = '*'; -#else -#define LEN 0 -#endif - } - done = redo = 0; - *el->el_line.lastchar++ = '\n'; - for (cp = (newdir == ED_SEARCH_PREV_HISTORY) ? STRbck : STRfwd; - *cp; *el->el_line.lastchar++ = *cp++) - continue; - *el->el_line.lastchar++ = pchar; - for (cp = &el->el_search.patbuf[LEN]; - cp < &el->el_search.patbuf[el->el_search.patlen]; - *el->el_line.lastchar++ = *cp++) - continue; - *el->el_line.lastchar = '\0'; - re_refresh(el); - - if (el_wgetc(el, &ch) != 1) - return ed_end_of_file(el, 0); - - switch (el->el_map.current[(unsigned char) ch]) { - case ED_INSERT: - case ED_DIGIT: - if (el->el_search.patlen >= EL_BUFSIZ - LEN) - terminal_beep(el); - else { - el->el_search.patbuf[el->el_search.patlen++] = - ch; - *el->el_line.lastchar++ = ch; - *el->el_line.lastchar = '\0'; - re_refresh(el); - } - break; - - case EM_INC_SEARCH_NEXT: - newdir = ED_SEARCH_NEXT_HISTORY; - redo++; - break; - - case EM_INC_SEARCH_PREV: - newdir = ED_SEARCH_PREV_HISTORY; - redo++; - break; - - case EM_DELETE_PREV_CHAR: - case ED_DELETE_PREV_CHAR: - if (el->el_search.patlen > LEN) - done++; - else - terminal_beep(el); - break; - - default: - switch (ch) { - case 0007: /* ^G: Abort */ - ret = CC_ERROR; - done++; - break; - - case 0027: /* ^W: Append word */ - /* No can do if globbing characters in pattern */ - for (cp = &el->el_search.patbuf[LEN];; cp++) - if (cp >= &el->el_search.patbuf[ - el->el_search.patlen]) { - el->el_line.cursor += - el->el_search.patlen - LEN - 1; - cp = c__next_word(el->el_line.cursor, - el->el_line.lastchar, 1, - ce__isword); - while (el->el_line.cursor < cp && - *el->el_line.cursor != '\n') { - if (el->el_search.patlen >= - EL_BUFSIZ - LEN) { - terminal_beep(el); - break; - } - el->el_search.patbuf[el->el_search.patlen++] = - *el->el_line.cursor; - *el->el_line.lastchar++ = - *el->el_line.cursor++; - } - el->el_line.cursor = ocursor; - *el->el_line.lastchar = '\0'; - re_refresh(el); - break; - } else if (isglob(*cp)) { - terminal_beep(el); - break; - } - break; - - default: /* Terminate and execute cmd */ - endcmd[0] = ch; - el_wpush(el, endcmd); - /* FALLTHROUGH */ - - case 0033: /* ESC: Terminate */ - ret = CC_REFRESH; - done++; - break; - } - break; - } - - while (el->el_line.lastchar > el->el_line.buffer && - *el->el_line.lastchar != '\n') - *el->el_line.lastchar-- = '\0'; - *el->el_line.lastchar = '\0'; - - if (!done) { - - /* Can't search if unmatched '[' */ - for (cp = &el->el_search.patbuf[el->el_search.patlen-1], - ch = L']'; - cp >= &el->el_search.patbuf[LEN]; - cp--) - if (*cp == '[' || *cp == ']') { - ch = *cp; - break; - } - if (el->el_search.patlen > LEN && ch != L'[') { - if (redo && newdir == dir) { - if (pchar == '?') { /* wrap around */ - el->el_history.eventno = - newdir == ED_SEARCH_PREV_HISTORY ? 0 : 0x7fffffff; - if (hist_get(el) == CC_ERROR) - /* el->el_history.event - * no was fixed by - * first call */ - (void) hist_get(el); - el->el_line.cursor = newdir == - ED_SEARCH_PREV_HISTORY ? - el->el_line.lastchar : - el->el_line.buffer; - } else - el->el_line.cursor += - newdir == - ED_SEARCH_PREV_HISTORY ? - -1 : 1; - } -#ifdef ANCHOR - el->el_search.patbuf[el->el_search.patlen++] = - '.'; - el->el_search.patbuf[el->el_search.patlen++] = - '*'; -#endif - el->el_search.patbuf[el->el_search.patlen] = - '\0'; - if (el->el_line.cursor < el->el_line.buffer || - el->el_line.cursor > el->el_line.lastchar || - (ret = ce_search_line(el, newdir)) - == CC_ERROR) { - /* avoid c_setpat */ - el->el_state.lastcmd = - (el_action_t) newdir; - ret = (el_action_t) - (newdir == ED_SEARCH_PREV_HISTORY ? - ed_search_prev_history(el, 0) : - ed_search_next_history(el, 0)); - if (ret != CC_ERROR) { - el->el_line.cursor = newdir == - ED_SEARCH_PREV_HISTORY ? - el->el_line.lastchar : - el->el_line.buffer; - (void) ce_search_line(el, - newdir); - } - } - el->el_search.patlen -= LEN; - el->el_search.patbuf[el->el_search.patlen] = - '\0'; - if (ret == CC_ERROR) { - terminal_beep(el); - if (el->el_history.eventno != - ohisteventno) { - el->el_history.eventno = - ohisteventno; - if (hist_get(el) == CC_ERROR) - return CC_ERROR; - } - el->el_line.cursor = ocursor; - pchar = '?'; - } else { - pchar = ':'; - } - } - ret = ce_inc_search(el, newdir); - - if (ret == CC_ERROR && pchar == '?' && oldpchar == ':') - /* - * break abort of failed search at last - * non-failed - */ - ret = CC_NORM; - - } - if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) { - /* restore on normal return or error exit */ - pchar = oldpchar; - el->el_search.patlen = oldpatlen; - if (el->el_history.eventno != ohisteventno) { - el->el_history.eventno = ohisteventno; - if (hist_get(el) == CC_ERROR) - return CC_ERROR; - } - el->el_line.cursor = ocursor; - if (ret == CC_ERROR) - re_refresh(el); - } - if (done || ret != CC_NORM) - return ret; - } -} - - -/* cv_search(): - * Vi search. - */ -libedit_private el_action_t -cv_search(EditLine *el, int dir) -{ - wchar_t ch; - wchar_t tmpbuf[EL_BUFSIZ]; - ssize_t tmplen; - -#ifdef ANCHOR - tmpbuf[0] = '.'; - tmpbuf[1] = '*'; -#endif - tmplen = LEN; - - el->el_search.patdir = dir; - - tmplen = c_gets(el, &tmpbuf[LEN], - dir == ED_SEARCH_PREV_HISTORY ? L"\n/" : L"\n?" ); - if (tmplen == -1) - return CC_REFRESH; - - tmplen += LEN; - ch = tmpbuf[tmplen]; - tmpbuf[tmplen] = '\0'; - - if (tmplen == LEN) { - /* - * Use the old pattern, but wild-card it. - */ - if (el->el_search.patlen == 0) { - re_refresh(el); - return CC_ERROR; - } -#ifdef ANCHOR - if (el->el_search.patbuf[0] != '.' && - el->el_search.patbuf[0] != '*') { - (void) wcsncpy(tmpbuf, el->el_search.patbuf, - sizeof(tmpbuf) / sizeof(*tmpbuf) - 1); - el->el_search.patbuf[0] = '.'; - el->el_search.patbuf[1] = '*'; - (void) wcsncpy(&el->el_search.patbuf[2], tmpbuf, - EL_BUFSIZ - 3); - el->el_search.patlen++; - el->el_search.patbuf[el->el_search.patlen++] = '.'; - el->el_search.patbuf[el->el_search.patlen++] = '*'; - el->el_search.patbuf[el->el_search.patlen] = '\0'; - } -#endif - } else { -#ifdef ANCHOR - tmpbuf[tmplen++] = '.'; - tmpbuf[tmplen++] = '*'; -#endif - tmpbuf[tmplen] = '\0'; - (void) wcsncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1); - el->el_search.patlen = (size_t)tmplen; - } - el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */ - el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer; - if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) : - ed_search_next_history(el, 0)) == CC_ERROR) { - re_refresh(el); - return CC_ERROR; - } - if (ch == 0033) { - re_refresh(el); - return ed_newline(el, 0); - } - return CC_REFRESH; -} - - -/* ce_search_line(): - * Look for a pattern inside a line - */ -libedit_private el_action_t -ce_search_line(EditLine *el, int dir) -{ - wchar_t *cp = el->el_line.cursor; - wchar_t *pattern = el->el_search.patbuf; - wchar_t oc, *ocp; -#ifdef ANCHOR - ocp = &pattern[1]; - oc = *ocp; - *ocp = '^'; -#else - ocp = pattern; - oc = *ocp; -#endif - - if (dir == ED_SEARCH_PREV_HISTORY) { - for (; cp >= el->el_line.buffer; cp--) { - if (el_match(cp, ocp)) { - *ocp = oc; - el->el_line.cursor = cp; - return CC_NORM; - } - } - *ocp = oc; - return CC_ERROR; - } else { - for (; *cp != '\0' && cp < el->el_line.limit; cp++) { - if (el_match(cp, ocp)) { - *ocp = oc; - el->el_line.cursor = cp; - return CC_NORM; - } - } - *ocp = oc; - return CC_ERROR; - } -} - - -/* cv_repeat_srch(): - * Vi repeat search - */ -libedit_private el_action_t -cv_repeat_srch(EditLine *el, wint_t c) -{ - -#ifdef SDEBUG - (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n", - c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf)); -#endif - - el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */ - el->el_line.lastchar = el->el_line.buffer; - - switch (c) { - case ED_SEARCH_NEXT_HISTORY: - return ed_search_next_history(el, 0); - case ED_SEARCH_PREV_HISTORY: - return ed_search_prev_history(el, 0); - default: - return CC_ERROR; - } -} - - -/* cv_csearch(): - * Vi character search - */ -libedit_private el_action_t -cv_csearch(EditLine *el, int direction, wint_t ch, int count, int tflag) -{ - wchar_t *cp; - - if (ch == 0) - return CC_ERROR; - - if (ch == (wint_t)-1) { - if (el_wgetc(el, &ch) != 1) - return ed_end_of_file(el, 0); - } - - /* Save for ';' and ',' commands */ - el->el_search.chacha = ch; - el->el_search.chadir = direction; - el->el_search.chatflg = (char)tflag; - - cp = el->el_line.cursor; - while (count--) { - if ((wint_t)*cp == ch) - cp += direction; - for (;;cp += direction) { - if (cp >= el->el_line.lastchar) - return CC_ERROR; - if (cp < el->el_line.buffer) - return CC_ERROR; - if ((wint_t)*cp == ch) - break; - } - } - - if (tflag) - cp -= direction; - - el->el_line.cursor = cp; - - if (el->el_chared.c_vcmd.action != NOP) { - if (direction > 0) - el->el_line.cursor++; - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/search.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/search.h deleted file mode 100644 index 4ca39c4..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/search.h +++ /dev/null @@ -1,64 +0,0 @@ -/* $NetBSD: search.h,v 1.14 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)search.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.search.h: Line and history searching utilities - */ -#ifndef _h_el_search -#define _h_el_search - -typedef struct el_search_t { - wchar_t *patbuf; /* The pattern buffer */ - size_t patlen; /* Length of the pattern buffer */ - int patdir; /* Direction of the last search */ - int chadir; /* Character search direction */ - wchar_t chacha; /* Character we are looking for */ - char chatflg; /* 0 if f, 1 if t */ -} el_search_t; - - -libedit_private int el_match(const wchar_t *, const wchar_t *); -libedit_private int search_init(EditLine *); -libedit_private void search_end(EditLine *); -libedit_private int c_hmatch(EditLine *, const wchar_t *); -libedit_private void c_setpat(EditLine *); -libedit_private el_action_t ce_inc_search(EditLine *, int); -libedit_private el_action_t cv_search(EditLine *, int); -libedit_private el_action_t ce_search_line(EditLine *, int); -libedit_private el_action_t cv_repeat_srch(EditLine *, wint_t); -libedit_private el_action_t cv_csearch(EditLine *, int, wint_t, int, int); - -#endif /* _h_el_search */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sig.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sig.c deleted file mode 100644 index 83742a3..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sig.c +++ /dev/null @@ -1,205 +0,0 @@ -/* $NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * sig.c: Signal handling stuff. - * our policy is to trap all signals, set a good state - * and pass the ball to our caller. - */ -#include -#include - -#include "el.h" -#include "common.h" - -static EditLine *sel = NULL; - -static const int sighdl[] = { -#define _DO(a) (a), - ALLSIGS -#undef _DO - - 1 -}; - -static void sig_handler(int); - -/* sig_handler(): - * This is the handler called for all signals - * XXX: we cannot pass any data so we just store the old editline - * state in a private variable - */ -static void -sig_handler(int signo) -{ - int i, save_errno; - sigset_t nset, oset; - - save_errno = errno; - (void) sigemptyset(&nset); - (void) sigaddset(&nset, signo); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - - sel->el_signal->sig_no = signo; - - switch (signo) { - case SIGCONT: - tty_rawmode(sel); - if (ed_redisplay(sel, 0) == CC_REFRESH) - re_refresh(sel); - terminal__flush(sel); - break; - - case SIGWINCH: - el_resize(sel); - break; - - default: - tty_cookedmode(sel); - break; - } - - for (i = 0; sighdl[i] != -1; i++) - if (signo == sighdl[i]) - break; - - (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL); - sel->el_signal->sig_action[i].sa_handler = SIG_ERR; - sel->el_signal->sig_action[i].sa_flags = 0; - sigemptyset(&sel->el_signal->sig_action[i].sa_mask); - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - (void) kill(0, signo); - errno = save_errno; -} - - -/* sig_init(): - * Initialize all signal stuff - */ -libedit_private int -sig_init(EditLine *el) -{ - size_t i; - sigset_t *nset, oset; - - el->el_signal = el_malloc(sizeof(*el->el_signal)); - if (el->el_signal == NULL) - return -1; - - nset = &el->el_signal->sig_set; - (void) sigemptyset(nset); -#define _DO(a) (void) sigaddset(nset, a); - ALLSIGS -#undef _DO - (void) sigprocmask(SIG_BLOCK, nset, &oset); - - for (i = 0; sighdl[i] != -1; i++) { - el->el_signal->sig_action[i].sa_handler = SIG_ERR; - el->el_signal->sig_action[i].sa_flags = 0; - sigemptyset(&el->el_signal->sig_action[i].sa_mask); - } - - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - - return 0; -} - - -/* sig_end(): - * Clear all signal stuff - */ -libedit_private void -sig_end(EditLine *el) -{ - - el_free(el->el_signal); - el->el_signal = NULL; -} - - -/* sig_set(): - * set all the signal handlers - */ -libedit_private void -sig_set(EditLine *el) -{ - size_t i; - sigset_t oset; - struct sigaction osa, nsa; - - nsa.sa_handler = sig_handler; - nsa.sa_flags = 0; - sigemptyset(&nsa.sa_mask); - - (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); - - for (i = 0; sighdl[i] != -1; i++) { - /* This could happen if we get interrupted */ - if (sigaction(sighdl[i], &nsa, &osa) != -1 && - osa.sa_handler != sig_handler) - el->el_signal->sig_action[i] = osa; - } - sel = el; - (void) sigprocmask(SIG_SETMASK, &oset, NULL); -} - - -/* sig_clr(): - * clear all the signal handlers - */ -libedit_private void -sig_clr(EditLine *el) -{ - size_t i; - sigset_t oset; - - (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); - - for (i = 0; sighdl[i] != -1; i++) - if (el->el_signal->sig_action[i].sa_handler != SIG_ERR) - (void)sigaction(sighdl[i], - &el->el_signal->sig_action[i], NULL); - - sel = NULL; /* we are going to die if the handler is - * called */ - (void)sigprocmask(SIG_SETMASK, &oset, NULL); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sig.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sig.h deleted file mode 100644 index 5ee453f..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sig.h +++ /dev/null @@ -1,70 +0,0 @@ -/* $NetBSD: sig.h,v 1.11 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)sig.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.sig.h: Signal handling functions - */ -#ifndef _h_el_sig -#define _h_el_sig - -#include - -/* - * Define here all the signals we are going to handle - * The _DO macro is used to iterate in the source code - */ -#define ALLSIGS \ - _DO(SIGINT) \ - _DO(SIGTSTP) \ - _DO(SIGQUIT) \ - _DO(SIGHUP) \ - _DO(SIGTERM) \ - _DO(SIGCONT) \ - _DO(SIGWINCH) -#define ALLSIGSNO 7 - -typedef struct { - struct sigaction sig_action[ALLSIGSNO]; - sigset_t sig_set; - volatile sig_atomic_t sig_no; -} *el_signal_t; - -libedit_private void sig_end(EditLine*); -libedit_private int sig_init(EditLine*); -libedit_private void sig_set(EditLine*); -libedit_private void sig_clr(EditLine*); - -#endif /* _h_el_sig */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/strlcat.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/strlcat.c deleted file mode 100644 index c1ef3a2..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/strlcat.c +++ /dev/null @@ -1,90 +0,0 @@ -/* $NetBSD: strlcat.c,v 1.4 2013/01/23 07:57:27 matt Exp $ */ -/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE - * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "config.h" - -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strlcat.c,v 1.4 2013/01/23 07:57:27 matt Exp $"); -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -#ifdef _LIBC -# ifdef __weak_alias -__weak_alias(strlcat, _strlcat) -# endif -#endif - -#if !HAVE_STRLCAT -/* - * Appends src to string dst of size siz (unlike strncat, siz is the - * full size of dst, not space left). At most siz-1 characters - * will be copied. Always NUL terminates (unless siz <= strlen(dst)). - * Returns strlen(src) + MIN(siz, strlen(initial dst)). - * If retval >= siz, truncation occurred. - */ -size_t -strlcat(char *dst, const char *src, size_t siz) -{ -#if 1 - char *d = dst; - const char *s = src; - size_t n = siz; - size_t dlen; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - dlen = d - dst; - n = siz - dlen; - - if (n == 0) - return(dlen + strlen(s)); - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = '\0'; - - return(dlen + (s - src)); /* count does not include NUL */ -#else - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - - /* - * Find length of string in dst (maxing out at siz). - */ - size_t dlen = strnlen(dst, siz); - - /* - * Copy src into any remaining space in dst (truncating if needed). - * Note strlcpy(dst, src, 0) returns strlen(src). - */ - return dlen + strlcpy(dst + dlen, src, siz - dlen); -#endif -} -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/strlcpy.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/strlcpy.c deleted file mode 100644 index 8b3dfad..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/strlcpy.c +++ /dev/null @@ -1,70 +0,0 @@ -/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */ -/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE - * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "config.h" - -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $"); -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -#ifdef _LIBC -# ifdef __weak_alias -__weak_alias(strlcpy, _strlcpy) -# endif -#endif - -#if !HAVE_STRLCPY -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -strlcpy(char *dst, const char *src, size_t siz) -{ - char *d = dst; - const char *s = src; - size_t n = siz; - - _DIAGASSERT(dst != NULL); - _DIAGASSERT(src != NULL); - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sys.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sys.h deleted file mode 100644 index e575432..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/sys.h +++ /dev/null @@ -1,127 +0,0 @@ -/* $NetBSD: sys.h,v 1.27 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)sys.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * sys.h: Put all the stupid compiler and system dependencies here... - */ -#ifndef _h_sys -#define _h_sys - -#ifdef HAVE_SYS_CDEFS_H -#include -#endif - -#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) -# define __attribute__(A) -#endif - -#ifndef _DIAGASSERT -# define _DIAGASSERT(x) -#endif - -#ifndef __BEGIN_DECLS -# ifdef __cplusplus -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -#endif - -/* If your compiler does not support this, define it to be empty. */ -#define libedit_private __attribute__((__visibility__("hidden"))) - -#ifndef __arraycount -# define __arraycount(a) (sizeof(a) / sizeof(*(a))) -#endif - -#ifndef _PTR_T -# define _PTR_T -typedef void *ptr_t; -#endif - -#ifndef _IOCTL_T -# define _IOCTL_T -typedef void *ioctl_t; -#endif - -#include - -#ifndef HAVE_STRLCAT -#define strlcat libedit_strlcat -size_t strlcat(char *dst, const char *src, size_t size); -#endif - -#ifndef HAVE_STRLCPY -#define strlcpy libedit_strlcpy -size_t strlcpy(char *dst, const char *src, size_t size); -#endif - -#ifndef HAVE_GETLINE -#define getline libedit_getline -ssize_t getline(char **line, size_t *len, FILE *fp); -#endif - -#ifndef _DIAGASSERT -#define _DIAGASSERT(x) -#endif - -#ifndef __RCSID -#define __RCSID(x) -#endif - -#ifndef HAVE_U_INT32_T -typedef unsigned int u_int32_t; -#endif - -#ifndef HAVE_SIZE_MAX -#define SIZE_MAX ((size_t)-1) -#endif - -#define REGEX /* Use POSIX.2 regular expression functions */ -#undef REGEXP /* Use UNIX V8 regular expression functions */ - -#if defined(__sun) -extern int tgetent(char *, const char *); -extern int tgetflag(char *); -extern int tgetnum(char *); -extern int tputs(const char *, int, int (*)(int)); -extern char* tgoto(const char*, int, int); -extern char* tgetstr(char*, char**); -#endif - -#endif /* _h_sys */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/terminal.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/terminal.c deleted file mode 100644 index 26838e8..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/terminal.c +++ /dev/null @@ -1,1682 +0,0 @@ -/* $NetBSD: terminal.c,v 1.32 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; -#else -__RCSID("$NetBSD: terminal.c,v 1.32 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * terminal.c: Editor/termcap-curses interface - * We have to declare a static variable here, since the - * termcap putchar routine does not take an argument! - */ -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_TERMCAP_H -#include -#endif -#ifdef HAVE_CURSES_H -#include -#elif HAVE_NCURSES_H -#include -#endif - -/* Solaris's term.h does horrid things. */ -#if defined(HAVE_TERM_H) && !defined(__sun) && !defined(HAVE_TERMCAP_H) -#include -#endif - -#ifdef _REENTRANT -#include -#endif - -#include "el.h" -#include "fcns.h" - -/* - * IMPORTANT NOTE: these routines are allowed to look at the current screen - * and the current position assuming that it is correct. If this is not - * true, then the update will be WRONG! This is (should be) a valid - * assumption... - */ - -#define TC_BUFSIZE ((size_t)2048) - -#define GoodStr(a) (el->el_terminal.t_str[a] != NULL && \ - el->el_terminal.t_str[a][0] != '\0') -#define Str(a) el->el_terminal.t_str[a] -#define Val(a) el->el_terminal.t_val[a] - -static const struct termcapstr { - const char *name; - const char *long_name; -} tstr[] = { -#define T_al 0 - { "al", "add new blank line" }, -#define T_bl 1 - { "bl", "audible bell" }, -#define T_cd 2 - { "cd", "clear to bottom" }, -#define T_ce 3 - { "ce", "clear to end of line" }, -#define T_ch 4 - { "ch", "cursor to horiz pos" }, -#define T_cl 5 - { "cl", "clear screen" }, -#define T_dc 6 - { "dc", "delete a character" }, -#define T_dl 7 - { "dl", "delete a line" }, -#define T_dm 8 - { "dm", "start delete mode" }, -#define T_ed 9 - { "ed", "end delete mode" }, -#define T_ei 10 - { "ei", "end insert mode" }, -#define T_fs 11 - { "fs", "cursor from status line" }, -#define T_ho 12 - { "ho", "home cursor" }, -#define T_ic 13 - { "ic", "insert character" }, -#define T_im 14 - { "im", "start insert mode" }, -#define T_ip 15 - { "ip", "insert padding" }, -#define T_kd 16 - { "kd", "sends cursor down" }, -#define T_kl 17 - { "kl", "sends cursor left" }, -#define T_kr 18 - { "kr", "sends cursor right" }, -#define T_ku 19 - { "ku", "sends cursor up" }, -#define T_md 20 - { "md", "begin bold" }, -#define T_me 21 - { "me", "end attributes" }, -#define T_nd 22 - { "nd", "non destructive space" }, -#define T_se 23 - { "se", "end standout" }, -#define T_so 24 - { "so", "begin standout" }, -#define T_ts 25 - { "ts", "cursor to status line" }, -#define T_up 26 - { "up", "cursor up one" }, -#define T_us 27 - { "us", "begin underline" }, -#define T_ue 28 - { "ue", "end underline" }, -#define T_vb 29 - { "vb", "visible bell" }, -#define T_DC 30 - { "DC", "delete multiple chars" }, -#define T_DO 31 - { "DO", "cursor down multiple" }, -#define T_IC 32 - { "IC", "insert multiple chars" }, -#define T_LE 33 - { "LE", "cursor left multiple" }, -#define T_RI 34 - { "RI", "cursor right multiple" }, -#define T_UP 35 - { "UP", "cursor up multiple" }, -#define T_kh 36 - { "kh", "send cursor home" }, -#define T_at7 37 - { "@7", "send cursor end" }, -#define T_kD 38 - { "kD", "send cursor delete" }, -#define T_str 39 - { NULL, NULL } -}; - -static const struct termcapval { - const char *name; - const char *long_name; -} tval[] = { -#define T_am 0 - { "am", "has automatic margins" }, -#define T_pt 1 - { "pt", "has physical tabs" }, -#define T_li 2 - { "li", "Number of lines" }, -#define T_co 3 - { "co", "Number of columns" }, -#define T_km 4 - { "km", "Has meta key" }, -#define T_xt 5 - { "xt", "Tab chars destructive" }, -#define T_xn 6 - { "xn", "newline ignored at right margin" }, -#define T_MT 7 - { "MT", "Has meta key" }, /* XXX? */ -#define T_val 8 - { NULL, NULL, } -}; -/* do two or more of the attributes use me */ - -static void terminal_setflags(EditLine *); -static int terminal_rebuffer_display(EditLine *); -static void terminal_free_display(EditLine *); -static int terminal_alloc_display(EditLine *); -static void terminal_alloc(EditLine *, const struct termcapstr *, - const char *); -static void terminal_init_arrow(EditLine *); -static void terminal_reset_arrow(EditLine *); -static int terminal_putc(int); -static void terminal_tputs(EditLine *, const char *, int); - -#ifdef _REENTRANT -static pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif -static FILE *terminal_outfile = NULL; - - -/* terminal_setflags(): - * Set the terminal capability flags - */ -static void -terminal_setflags(EditLine *el) -{ - EL_FLAGS = 0; - if (el->el_tty.t_tabs) - EL_FLAGS |= (Val(T_pt) && !Val(T_xt)) ? TERM_CAN_TAB : 0; - - EL_FLAGS |= (Val(T_km) || Val(T_MT)) ? TERM_HAS_META : 0; - EL_FLAGS |= GoodStr(T_ce) ? TERM_CAN_CEOL : 0; - EL_FLAGS |= (GoodStr(T_dc) || GoodStr(T_DC)) ? TERM_CAN_DELETE : 0; - EL_FLAGS |= (GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC)) ? - TERM_CAN_INSERT : 0; - EL_FLAGS |= (GoodStr(T_up) || GoodStr(T_UP)) ? TERM_CAN_UP : 0; - EL_FLAGS |= Val(T_am) ? TERM_HAS_AUTO_MARGINS : 0; - EL_FLAGS |= Val(T_xn) ? TERM_HAS_MAGIC_MARGINS : 0; - - if (GoodStr(T_me) && GoodStr(T_ue)) - EL_FLAGS |= (strcmp(Str(T_me), Str(T_ue)) == 0) ? - TERM_CAN_ME : 0; - else - EL_FLAGS &= ~TERM_CAN_ME; - if (GoodStr(T_me) && GoodStr(T_se)) - EL_FLAGS |= (strcmp(Str(T_me), Str(T_se)) == 0) ? - TERM_CAN_ME : 0; - - -#ifdef DEBUG_SCREEN - if (!EL_CAN_UP) { - (void) fprintf(el->el_errfile, - "WARNING: Your terminal cannot move up.\n"); - (void) fprintf(el->el_errfile, - "Editing may be odd for long lines.\n"); - } - if (!EL_CAN_CEOL) - (void) fprintf(el->el_errfile, "no clear EOL capability.\n"); - if (!EL_CAN_DELETE) - (void) fprintf(el->el_errfile, "no delete char capability.\n"); - if (!EL_CAN_INSERT) - (void) fprintf(el->el_errfile, "no insert char capability.\n"); -#endif /* DEBUG_SCREEN */ -} - -/* terminal_init(): - * Initialize the terminal stuff - */ -libedit_private int -terminal_init(EditLine *el) -{ - - el->el_terminal.t_buf = el_malloc(TC_BUFSIZE * - sizeof(*el->el_terminal.t_buf)); - if (el->el_terminal.t_buf == NULL) - goto fail1; - el->el_terminal.t_cap = el_malloc(TC_BUFSIZE * - sizeof(*el->el_terminal.t_cap)); - if (el->el_terminal.t_cap == NULL) - goto fail2; - el->el_terminal.t_fkey = el_malloc(A_K_NKEYS * - sizeof(*el->el_terminal.t_fkey)); - if (el->el_terminal.t_fkey == NULL) - goto fail3; - el->el_terminal.t_loc = 0; - el->el_terminal.t_str = el_malloc(T_str * - sizeof(*el->el_terminal.t_str)); - if (el->el_terminal.t_str == NULL) - goto fail4; - (void) memset(el->el_terminal.t_str, 0, T_str * - sizeof(*el->el_terminal.t_str)); - el->el_terminal.t_val = el_malloc(T_val * - sizeof(*el->el_terminal.t_val)); - if (el->el_terminal.t_val == NULL) - goto fail5; - (void) memset(el->el_terminal.t_val, 0, T_val * - sizeof(*el->el_terminal.t_val)); - (void) terminal_set(el, NULL); - terminal_init_arrow(el); - return 0; -fail5: - free(el->el_terminal.t_str); - el->el_terminal.t_str = NULL; -fail4: - free(el->el_terminal.t_fkey); - el->el_terminal.t_fkey = NULL; -fail3: - free(el->el_terminal.t_cap); - el->el_terminal.t_cap = NULL; -fail2: - free(el->el_terminal.t_buf); - el->el_terminal.t_buf = NULL; -fail1: - return -1; -} - -/* terminal_end(): - * Clean up the terminal stuff - */ -libedit_private void -terminal_end(EditLine *el) -{ - - el_free(el->el_terminal.t_buf); - el->el_terminal.t_buf = NULL; - el_free(el->el_terminal.t_cap); - el->el_terminal.t_cap = NULL; - el->el_terminal.t_loc = 0; - el_free(el->el_terminal.t_str); - el->el_terminal.t_str = NULL; - el_free(el->el_terminal.t_val); - el->el_terminal.t_val = NULL; - el_free(el->el_terminal.t_fkey); - el->el_terminal.t_fkey = NULL; - terminal_free_display(el); -} - - -/* terminal_alloc(): - * Maintain a string pool for termcap strings - */ -static void -terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap) -{ - char termbuf[TC_BUFSIZE]; - size_t tlen, clen; - char **tlist = el->el_terminal.t_str; - char **tmp, **str = &tlist[t - tstr]; - - (void) memset(termbuf, 0, sizeof(termbuf)); - if (cap == NULL || *cap == '\0') { - *str = NULL; - return; - } else - clen = strlen(cap); - - tlen = *str == NULL ? 0 : strlen(*str); - - /* - * New string is shorter; no need to allocate space - */ - if (clen <= tlen) { - if (*str) - (void) strcpy(*str, cap); /* XXX strcpy is safe */ - return; - } - /* - * New string is longer; see if we have enough space to append - */ - if (el->el_terminal.t_loc + 3 < TC_BUFSIZE) { - /* XXX strcpy is safe */ - (void) strcpy(*str = &el->el_terminal.t_buf[ - el->el_terminal.t_loc], cap); - el->el_terminal.t_loc += clen + 1; /* one for \0 */ - return; - } - /* - * Compact our buffer; no need to check compaction, cause we know it - * fits... - */ - tlen = 0; - for (tmp = tlist; tmp < &tlist[T_str]; tmp++) - if (*tmp != NULL && **tmp != '\0' && *tmp != *str) { - char *ptr; - - for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++) - continue; - termbuf[tlen++] = '\0'; - } - memcpy(el->el_terminal.t_buf, termbuf, TC_BUFSIZE); - el->el_terminal.t_loc = tlen; - if (el->el_terminal.t_loc + 3 >= TC_BUFSIZE) { - (void) fprintf(el->el_errfile, - "Out of termcap string space.\n"); - return; - } - /* XXX strcpy is safe */ - (void) strcpy(*str = &el->el_terminal.t_buf[el->el_terminal.t_loc], - cap); - el->el_terminal.t_loc += (size_t)clen + 1; /* one for \0 */ - return; -} - - -/* terminal_rebuffer_display(): - * Rebuffer the display after the screen changed size - */ -static int -terminal_rebuffer_display(EditLine *el) -{ - coord_t *c = &el->el_terminal.t_size; - - terminal_free_display(el); - - c->h = Val(T_co); - c->v = Val(T_li); - - if (terminal_alloc_display(el) == -1) - return -1; - return 0; -} - - -/* terminal_alloc_display(): - * Allocate a new display. - */ -static int -terminal_alloc_display(EditLine *el) -{ - int i; - wchar_t **b; - coord_t *c = &el->el_terminal.t_size; - - b = el_malloc(sizeof(*b) * (size_t)(c->v + 1)); - if (b == NULL) - goto done; - for (i = 0; i < c->v; i++) { - b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1)); - if (b[i] == NULL) { - while (--i >= 0) - el_free(b[i]); - el_free(b); - goto done; - } - } - b[c->v] = NULL; - el->el_display = b; - - b = el_malloc(sizeof(*b) * (size_t)(c->v + 1)); - if (b == NULL) - goto done; - for (i = 0; i < c->v; i++) { - b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1)); - if (b[i] == NULL) { - while (--i >= 0) - el_free(b[i]); - el_free(b); - goto done; - } - } - b[c->v] = NULL; - el->el_vdisplay = b; - return 0; -done: - terminal_free_display(el); - return -1; -} - - -/* terminal_free_display(): - * Free the display buffers - */ -static void -terminal_free_display(EditLine *el) -{ - wchar_t **b; - wchar_t **bufp; - - b = el->el_display; - el->el_display = NULL; - if (b != NULL) { - for (bufp = b; *bufp != NULL; bufp++) - el_free(*bufp); - el_free(b); - } - b = el->el_vdisplay; - el->el_vdisplay = NULL; - if (b != NULL) { - for (bufp = b; *bufp != NULL; bufp++) - el_free(*bufp); - el_free(b); - } -} - - -/* terminal_move_to_line(): - * move to line (first line == 0) - * as efficiently as possible - */ -libedit_private void -terminal_move_to_line(EditLine *el, int where) -{ - int del; - - if (where == el->el_cursor.v) - return; - - if (where > el->el_terminal.t_size.v) { -#ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "%s: where is ridiculous: %d\r\n", __func__, where); -#endif /* DEBUG_SCREEN */ - return; - } - if ((del = where - el->el_cursor.v) > 0) { - while (del > 0) { - if (EL_HAS_AUTO_MARGINS && - el->el_display[el->el_cursor.v][0] != '\0') { - size_t h = (size_t) - (el->el_terminal.t_size.h - 1); - for (; h > 0 && - el->el_display[el->el_cursor.v][h] == - MB_FILL_CHAR; - h--) - continue; - /* move without newline */ - terminal_move_to_char(el, (int)h); - terminal_overwrite(el, &el->el_display - [el->el_cursor.v][el->el_cursor.h], - (size_t)(el->el_terminal.t_size.h - - el->el_cursor.h)); - /* updates Cursor */ - del--; - } else { - if ((del > 1) && GoodStr(T_DO)) { - terminal_tputs(el, tgoto(Str(T_DO), del, - del), del); - del = 0; - } else { - for (; del > 0; del--) - terminal__putc(el, '\n'); - /* because the \n will become \r\n */ - el->el_cursor.h = 0; - } - } - } - } else { /* del < 0 */ - if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) - terminal_tputs(el, tgoto(Str(T_UP), -del, -del), -del); - else { - if (GoodStr(T_up)) - for (; del < 0; del++) - terminal_tputs(el, Str(T_up), 1); - } - } - el->el_cursor.v = where;/* now where is here */ -} - - -/* terminal_move_to_char(): - * Move to the character position specified - */ -libedit_private void -terminal_move_to_char(EditLine *el, int where) -{ - int del, i; - -mc_again: - if (where == el->el_cursor.h) - return; - - if (where > el->el_terminal.t_size.h) { -#ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "%s: where is ridiculous: %d\r\n", __func__, where); -#endif /* DEBUG_SCREEN */ - return; - } - if (!where) { /* if where is first column */ - terminal__putc(el, '\r'); /* do a CR */ - el->el_cursor.h = 0; - return; - } - del = where - el->el_cursor.h; - - if ((del < -4 || del > 4) && GoodStr(T_ch)) - /* go there directly */ - terminal_tputs(el, tgoto(Str(T_ch), where, where), where); - else { - if (del > 0) { /* moving forward */ - if ((del > 4) && GoodStr(T_RI)) - terminal_tputs(el, tgoto(Str(T_RI), del, del), - del); - else { - /* if I can do tabs, use them */ - if (EL_CAN_TAB) { - if ((el->el_cursor.h & 0370) != - (where & ~0x7) - && (el->el_display[ - el->el_cursor.v][where & 0370] != - MB_FILL_CHAR) - ) { - /* if not within tab stop */ - for (i = - (el->el_cursor.h & 0370); - i < (where & ~0x7); - i += 8) - terminal__putc(el, - '\t'); - /* then tab over */ - el->el_cursor.h = where & ~0x7; - } - } - /* - * it's usually cheaper to just write the - * chars, so we do. - */ - /* - * NOTE THAT terminal_overwrite() WILL CHANGE - * el->el_cursor.h!!! - */ - terminal_overwrite(el, &el->el_display[ - el->el_cursor.v][el->el_cursor.h], - (size_t)(where - el->el_cursor.h)); - - } - } else { /* del < 0 := moving backward */ - if ((-del > 4) && GoodStr(T_LE)) - terminal_tputs(el, tgoto(Str(T_LE), -del, -del), - -del); - else { /* can't go directly there */ - /* - * if the "cost" is greater than the "cost" - * from col 0 - */ - if (EL_CAN_TAB ? - ((unsigned int)-del > - (((unsigned int) where >> 3) + - (where & 07))) - : (-del > where)) { - terminal__putc(el, '\r');/* do a CR */ - el->el_cursor.h = 0; - goto mc_again; /* and try again */ - } - for (i = 0; i < -del; i++) - terminal__putc(el, '\b'); - } - } - } - el->el_cursor.h = where; /* now where is here */ -} - - -/* terminal_overwrite(): - * Overstrike num characters - * Assumes MB_FILL_CHARs are present to keep the column count correct - */ -libedit_private void -terminal_overwrite(EditLine *el, const wchar_t *cp, size_t n) -{ - if (n == 0) - return; - - if (n > (size_t)el->el_terminal.t_size.h) { -#ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "%s: n is ridiculous: %zu\r\n", __func__, n); -#endif /* DEBUG_SCREEN */ - return; - } - - do { - /* terminal__putc() ignores any MB_FILL_CHARs */ - terminal__putc(el, *cp++); - el->el_cursor.h++; - } while (--n); - - if (el->el_cursor.h >= el->el_terminal.t_size.h) { /* wrap? */ - if (EL_HAS_AUTO_MARGINS) { /* yes */ - el->el_cursor.h = 0; - el->el_cursor.v++; - if (EL_HAS_MAGIC_MARGINS) { - /* force the wrap to avoid the "magic" - * situation */ - wchar_t c; - if ((c = el->el_display[el->el_cursor.v] - [el->el_cursor.h]) != '\0') { - terminal_overwrite(el, &c, (size_t)1); - while (el->el_display[el->el_cursor.v] - [el->el_cursor.h] == MB_FILL_CHAR) - el->el_cursor.h++; - } else { - terminal__putc(el, ' '); - el->el_cursor.h = 1; - } - } - } else /* no wrap, but cursor stays on screen */ - el->el_cursor.h = el->el_terminal.t_size.h - 1; - } -} - - -/* terminal_deletechars(): - * Delete num characters - */ -libedit_private void -terminal_deletechars(EditLine *el, int num) -{ - if (num <= 0) - return; - - if (!EL_CAN_DELETE) { -#ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, " ERROR: cannot delete \n"); -#endif /* DEBUG_EDIT */ - return; - } - if (num > el->el_terminal.t_size.h) { -#ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "%s: num is ridiculous: %d\r\n", __func__, num); -#endif /* DEBUG_SCREEN */ - return; - } - if (GoodStr(T_DC)) /* if I have multiple delete */ - if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more - * expen. */ - terminal_tputs(el, tgoto(Str(T_DC), num, num), num); - return; - } - if (GoodStr(T_dm)) /* if I have delete mode */ - terminal_tputs(el, Str(T_dm), 1); - - if (GoodStr(T_dc)) /* else do one at a time */ - while (num--) - terminal_tputs(el, Str(T_dc), 1); - - if (GoodStr(T_ed)) /* if I have delete mode */ - terminal_tputs(el, Str(T_ed), 1); -} - - -/* terminal_insertwrite(): - * Puts terminal in insert character mode or inserts num - * characters in the line - * Assumes MB_FILL_CHARs are present to keep column count correct - */ -libedit_private void -terminal_insertwrite(EditLine *el, wchar_t *cp, int num) -{ - if (num <= 0) - return; - if (!EL_CAN_INSERT) { -#ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, " ERROR: cannot insert \n"); -#endif /* DEBUG_EDIT */ - return; - } - if (num > el->el_terminal.t_size.h) { -#ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "%s: num is ridiculous: %d\r\n", __func__, num); -#endif /* DEBUG_SCREEN */ - return; - } - if (GoodStr(T_IC)) /* if I have multiple insert */ - if ((num > 1) || !GoodStr(T_ic)) { - /* if ic would be more expensive */ - terminal_tputs(el, tgoto(Str(T_IC), num, num), num); - terminal_overwrite(el, cp, (size_t)num); - /* this updates el_cursor.h */ - return; - } - if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ - terminal_tputs(el, Str(T_im), 1); - - el->el_cursor.h += num; - do - terminal__putc(el, *cp++); - while (--num); - - if (GoodStr(T_ip)) /* have to make num chars insert */ - terminal_tputs(el, Str(T_ip), 1); - - terminal_tputs(el, Str(T_ei), 1); - return; - } - do { - if (GoodStr(T_ic)) /* have to make num chars insert */ - terminal_tputs(el, Str(T_ic), 1); - - terminal__putc(el, *cp++); - - el->el_cursor.h++; - - if (GoodStr(T_ip)) /* have to make num chars insert */ - terminal_tputs(el, Str(T_ip), 1); - /* pad the inserted char */ - - } while (--num); -} - - -/* terminal_clear_EOL(): - * clear to end of line. There are num characters to clear - */ -libedit_private void -terminal_clear_EOL(EditLine *el, int num) -{ - int i; - - if (EL_CAN_CEOL && GoodStr(T_ce)) - terminal_tputs(el, Str(T_ce), 1); - else { - for (i = 0; i < num; i++) - terminal__putc(el, ' '); - el->el_cursor.h += num; /* have written num spaces */ - } -} - - -/* terminal_clear_screen(): - * Clear the screen - */ -libedit_private void -terminal_clear_screen(EditLine *el) -{ /* clear the whole screen and home */ - - if (GoodStr(T_cl)) - /* send the clear screen code */ - terminal_tputs(el, Str(T_cl), Val(T_li)); - else if (GoodStr(T_ho) && GoodStr(T_cd)) { - terminal_tputs(el, Str(T_ho), Val(T_li)); /* home */ - /* clear to bottom of screen */ - terminal_tputs(el, Str(T_cd), Val(T_li)); - } else { - terminal__putc(el, '\r'); - terminal__putc(el, '\n'); - } -} - - -/* terminal_beep(): - * Beep the way the terminal wants us - */ -libedit_private void -terminal_beep(EditLine *el) -{ - if (GoodStr(T_bl)) - /* what termcap says we should use */ - terminal_tputs(el, Str(T_bl), 1); - else - terminal__putc(el, '\007'); /* an ASCII bell; ^G */ -} - - -libedit_private void -terminal_get(EditLine *el, const char **term) -{ - *term = el->el_terminal.t_name; -} - - -/* terminal_set(): - * Read in the terminal capabilities from the requested terminal - */ -libedit_private int -terminal_set(EditLine *el, const char *term) -{ - int i; - char buf[TC_BUFSIZE]; - char *area; - const struct termcapstr *t; - sigset_t oset, nset; - int lins, cols; - - (void) sigemptyset(&nset); - (void) sigaddset(&nset, SIGWINCH); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - - area = buf; - - - if (term == NULL) - term = getenv("TERM"); - - if (!term || !term[0]) - term = "dumb"; - - if (strcmp(term, "emacs") == 0) - el->el_flags |= EDIT_DISABLED; - - (void) memset(el->el_terminal.t_cap, 0, TC_BUFSIZE); - - i = tgetent(el->el_terminal.t_cap, term); - - if (i <= 0) { - if (i == -1) - (void) fprintf(el->el_errfile, - "Cannot read termcap database;\n"); - else if (i == 0) - (void) fprintf(el->el_errfile, - "No entry for terminal type \"%s\";\n", term); - (void) fprintf(el->el_errfile, - "using dumb terminal settings.\n"); - Val(T_co) = 80; /* do a dumb terminal */ - Val(T_pt) = Val(T_km) = Val(T_li) = 0; - Val(T_xt) = Val(T_MT); - for (t = tstr; t->name != NULL; t++) - terminal_alloc(el, t, NULL); - } else { - /* auto/magic margins */ - Val(T_am) = tgetflag("am"); - Val(T_xn) = tgetflag("xn"); - /* Can we tab */ - Val(T_pt) = tgetflag("pt"); - Val(T_xt) = tgetflag("xt"); - /* do we have a meta? */ - Val(T_km) = tgetflag("km"); - Val(T_MT) = tgetflag("MT"); - /* Get the size */ - Val(T_co) = tgetnum("co"); - Val(T_li) = tgetnum("li"); - for (t = tstr; t->name != NULL; t++) { - /* XXX: some systems' tgetstr needs non const */ - terminal_alloc(el, t, tgetstr(strchr(t->name, *t->name), - &area)); - } - } - - if (Val(T_co) < 2) - Val(T_co) = 80; /* just in case */ - if (Val(T_li) < 1) - Val(T_li) = 24; - - el->el_terminal.t_size.v = Val(T_co); - el->el_terminal.t_size.h = Val(T_li); - - terminal_setflags(el); - - /* get the correct window size */ - (void) terminal_get_size(el, &lins, &cols); - if (terminal_change_size(el, lins, cols) == -1) - return -1; - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - terminal_bind_arrow(el); - el->el_terminal.t_name = term; - return i <= 0 ? -1 : 0; -} - - -/* terminal_get_size(): - * Return the new window size in lines and cols, and - * true if the size was changed. - */ -libedit_private int -terminal_get_size(EditLine *el, int *lins, int *cols) -{ - - *cols = Val(T_co); - *lins = Val(T_li); - -#ifdef TIOCGWINSZ - { - struct winsize ws; - if (ioctl(el->el_infd, TIOCGWINSZ, &ws) != -1) { - if (ws.ws_col) - *cols = ws.ws_col; - if (ws.ws_row) - *lins = ws.ws_row; - } - } -#endif -#ifdef TIOCGSIZE - { - struct ttysize ts; - if (ioctl(el->el_infd, TIOCGSIZE, &ts) != -1) { - if (ts.ts_cols) - *cols = ts.ts_cols; - if (ts.ts_lines) - *lins = ts.ts_lines; - } - } -#endif - return Val(T_co) != *cols || Val(T_li) != *lins; -} - - -/* terminal_change_size(): - * Change the size of the terminal - */ -libedit_private int -terminal_change_size(EditLine *el, int lins, int cols) -{ - /* - * Just in case - */ - Val(T_co) = (cols < 2) ? 80 : cols; - Val(T_li) = (lins < 1) ? 24 : lins; - - /* re-make display buffers */ - if (terminal_rebuffer_display(el) == -1) - return -1; - re_clear_display(el); - return 0; -} - - -/* terminal_init_arrow(): - * Initialize the arrow key bindings from termcap - */ -static void -terminal_init_arrow(EditLine *el) -{ - funckey_t *arrow = el->el_terminal.t_fkey; - - arrow[A_K_DN].name = L"down"; - arrow[A_K_DN].key = T_kd; - arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY; - arrow[A_K_DN].type = XK_CMD; - - arrow[A_K_UP].name = L"up"; - arrow[A_K_UP].key = T_ku; - arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY; - arrow[A_K_UP].type = XK_CMD; - - arrow[A_K_LT].name = L"left"; - arrow[A_K_LT].key = T_kl; - arrow[A_K_LT].fun.cmd = ED_PREV_CHAR; - arrow[A_K_LT].type = XK_CMD; - - arrow[A_K_RT].name = L"right"; - arrow[A_K_RT].key = T_kr; - arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR; - arrow[A_K_RT].type = XK_CMD; - - arrow[A_K_HO].name = L"home"; - arrow[A_K_HO].key = T_kh; - arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG; - arrow[A_K_HO].type = XK_CMD; - - arrow[A_K_EN].name = L"end"; - arrow[A_K_EN].key = T_at7; - arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END; - arrow[A_K_EN].type = XK_CMD; - - arrow[A_K_DE].name = L"delete"; - arrow[A_K_DE].key = T_kD; - arrow[A_K_DE].fun.cmd = ED_DELETE_NEXT_CHAR; - arrow[A_K_DE].type = XK_CMD; -} - - -/* terminal_reset_arrow(): - * Reset arrow key bindings - */ -static void -terminal_reset_arrow(EditLine *el) -{ - funckey_t *arrow = el->el_terminal.t_fkey; - static const wchar_t strA[] = L"\033[A"; - static const wchar_t strB[] = L"\033[B"; - static const wchar_t strC[] = L"\033[C"; - static const wchar_t strD[] = L"\033[D"; - static const wchar_t strH[] = L"\033[H"; - static const wchar_t strF[] = L"\033[F"; - static const wchar_t stOA[] = L"\033OA"; - static const wchar_t stOB[] = L"\033OB"; - static const wchar_t stOC[] = L"\033OC"; - static const wchar_t stOD[] = L"\033OD"; - static const wchar_t stOH[] = L"\033OH"; - static const wchar_t stOF[] = L"\033OF"; - - keymacro_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - keymacro_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - keymacro_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - keymacro_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - keymacro_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - keymacro_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - keymacro_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - keymacro_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - keymacro_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - keymacro_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - keymacro_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - keymacro_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - - if (el->el_map.type != MAP_VI) - return; - keymacro_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - keymacro_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - keymacro_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - keymacro_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - keymacro_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - keymacro_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - keymacro_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - keymacro_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - keymacro_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - keymacro_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - keymacro_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - keymacro_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); -} - - -/* terminal_set_arrow(): - * Set an arrow key binding - */ -libedit_private int -terminal_set_arrow(EditLine *el, const wchar_t *name, keymacro_value_t *fun, - int type) -{ - funckey_t *arrow = el->el_terminal.t_fkey; - int i; - - for (i = 0; i < A_K_NKEYS; i++) - if (wcscmp(name, arrow[i].name) == 0) { - arrow[i].fun = *fun; - arrow[i].type = type; - return 0; - } - return -1; -} - - -/* terminal_clear_arrow(): - * Clear an arrow key binding - */ -libedit_private int -terminal_clear_arrow(EditLine *el, const wchar_t *name) -{ - funckey_t *arrow = el->el_terminal.t_fkey; - int i; - - for (i = 0; i < A_K_NKEYS; i++) - if (wcscmp(name, arrow[i].name) == 0) { - arrow[i].type = XK_NOD; - return 0; - } - return -1; -} - - -/* terminal_print_arrow(): - * Print the arrow key bindings - */ -libedit_private void -terminal_print_arrow(EditLine *el, const wchar_t *name) -{ - int i; - funckey_t *arrow = el->el_terminal.t_fkey; - - for (i = 0; i < A_K_NKEYS; i++) - if (*name == '\0' || wcscmp(name, arrow[i].name) == 0) - if (arrow[i].type != XK_NOD) - keymacro_kprint(el, arrow[i].name, - &arrow[i].fun, arrow[i].type); -} - - -/* terminal_bind_arrow(): - * Bind the arrow keys - */ -libedit_private void -terminal_bind_arrow(EditLine *el) -{ - el_action_t *map; - const el_action_t *dmap; - int i, j; - char *p; - funckey_t *arrow = el->el_terminal.t_fkey; - - /* Check if the components needed are initialized */ - if (el->el_terminal.t_buf == NULL || el->el_map.key == NULL) - return; - - map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key; - dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs; - - terminal_reset_arrow(el); - - for (i = 0; i < A_K_NKEYS; i++) { - wchar_t wt_str[VISUAL_WIDTH_MAX]; - wchar_t *px; - size_t n; - - p = el->el_terminal.t_str[arrow[i].key]; - if (!p || !*p) - continue; - for (n = 0; n < VISUAL_WIDTH_MAX && p[n]; ++n) - wt_str[n] = p[n]; - while (n < VISUAL_WIDTH_MAX) - wt_str[n++] = '\0'; - px = wt_str; - j = (unsigned char) *p; - /* - * Assign the arrow keys only if: - * - * 1. They are multi-character arrow keys and the user - * has not re-assigned the leading character, or - * has re-assigned the leading character to be - * ED_SEQUENCE_LEAD_IN - * 2. They are single arrow keys pointing to an - * unassigned key. - */ - if (arrow[i].type == XK_NOD) - keymacro_clear(el, map, px); - else { - if (p[1] && (dmap[j] == map[j] || - map[j] == ED_SEQUENCE_LEAD_IN)) { - keymacro_add(el, px, &arrow[i].fun, - arrow[i].type); - map[j] = ED_SEQUENCE_LEAD_IN; - } else if (map[j] == ED_UNASSIGNED) { - keymacro_clear(el, map, px); - if (arrow[i].type == XK_CMD) - map[j] = arrow[i].fun.cmd; - else - keymacro_add(el, px, &arrow[i].fun, - arrow[i].type); - } - } - } -} - -/* terminal_putc(): - * Add a character - */ -static int -terminal_putc(int c) -{ - if (terminal_outfile == NULL) - return -1; - return fputc(c, terminal_outfile); -} - -static void -terminal_tputs(EditLine *el, const char *cap, int affcnt) -{ -#ifdef _REENTRANT - pthread_mutex_lock(&terminal_mutex); -#endif - terminal_outfile = el->el_outfile; - (void)tputs(cap, affcnt, terminal_putc); -#ifdef _REENTRANT - pthread_mutex_unlock(&terminal_mutex); -#endif -} - -/* terminal__putc(): - * Add a character - */ -libedit_private int -terminal__putc(EditLine *el, wint_t c) -{ - char buf[MB_LEN_MAX +1]; - ssize_t i; - if (c == (wint_t)MB_FILL_CHAR) - return 0; - i = ct_encode_char(buf, (size_t)MB_LEN_MAX, c); - if (i <= 0) - return (int)i; - buf[i] = '\0'; - return fputs(buf, el->el_outfile); -} - -/* terminal__flush(): - * Flush output - */ -libedit_private void -terminal__flush(EditLine *el) -{ - - (void) fflush(el->el_outfile); -} - -/* terminal_writec(): - * Write the given character out, in a human readable form - */ -libedit_private void -terminal_writec(EditLine *el, wint_t c) -{ - wchar_t visbuf[VISUAL_WIDTH_MAX +1]; - ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c); - if (vcnt < 0) - vcnt = 0; - visbuf[vcnt] = '\0'; - terminal_overwrite(el, visbuf, (size_t)vcnt); - terminal__flush(el); -} - - -/* terminal_telltc(): - * Print the current termcap characteristics - */ -libedit_private int -/*ARGSUSED*/ -terminal_telltc(EditLine *el, int argc __attribute__((__unused__)), - const wchar_t **argv __attribute__((__unused__))) -{ - const struct termcapstr *t; - char **ts; - - (void) fprintf(el->el_outfile, "\n\tYour terminal has the\n"); - (void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n"); - (void) fprintf(el->el_outfile, "\tIt has %d columns and %d lines\n", - Val(T_co), Val(T_li)); - (void) fprintf(el->el_outfile, - "\tIt has %s meta key\n", EL_HAS_META ? "a" : "no"); - (void) fprintf(el->el_outfile, - "\tIt can%suse tabs\n", EL_CAN_TAB ? " " : "not "); - (void) fprintf(el->el_outfile, "\tIt %s automatic margins\n", - EL_HAS_AUTO_MARGINS ? "has" : "does not have"); - if (EL_HAS_AUTO_MARGINS) - (void) fprintf(el->el_outfile, "\tIt %s magic margins\n", - EL_HAS_MAGIC_MARGINS ? "has" : "does not have"); - - for (t = tstr, ts = el->el_terminal.t_str; t->name != NULL; t++, ts++) { - const char *ub; - if (*ts && **ts) { - ub = ct_encode_string(ct_visual_string( - ct_decode_string(*ts, &el->el_scratch), - &el->el_visual), &el->el_scratch); - } else { - ub = "(empty)"; - } - (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", - t->long_name, t->name, ub); - } - (void) fputc('\n', el->el_outfile); - return 0; -} - - -/* terminal_settc(): - * Change the current terminal characteristics - */ -libedit_private int -/*ARGSUSED*/ -terminal_settc(EditLine *el, int argc __attribute__((__unused__)), - const wchar_t **argv) -{ - const struct termcapstr *ts; - const struct termcapval *tv; - char what[8], how[8]; - - if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return -1; - - strncpy(what, ct_encode_string(argv[1], &el->el_scratch), sizeof(what)); - what[sizeof(what) - 1] = '\0'; - strncpy(how, ct_encode_string(argv[2], &el->el_scratch), sizeof(how)); - how[sizeof(how) - 1] = '\0'; - - /* - * Do the strings first - */ - for (ts = tstr; ts->name != NULL; ts++) - if (strcmp(ts->name, what) == 0) - break; - - if (ts->name != NULL) { - terminal_alloc(el, ts, how); - terminal_setflags(el); - return 0; - } - /* - * Do the numeric ones second - */ - for (tv = tval; tv->name != NULL; tv++) - if (strcmp(tv->name, what) == 0) - break; - - if (tv->name != NULL) - return -1; - - if (tv == &tval[T_pt] || tv == &tval[T_km] || - tv == &tval[T_am] || tv == &tval[T_xn]) { - if (strcmp(how, "yes") == 0) - el->el_terminal.t_val[tv - tval] = 1; - else if (strcmp(how, "no") == 0) - el->el_terminal.t_val[tv - tval] = 0; - else { - (void) fprintf(el->el_errfile, - "%ls: Bad value `%s'.\n", argv[0], how); - return -1; - } - terminal_setflags(el); - if (terminal_change_size(el, Val(T_li), Val(T_co)) == -1) - return -1; - return 0; - } else { - long i; - char *ep; - - i = strtol(how, &ep, 10); - if (*ep != '\0') { - (void) fprintf(el->el_errfile, - "%ls: Bad value `%s'.\n", argv[0], how); - return -1; - } - el->el_terminal.t_val[tv - tval] = (int) i; - el->el_terminal.t_size.v = Val(T_co); - el->el_terminal.t_size.h = Val(T_li); - if (tv == &tval[T_co] || tv == &tval[T_li]) - if (terminal_change_size(el, Val(T_li), Val(T_co)) - == -1) - return -1; - return 0; - } -} - - -/* terminal_gettc(): - * Get the current terminal characteristics - */ -libedit_private int -/*ARGSUSED*/ -terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) -{ - const struct termcapstr *ts; - const struct termcapval *tv; - char *what; - void *how; - - if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return -1; - - what = argv[1]; - how = argv[2]; - - /* - * Do the strings first - */ - for (ts = tstr; ts->name != NULL; ts++) - if (strcmp(ts->name, what) == 0) - break; - - if (ts->name != NULL) { - *(char **)how = el->el_terminal.t_str[ts - tstr]; - return 0; - } - /* - * Do the numeric ones second - */ - for (tv = tval; tv->name != NULL; tv++) - if (strcmp(tv->name, what) == 0) - break; - - if (tv->name == NULL) - return -1; - - if (tv == &tval[T_pt] || tv == &tval[T_km] || - tv == &tval[T_am] || tv == &tval[T_xn]) { - static char yes[] = "yes"; - static char no[] = "no"; - if (el->el_terminal.t_val[tv - tval]) - *(char **)how = yes; - else - *(char **)how = no; - return 0; - } else { - *(int *)how = el->el_terminal.t_val[tv - tval]; - return 0; - } -} - -/* terminal_echotc(): - * Print the termcap string out with variable substitution - */ -libedit_private int -/*ARGSUSED*/ -terminal_echotc(EditLine *el, int argc __attribute__((__unused__)), - const wchar_t **argv) -{ - char *cap, *scap; - wchar_t *ep; - int arg_need, arg_cols, arg_rows; - int verbose = 0, silent = 0; - char *area; - static const char fmts[] = "%s\n", fmtd[] = "%d\n"; - const struct termcapstr *t; - char buf[TC_BUFSIZE]; - long i; - - area = buf; - - if (argv == NULL || argv[1] == NULL) - return -1; - argv++; - - if (argv[0][0] == '-') { - switch (argv[0][1]) { - case 'v': - verbose = 1; - break; - case 's': - silent = 1; - break; - default: - /* stderror(ERR_NAME | ERR_TCUSAGE); */ - break; - } - argv++; - } - if (!*argv || *argv[0] == '\0') - return 0; - if (wcscmp(*argv, L"tabs") == 0) { - (void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no"); - return 0; - } else if (wcscmp(*argv, L"meta") == 0) { - (void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no"); - return 0; - } else if (wcscmp(*argv, L"xn") == 0) { - (void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ? - "yes" : "no"); - return 0; - } else if (wcscmp(*argv, L"am") == 0) { - (void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ? - "yes" : "no"); - return 0; - } else if (wcscmp(*argv, L"baud") == 0) { - (void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed); - return 0; - } else if (wcscmp(*argv, L"rows") == 0 || - wcscmp(*argv, L"lines") == 0) { - (void) fprintf(el->el_outfile, fmtd, Val(T_li)); - return 0; - } else if (wcscmp(*argv, L"cols") == 0) { - (void) fprintf(el->el_outfile, fmtd, Val(T_co)); - return 0; - } - /* - * Try to use our local definition first - */ - scap = NULL; - for (t = tstr; t->name != NULL; t++) - if (strcmp(t->name, - ct_encode_string(*argv, &el->el_scratch)) == 0) { - scap = el->el_terminal.t_str[t - tstr]; - break; - } - if (t->name == NULL) { - /* XXX: some systems' tgetstr needs non const */ - scap = tgetstr(ct_encode_string(*argv, &el->el_scratch), &area); - } - if (!scap || scap[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Termcap parameter `%ls' not found.\n", - *argv); - return -1; - } - /* - * Count home many values we need for this capability. - */ - for (cap = scap, arg_need = 0; *cap; cap++) - if (*cap == '%') - switch (*++cap) { - case 'd': - case '2': - case '3': - case '.': - case '+': - arg_need++; - break; - case '%': - case '>': - case 'i': - case 'r': - case 'n': - case 'B': - case 'D': - break; - default: - /* - * hpux has lot's of them... - */ - if (verbose) - (void) fprintf(el->el_errfile, - "echotc: Warning: unknown termcap %% `%c'.\n", - *cap); - /* This is bad, but I won't complain */ - break; - } - - switch (arg_need) { - case 0: - argv++; - if (*argv && *argv[0]) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%ls'.\n", - *argv); - return -1; - } - terminal_tputs(el, scap, 1); - break; - case 1: - argv++; - if (!*argv || *argv[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Missing argument.\n"); - return -1; - } - arg_cols = 0; - i = wcstol(*argv, &ep, 10); - if (*ep != '\0' || i < 0) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Bad value `%ls' for rows.\n", - *argv); - return -1; - } - arg_rows = (int) i; - argv++; - if (*argv && *argv[0]) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%ls" - "'.\n", *argv); - return -1; - } - terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), 1); - break; - default: - /* This is wrong, but I will ignore it... */ - if (verbose) - (void) fprintf(el->el_errfile, - "echotc: Warning: Too many required arguments (%d).\n", - arg_need); - /* FALLTHROUGH */ - case 2: - argv++; - if (!*argv || *argv[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Missing argument.\n"); - return -1; - } - i = wcstol(*argv, &ep, 10); - if (*ep != '\0' || i < 0) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Bad value `%ls' for cols.\n", - *argv); - return -1; - } - arg_cols = (int) i; - argv++; - if (!*argv || *argv[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Missing argument.\n"); - return -1; - } - i = wcstol(*argv, &ep, 10); - if (*ep != '\0' || i < 0) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Bad value `%ls' for rows.\n", - *argv); - return -1; - } - arg_rows = (int) i; - if (*ep != '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Bad value `%ls'.\n", *argv); - return -1; - } - argv++; - if (*argv && *argv[0]) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%ls" - "'.\n", *argv); - return -1; - } - terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows); - break; - } - return 0; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/terminal.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/terminal.h deleted file mode 100644 index e458369..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/terminal.h +++ /dev/null @@ -1,134 +0,0 @@ -/* $NetBSD: terminal.h,v 1.9 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)term.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.term.h: Termcap header - */ -#ifndef _h_el_terminal -#define _h_el_terminal - -typedef struct { /* Symbolic function key bindings */ - const wchar_t *name; /* name of the key */ - int key; /* Index in termcap table */ - keymacro_value_t fun; /* Function bound to it */ - int type; /* Type of function */ -} funckey_t; - -typedef struct { - const char *t_name; /* the terminal name */ - coord_t t_size; /* # lines and cols */ - int t_flags; -#define TERM_CAN_INSERT 0x001 /* Has insert cap */ -#define TERM_CAN_DELETE 0x002 /* Has delete cap */ -#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */ -#define TERM_CAN_TAB 0x008 /* Can use tabs */ -#define TERM_CAN_ME 0x010 /* Can turn all attrs. */ -#define TERM_CAN_UP 0x020 /* Can move up */ -#define TERM_HAS_META 0x040 /* Has a meta key */ -#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ -#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ - char *t_buf; /* Termcap buffer */ - size_t t_loc; /* location used */ - char **t_str; /* termcap strings */ - int *t_val; /* termcap values */ - char *t_cap; /* Termcap buffer */ - funckey_t *t_fkey; /* Array of keys */ -} el_terminal_t; - -/* - * fKey indexes - */ -#define A_K_DN 0 -#define A_K_UP 1 -#define A_K_LT 2 -#define A_K_RT 3 -#define A_K_HO 4 -#define A_K_EN 5 -#define A_K_DE 6 -#define A_K_NKEYS 7 - -#ifdef __sun -extern int tgetent(char *, const char *); -extern int tgetflag(char *); -extern int tgetnum(char *); -extern int tputs(const char *, int, int (*)(int)); -extern char* tgoto(const char*, int, int); -extern char* tgetstr(char*, char**); -#endif - -libedit_private void terminal_move_to_line(EditLine *, int); -libedit_private void terminal_move_to_char(EditLine *, int); -libedit_private void terminal_clear_EOL(EditLine *, int); -libedit_private void terminal_overwrite(EditLine *, const wchar_t *, size_t); -libedit_private void terminal_insertwrite(EditLine *, wchar_t *, int); -libedit_private void terminal_deletechars(EditLine *, int); -libedit_private void terminal_clear_screen(EditLine *); -libedit_private void terminal_beep(EditLine *); -libedit_private int terminal_change_size(EditLine *, int, int); -libedit_private int terminal_get_size(EditLine *, int *, int *); -libedit_private int terminal_init(EditLine *); -libedit_private void terminal_bind_arrow(EditLine *); -libedit_private void terminal_print_arrow(EditLine *, const wchar_t *); -libedit_private int terminal_clear_arrow(EditLine *, const wchar_t *); -libedit_private int terminal_set_arrow(EditLine *, const wchar_t *, - keymacro_value_t *, int); -libedit_private void terminal_end(EditLine *); -libedit_private void terminal_get(EditLine *, const char **); -libedit_private int terminal_set(EditLine *, const char *); -libedit_private int terminal_settc(EditLine *, int, const wchar_t **); -libedit_private int terminal_gettc(EditLine *, int, char **); -libedit_private int terminal_telltc(EditLine *, int, const wchar_t **); -libedit_private int terminal_echotc(EditLine *, int, const wchar_t **); -libedit_private void terminal_writec(EditLine *, wint_t); -libedit_private int terminal__putc(EditLine *, wint_t); -libedit_private void terminal__flush(EditLine *); - -/* - * Easy access macros - */ -#define EL_FLAGS (el)->el_terminal.t_flags - -#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) -#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) -#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) -#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) -#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) -#define EL_CAN_UP (EL_FLAGS & TERM_CAN_UP) -#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) -#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) -#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) - -#endif /* _h_el_terminal */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tokenizer.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tokenizer.c deleted file mode 100644 index 5efb432..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tokenizer.c +++ /dev/null @@ -1,469 +0,0 @@ -/* $NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#ifndef NARROWCHAR -#include "config.h" -#endif - -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* We build this file twice, once as NARROW, once as WIDE. */ -/* - * tokenize.c: Bourne shell like tokenizer - */ -#include -#include - -#include "histedit.h" - -typedef enum { - Q_none, Q_single, Q_double, Q_one, Q_doubleone -} quote_t; - -#define TOK_KEEP 1 -#define TOK_EAT 2 - -#define WINCR 20 -#define AINCR 10 - -#define IFS STR("\t \n") - -#define tok_malloc(a) malloc(a) -#define tok_free(a) free(a) -#define tok_realloc(a, b) realloc(a, b) - -#ifdef NARROWCHAR -#define Char char -#define FUN(prefix, rest) prefix ## _ ## rest -#define TYPE(type) type -#define STR(x) x -#define Strchr(s, c) strchr(s, c) -#define tok_strdup(s) strdup(s) -#else -#define Char wchar_t -#define FUN(prefix, rest) prefix ## _w ## rest -#define TYPE(type) type ## W -#define STR(x) L ## x -#define Strchr(s, c) wcschr(s, c) -#define tok_strdup(s) wcsdup(s) -#endif - -struct TYPE(tokenizer) { - Char *ifs; /* In field separator */ - size_t argc, amax; /* Current and maximum number of args */ - Char **argv; /* Argument list */ - Char *wptr, *wmax; /* Space and limit on the word buffer */ - Char *wstart; /* Beginning of next word */ - Char *wspace; /* Space of word buffer */ - quote_t quote; /* Quoting state */ - int flags; /* flags; */ -}; - - -static void FUN(tok,finish)(TYPE(Tokenizer) *); - - -/* FUN(tok,finish)(): - * Finish a word in the tokenizer. - */ -static void -FUN(tok,finish)(TYPE(Tokenizer) *tok) -{ - - *tok->wptr = '\0'; - if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) { - tok->argv[tok->argc++] = tok->wstart; - tok->argv[tok->argc] = NULL; - tok->wstart = ++tok->wptr; - } - tok->flags &= ~TOK_KEEP; -} - - -/* FUN(tok,init)(): - * Initialize the tokenizer - */ -TYPE(Tokenizer) * -FUN(tok,init)(const Char *ifs) -{ - TYPE(Tokenizer) *tok = tok_malloc(sizeof(*tok)); - - if (tok == NULL) - return NULL; - tok->ifs = tok_strdup(ifs ? ifs : IFS); - if (tok->ifs == NULL) { - tok_free(tok); - return NULL; - } - tok->argc = 0; - tok->amax = AINCR; - tok->argv = tok_malloc(sizeof(*tok->argv) * tok->amax); - if (tok->argv == NULL) { - tok_free(tok->ifs); - tok_free(tok); - return NULL; - } - tok->argv[0] = NULL; - tok->wspace = tok_malloc(WINCR * sizeof(*tok->wspace)); - if (tok->wspace == NULL) { - tok_free(tok->argv); - tok_free(tok->ifs); - tok_free(tok); - return NULL; - } - tok->wmax = tok->wspace + WINCR; - tok->wstart = tok->wspace; - tok->wptr = tok->wspace; - tok->flags = 0; - tok->quote = Q_none; - - return tok; -} - - -/* FUN(tok,reset)(): - * Reset the tokenizer - */ -void -FUN(tok,reset)(TYPE(Tokenizer) *tok) -{ - - tok->argc = 0; - tok->wstart = tok->wspace; - tok->wptr = tok->wspace; - tok->flags = 0; - tok->quote = Q_none; -} - - -/* FUN(tok,end)(): - * Clean up - */ -void -FUN(tok,end)(TYPE(Tokenizer) *tok) -{ - - tok_free(tok->ifs); - tok_free(tok->wspace); - tok_free(tok->argv); - tok_free(tok); -} - - - -/* FUN(tok,line)(): - * Bourne shell (sh(1)) like tokenizing - * Arguments: - * tok current tokenizer state (setup with FUN(tok,init)()) - * line line to parse - * Returns: - * -1 Internal error - * 3 Quoted return - * 2 Unmatched double quote - * 1 Unmatched single quote - * 0 Ok - * Modifies (if return value is 0): - * argc number of arguments - * argv argument array - * cursorc if !NULL, argv element containing cursor - * cursorv if !NULL, offset in argv[cursorc] of cursor - */ -int -FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line, - int *argc, const Char ***argv, int *cursorc, int *cursoro) -{ - const Char *ptr; - int cc, co; - - cc = co = -1; - ptr = line->buffer; - for (ptr = line->buffer; ;ptr++) { - if (ptr >= line->lastchar) - ptr = STR(""); - if (ptr == line->cursor) { - cc = (int)tok->argc; - co = (int)(tok->wptr - tok->wstart); - } - switch (*ptr) { - case '\'': - tok->flags |= TOK_KEEP; - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - tok->quote = Q_single; /* Enter single quote - * mode */ - break; - - case Q_single: /* Exit single quote mode */ - tok->quote = Q_none; - break; - - case Q_one: /* Quote this ' */ - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - case Q_double: /* Stay in double quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this ' */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return -1; - } - break; - - case '"': - tok->flags &= ~TOK_EAT; - tok->flags |= TOK_KEEP; - switch (tok->quote) { - case Q_none: /* Enter double quote mode */ - tok->quote = Q_double; - break; - - case Q_double: /* Exit double quote mode */ - tok->quote = Q_none; - break; - - case Q_one: /* Quote this " */ - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - case Q_single: /* Stay in single quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this " */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return -1; - } - break; - - case '\\': - tok->flags |= TOK_KEEP; - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: /* Quote next character */ - tok->quote = Q_one; - break; - - case Q_double: /* Quote next character */ - tok->quote = Q_doubleone; - break; - - case Q_one: /* Quote this, restore state */ - *tok->wptr++ = *ptr; - tok->quote = Q_none; - break; - - case Q_single: /* Stay in single quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this \ */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return -1; - } - break; - - case '\n': - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - goto tok_line_outok; - - case Q_single: - case Q_double: - *tok->wptr++ = *ptr; /* Add the return */ - break; - - case Q_doubleone: /* Back to double, eat the '\n' */ - tok->flags |= TOK_EAT; - tok->quote = Q_double; - break; - - case Q_one: /* No quote, more eat the '\n' */ - tok->flags |= TOK_EAT; - tok->quote = Q_none; - break; - - default: - return 0; - } - break; - - case '\0': - switch (tok->quote) { - case Q_none: - /* Finish word and return */ - if (tok->flags & TOK_EAT) { - tok->flags &= ~TOK_EAT; - return 3; - } - goto tok_line_outok; - - case Q_single: - return 1; - - case Q_double: - return 2; - - case Q_doubleone: - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - case Q_one: - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - default: - return -1; - } - break; - - default: - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - if (Strchr(tok->ifs, *ptr) != NULL) - FUN(tok,finish)(tok); - else - *tok->wptr++ = *ptr; - break; - - case Q_single: - case Q_double: - *tok->wptr++ = *ptr; - break; - - - case Q_doubleone: - *tok->wptr++ = '\\'; - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - case Q_one: - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - default: - return -1; - - } - break; - } - - if (tok->wptr >= tok->wmax - 4) { - size_t size = (size_t)(tok->wmax - tok->wspace + WINCR); - Char *s = tok_realloc(tok->wspace, - size * sizeof(*s)); - if (s == NULL) - return -1; - - if (s != tok->wspace) { - size_t i; - for (i = 0; i < tok->argc; i++) { - tok->argv[i] = - (tok->argv[i] - tok->wspace) + s; - } - tok->wptr = (tok->wptr - tok->wspace) + s; - tok->wstart = (tok->wstart - tok->wspace) + s; - tok->wspace = s; - } - tok->wmax = s + size; - } - if (tok->argc >= tok->amax - 4) { - Char **p; - tok->amax += AINCR; - p = tok_realloc(tok->argv, tok->amax * sizeof(*p)); - if (p == NULL) { - tok->amax -= AINCR; - return -1; - } - tok->argv = p; - } - } - tok_line_outok: - if (cc == -1 && co == -1) { - cc = (int)tok->argc; - co = (int)(tok->wptr - tok->wstart); - } - if (cursorc != NULL) - *cursorc = cc; - if (cursoro != NULL) - *cursoro = co; - FUN(tok,finish)(tok); - *argv = (const Char **)tok->argv; - *argc = (int)tok->argc; - return 0; -} - -/* FUN(tok,str)(): - * Simpler version of tok_line, taking a NUL terminated line - * and splitting into words, ignoring cursor state. - */ -int -FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc, - const Char ***argv) -{ - TYPE(LineInfo) li; - - memset(&li, 0, sizeof(li)); - li.buffer = line; - li.cursor = li.lastchar = Strchr(line, '\0'); - return FUN(tok,line)(tok, &li, argc, argv, NULL, NULL); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tokenizern.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tokenizern.c deleted file mode 100644 index 5846b60..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tokenizern.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "config.h" -#define NARROWCHAR -#include "tokenizer.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tty.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tty.c deleted file mode 100644 index f524da4..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tty.c +++ /dev/null @@ -1,1342 +0,0 @@ -/* $NetBSD: tty.c,v 1.65 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: tty.c,v 1.65 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * tty.c: tty interface stuff - */ -#include -#include -#include /* for abort */ -#include -#include /* for ffs */ -#include /* for isatty */ - -#include "el.h" -#include "fcns.h" -#include "parse.h" - -typedef struct ttymodes_t { - const char *m_name; - unsigned int m_value; - int m_type; -} ttymodes_t; - -typedef struct ttymap_t { - wint_t nch, och; /* Internal and termio rep of chars */ - el_action_t bind[3]; /* emacs, vi, and vi-cmd */ -} ttymap_t; - - -static const ttyperm_t ttyperm = { - { - {"iflag:", ICRNL, (INLCR | IGNCR)}, - {"oflag:", (OPOST | ONLCR), ONLRET}, - {"cflag:", 0, 0}, - {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN), - (NOFLSH | ECHONL | EXTPROC | FLUSHO)}, - {"chars:", 0, 0}, - }, - { - {"iflag:", (INLCR | ICRNL), IGNCR}, - {"oflag:", (OPOST | ONLCR), ONLRET}, - {"cflag:", 0, 0}, - {"lflag:", ISIG, - (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)}, - {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) | - C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) | - C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0} - }, - { - {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL}, - {"oflag:", 0, 0}, - {"cflag:", 0, 0}, - {"lflag:", 0, ISIG | IEXTEN}, - {"chars:", 0, 0}, - } -}; - -static const ttychar_t ttychar = { - { - CINTR, CQUIT, CERASE, CKILL, - CEOF, CEOL, CEOL2, CSWTCH, - CDSWTCH, CERASE2, CSTART, CSTOP, - CWERASE, CSUSP, CDSUSP, CREPRINT, - CDISCARD, CLNEXT, CSTATUS, CPAGE, - CPGOFF, CKILL2, CBRK, CMIN, - CTIME - }, - { - CINTR, CQUIT, CERASE, CKILL, - _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, - _POSIX_VDISABLE, CERASE2, CSTART, CSTOP, - _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE, - CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, - _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1, - 0 - }, - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0 - } -}; - -static const ttymap_t tty_map[] = { -#ifdef VERASE - {C_ERASE, VERASE, - {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, -#endif /* VERASE */ -#ifdef VERASE2 - {C_ERASE2, VERASE2, - {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, -#endif /* VERASE2 */ -#ifdef VKILL - {C_KILL, VKILL, - {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, -#endif /* VKILL */ -#ifdef VKILL2 - {C_KILL2, VKILL2, - {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, -#endif /* VKILL2 */ -#ifdef VEOF - {C_EOF, VEOF, - {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}}, -#endif /* VEOF */ -#ifdef VWERASE - {C_WERASE, VWERASE, - {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}}, -#endif /* VWERASE */ -#ifdef VREPRINT - {C_REPRINT, VREPRINT, - {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}}, -#endif /* VREPRINT */ -#ifdef VLNEXT - {C_LNEXT, VLNEXT, - {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}}, -#endif /* VLNEXT */ - {(wint_t)-1, (wint_t)-1, - {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}} -}; - -static const ttymodes_t ttymodes[] = { -#ifdef IGNBRK - {"ignbrk", IGNBRK, MD_INP}, -#endif /* IGNBRK */ -#ifdef BRKINT - {"brkint", BRKINT, MD_INP}, -#endif /* BRKINT */ -#ifdef IGNPAR - {"ignpar", IGNPAR, MD_INP}, -#endif /* IGNPAR */ -#ifdef PARMRK - {"parmrk", PARMRK, MD_INP}, -#endif /* PARMRK */ -#ifdef INPCK - {"inpck", INPCK, MD_INP}, -#endif /* INPCK */ -#ifdef ISTRIP - {"istrip", ISTRIP, MD_INP}, -#endif /* ISTRIP */ -#ifdef INLCR - {"inlcr", INLCR, MD_INP}, -#endif /* INLCR */ -#ifdef IGNCR - {"igncr", IGNCR, MD_INP}, -#endif /* IGNCR */ -#ifdef ICRNL - {"icrnl", ICRNL, MD_INP}, -#endif /* ICRNL */ -#ifdef IUCLC - {"iuclc", IUCLC, MD_INP}, -#endif /* IUCLC */ -#ifdef IXON - {"ixon", IXON, MD_INP}, -#endif /* IXON */ -#ifdef IXANY - {"ixany", IXANY, MD_INP}, -#endif /* IXANY */ -#ifdef IXOFF - {"ixoff", IXOFF, MD_INP}, -#endif /* IXOFF */ -#ifdef IMAXBEL - {"imaxbel", IMAXBEL, MD_INP}, -#endif /* IMAXBEL */ - -#ifdef OPOST - {"opost", OPOST, MD_OUT}, -#endif /* OPOST */ -#ifdef OLCUC - {"olcuc", OLCUC, MD_OUT}, -#endif /* OLCUC */ -#ifdef ONLCR - {"onlcr", ONLCR, MD_OUT}, -#endif /* ONLCR */ -#ifdef OCRNL - {"ocrnl", OCRNL, MD_OUT}, -#endif /* OCRNL */ -#ifdef ONOCR - {"onocr", ONOCR, MD_OUT}, -#endif /* ONOCR */ -#ifdef ONOEOT - {"onoeot", ONOEOT, MD_OUT}, -#endif /* ONOEOT */ -#ifdef ONLRET - {"onlret", ONLRET, MD_OUT}, -#endif /* ONLRET */ -#ifdef OFILL - {"ofill", OFILL, MD_OUT}, -#endif /* OFILL */ -#ifdef OFDEL - {"ofdel", OFDEL, MD_OUT}, -#endif /* OFDEL */ -#ifdef NLDLY - {"nldly", NLDLY, MD_OUT}, -#endif /* NLDLY */ -#ifdef CRDLY - {"crdly", CRDLY, MD_OUT}, -#endif /* CRDLY */ -#ifdef TABDLY - {"tabdly", TABDLY, MD_OUT}, -#endif /* TABDLY */ -#ifdef XTABS - {"xtabs", XTABS, MD_OUT}, -#endif /* XTABS */ -#ifdef BSDLY - {"bsdly", BSDLY, MD_OUT}, -#endif /* BSDLY */ -#ifdef VTDLY - {"vtdly", VTDLY, MD_OUT}, -#endif /* VTDLY */ -#ifdef FFDLY - {"ffdly", FFDLY, MD_OUT}, -#endif /* FFDLY */ -#ifdef PAGEOUT - {"pageout", PAGEOUT, MD_OUT}, -#endif /* PAGEOUT */ -#ifdef WRAP - {"wrap", WRAP, MD_OUT}, -#endif /* WRAP */ - -#ifdef CIGNORE - {"cignore", CIGNORE, MD_CTL}, -#endif /* CBAUD */ -#ifdef CBAUD - {"cbaud", CBAUD, MD_CTL}, -#endif /* CBAUD */ -#ifdef CSTOPB - {"cstopb", CSTOPB, MD_CTL}, -#endif /* CSTOPB */ -#ifdef CREAD - {"cread", CREAD, MD_CTL}, -#endif /* CREAD */ -#ifdef PARENB - {"parenb", PARENB, MD_CTL}, -#endif /* PARENB */ -#ifdef PARODD - {"parodd", PARODD, MD_CTL}, -#endif /* PARODD */ -#ifdef HUPCL - {"hupcl", HUPCL, MD_CTL}, -#endif /* HUPCL */ -#ifdef CLOCAL - {"clocal", CLOCAL, MD_CTL}, -#endif /* CLOCAL */ -#ifdef LOBLK - {"loblk", LOBLK, MD_CTL}, -#endif /* LOBLK */ -#ifdef CIBAUD - {"cibaud", CIBAUD, MD_CTL}, -#endif /* CIBAUD */ -#ifdef CRTSCTS -#ifdef CCTS_OFLOW - {"ccts_oflow", CCTS_OFLOW, MD_CTL}, -#else - {"crtscts", CRTSCTS, MD_CTL}, -#endif /* CCTS_OFLOW */ -#endif /* CRTSCTS */ -#ifdef CRTS_IFLOW - {"crts_iflow", CRTS_IFLOW, MD_CTL}, -#endif /* CRTS_IFLOW */ -#ifdef CDTRCTS - {"cdtrcts", CDTRCTS, MD_CTL}, -#endif /* CDTRCTS */ -#ifdef MDMBUF - {"mdmbuf", MDMBUF, MD_CTL}, -#endif /* MDMBUF */ -#ifdef RCV1EN - {"rcv1en", RCV1EN, MD_CTL}, -#endif /* RCV1EN */ -#ifdef XMT1EN - {"xmt1en", XMT1EN, MD_CTL}, -#endif /* XMT1EN */ - -#ifdef ISIG - {"isig", ISIG, MD_LIN}, -#endif /* ISIG */ -#ifdef ICANON - {"icanon", ICANON, MD_LIN}, -#endif /* ICANON */ -#ifdef XCASE - {"xcase", XCASE, MD_LIN}, -#endif /* XCASE */ -#ifdef ECHO - {"echo", ECHO, MD_LIN}, -#endif /* ECHO */ -#ifdef ECHOE - {"echoe", ECHOE, MD_LIN}, -#endif /* ECHOE */ -#ifdef ECHOK - {"echok", ECHOK, MD_LIN}, -#endif /* ECHOK */ -#ifdef ECHONL - {"echonl", ECHONL, MD_LIN}, -#endif /* ECHONL */ -#ifdef NOFLSH - {"noflsh", NOFLSH, MD_LIN}, -#endif /* NOFLSH */ -#ifdef TOSTOP - {"tostop", TOSTOP, MD_LIN}, -#endif /* TOSTOP */ -#ifdef ECHOCTL - {"echoctl", ECHOCTL, MD_LIN}, -#endif /* ECHOCTL */ -#ifdef ECHOPRT - {"echoprt", ECHOPRT, MD_LIN}, -#endif /* ECHOPRT */ -#ifdef ECHOKE - {"echoke", ECHOKE, MD_LIN}, -#endif /* ECHOKE */ -#ifdef DEFECHO - {"defecho", DEFECHO, MD_LIN}, -#endif /* DEFECHO */ -#ifdef FLUSHO - {"flusho", FLUSHO, MD_LIN}, -#endif /* FLUSHO */ -#ifdef PENDIN - {"pendin", PENDIN, MD_LIN}, -#endif /* PENDIN */ -#ifdef IEXTEN - {"iexten", IEXTEN, MD_LIN}, -#endif /* IEXTEN */ -#ifdef NOKERNINFO - {"nokerninfo", NOKERNINFO, MD_LIN}, -#endif /* NOKERNINFO */ -#ifdef ALTWERASE - {"altwerase", ALTWERASE, MD_LIN}, -#endif /* ALTWERASE */ -#ifdef EXTPROC - {"extproc", EXTPROC, MD_LIN}, -#endif /* EXTPROC */ - -#if defined(VINTR) - {"intr", C_SH(C_INTR), MD_CHAR}, -#endif /* VINTR */ -#if defined(VQUIT) - {"quit", C_SH(C_QUIT), MD_CHAR}, -#endif /* VQUIT */ -#if defined(VERASE) - {"erase", C_SH(C_ERASE), MD_CHAR}, -#endif /* VERASE */ -#if defined(VKILL) - {"kill", C_SH(C_KILL), MD_CHAR}, -#endif /* VKILL */ -#if defined(VEOF) - {"eof", C_SH(C_EOF), MD_CHAR}, -#endif /* VEOF */ -#if defined(VEOL) - {"eol", C_SH(C_EOL), MD_CHAR}, -#endif /* VEOL */ -#if defined(VEOL2) - {"eol2", C_SH(C_EOL2), MD_CHAR}, -#endif /* VEOL2 */ -#if defined(VSWTCH) - {"swtch", C_SH(C_SWTCH), MD_CHAR}, -#endif /* VSWTCH */ -#if defined(VDSWTCH) - {"dswtch", C_SH(C_DSWTCH), MD_CHAR}, -#endif /* VDSWTCH */ -#if defined(VERASE2) - {"erase2", C_SH(C_ERASE2), MD_CHAR}, -#endif /* VERASE2 */ -#if defined(VSTART) - {"start", C_SH(C_START), MD_CHAR}, -#endif /* VSTART */ -#if defined(VSTOP) - {"stop", C_SH(C_STOP), MD_CHAR}, -#endif /* VSTOP */ -#if defined(VWERASE) - {"werase", C_SH(C_WERASE), MD_CHAR}, -#endif /* VWERASE */ -#if defined(VSUSP) - {"susp", C_SH(C_SUSP), MD_CHAR}, -#endif /* VSUSP */ -#if defined(VDSUSP) - {"dsusp", C_SH(C_DSUSP), MD_CHAR}, -#endif /* VDSUSP */ -#if defined(VREPRINT) - {"reprint", C_SH(C_REPRINT), MD_CHAR}, -#endif /* VREPRINT */ -#if defined(VDISCARD) - {"discard", C_SH(C_DISCARD), MD_CHAR}, -#endif /* VDISCARD */ -#if defined(VLNEXT) - {"lnext", C_SH(C_LNEXT), MD_CHAR}, -#endif /* VLNEXT */ -#if defined(VSTATUS) - {"status", C_SH(C_STATUS), MD_CHAR}, -#endif /* VSTATUS */ -#if defined(VPAGE) - {"page", C_SH(C_PAGE), MD_CHAR}, -#endif /* VPAGE */ -#if defined(VPGOFF) - {"pgoff", C_SH(C_PGOFF), MD_CHAR}, -#endif /* VPGOFF */ -#if defined(VKILL2) - {"kill2", C_SH(C_KILL2), MD_CHAR}, -#endif /* VKILL2 */ -#if defined(VBRK) - {"brk", C_SH(C_BRK), MD_CHAR}, -#endif /* VBRK */ -#if defined(VMIN) - {"min", C_SH(C_MIN), MD_CHAR}, -#endif /* VMIN */ -#if defined(VTIME) - {"time", C_SH(C_TIME), MD_CHAR}, -#endif /* VTIME */ - {NULL, 0, -1}, -}; - - - -#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) -#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) -#define tty__cooked_mode(td) ((td)->c_lflag & ICANON) - -static int tty_getty(EditLine *, struct termios *); -static int tty_setty(EditLine *, int, const struct termios *); -static int tty__getcharindex(int); -static void tty__getchar(struct termios *, unsigned char *); -static void tty__setchar(struct termios *, unsigned char *); -static speed_t tty__getspeed(struct termios *); -static int tty_setup(EditLine *); -static void tty_setup_flags(EditLine *, struct termios *, int); - -#define t_qu t_ts - -/* tty_getty(): - * Wrapper for tcgetattr to handle EINTR - */ -static int -tty_getty(EditLine *el, struct termios *t) -{ - int rv; - while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR) - continue; - return rv; -} - -/* tty_setty(): - * Wrapper for tcsetattr to handle EINTR - */ -static int -tty_setty(EditLine *el, int action, const struct termios *t) -{ - int rv; - while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR) - continue; - return rv; -} - -/* tty_setup(): - * Get the tty parameters and initialize the editing state - */ -static int -tty_setup(EditLine *el) -{ - int rst = 1; - - if (el->el_flags & EDIT_DISABLED) - return 0; - - if (el->el_tty.t_initialized) - return -1; - - if (!isatty(el->el_outfd)) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: isatty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - if (tty_getty(el, &el->el_tty.t_or) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or; - - el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); - el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); - el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); - - tty_setup_flags(el, &el->el_tty.t_ex, EX_IO); - - /* - * Reset the tty chars to reasonable defaults - * If they are disabled, then enable them. - */ - if (rst) { - if (tty__cooked_mode(&el->el_tty.t_ts)) { - tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); - /* - * Don't affect CMIN and CTIME for the editor mode - */ - for (rst = 0; rst < C_NCC - 2; rst++) - if (el->el_tty.t_c[TS_IO][rst] != - el->el_tty.t_vdisable - && el->el_tty.t_c[ED_IO][rst] != - el->el_tty.t_vdisable) - el->el_tty.t_c[ED_IO][rst] = - el->el_tty.t_c[TS_IO][rst]; - for (rst = 0; rst < C_NCC; rst++) - if (el->el_tty.t_c[TS_IO][rst] != - el->el_tty.t_vdisable) - el->el_tty.t_c[EX_IO][rst] = - el->el_tty.t_c[TS_IO][rst]; - } - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", - __func__, strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - } - - tty_setup_flags(el, &el->el_tty.t_ed, ED_IO); - - tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); - tty_bind_char(el, 1); - el->el_tty.t_initialized = 1; - return 0; -} - -libedit_private int -tty_init(EditLine *el) -{ - - el->el_tty.t_mode = EX_IO; - el->el_tty.t_vdisable = _POSIX_VDISABLE; - el->el_tty.t_initialized = 0; - (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); - (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); - return tty_setup(el); -} - - -/* tty_end(): - * Restore the tty to its original settings - */ -libedit_private void -/*ARGSUSED*/ -tty_end(EditLine *el) -{ - if (el->el_flags & EDIT_DISABLED) - return; - - if (!el->el_tty.t_initialized) - return; - - if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, - "%s: tty_setty: %s\n", __func__, strerror(errno)); -#endif /* DEBUG_TTY */ - } -} - - -/* tty__getspeed(): - * Get the tty speed - */ -static speed_t -tty__getspeed(struct termios *td) -{ - speed_t spd; - - if ((spd = cfgetispeed(td)) == 0) - spd = cfgetospeed(td); - return spd; -} - -/* tty__getspeed(): - * Return the index of the asked char in the c_cc array - */ -static int -tty__getcharindex(int i) -{ - switch (i) { -#ifdef VINTR - case C_INTR: - return VINTR; -#endif /* VINTR */ -#ifdef VQUIT - case C_QUIT: - return VQUIT; -#endif /* VQUIT */ -#ifdef VERASE - case C_ERASE: - return VERASE; -#endif /* VERASE */ -#ifdef VKILL - case C_KILL: - return VKILL; -#endif /* VKILL */ -#ifdef VEOF - case C_EOF: - return VEOF; -#endif /* VEOF */ -#ifdef VEOL - case C_EOL: - return VEOL; -#endif /* VEOL */ -#ifdef VEOL2 - case C_EOL2: - return VEOL2; -#endif /* VEOL2 */ -#ifdef VSWTCH - case C_SWTCH: - return VSWTCH; -#endif /* VSWTCH */ -#ifdef VDSWTCH - case C_DSWTCH: - return VDSWTCH; -#endif /* VDSWTCH */ -#ifdef VERASE2 - case C_ERASE2: - return VERASE2; -#endif /* VERASE2 */ -#ifdef VSTART - case C_START: - return VSTART; -#endif /* VSTART */ -#ifdef VSTOP - case C_STOP: - return VSTOP; -#endif /* VSTOP */ -#ifdef VWERASE - case C_WERASE: - return VWERASE; -#endif /* VWERASE */ -#ifdef VSUSP - case C_SUSP: - return VSUSP; -#endif /* VSUSP */ -#ifdef VDSUSP - case C_DSUSP: - return VDSUSP; -#endif /* VDSUSP */ -#ifdef VREPRINT - case C_REPRINT: - return VREPRINT; -#endif /* VREPRINT */ -#ifdef VDISCARD - case C_DISCARD: - return VDISCARD; -#endif /* VDISCARD */ -#ifdef VLNEXT - case C_LNEXT: - return VLNEXT; -#endif /* VLNEXT */ -#ifdef VSTATUS - case C_STATUS: - return VSTATUS; -#endif /* VSTATUS */ -#ifdef VPAGE - case C_PAGE: - return VPAGE; -#endif /* VPAGE */ -#ifdef VPGOFF - case C_PGOFF: - return VPGOFF; -#endif /* VPGOFF */ -#ifdef VKILL2 - case C_KILL2: - return VKILL2; -#endif /* KILL2 */ -#ifdef VMIN - case C_MIN: - return VMIN; -#endif /* VMIN */ -#ifdef VTIME - case C_TIME: - return VTIME; -#endif /* VTIME */ - default: - return -1; - } -} - -/* tty__getchar(): - * Get the tty characters - */ -static void -tty__getchar(struct termios *td, unsigned char *s) -{ - -#ifdef VINTR - s[C_INTR] = td->c_cc[VINTR]; -#endif /* VINTR */ -#ifdef VQUIT - s[C_QUIT] = td->c_cc[VQUIT]; -#endif /* VQUIT */ -#ifdef VERASE - s[C_ERASE] = td->c_cc[VERASE]; -#endif /* VERASE */ -#ifdef VKILL - s[C_KILL] = td->c_cc[VKILL]; -#endif /* VKILL */ -#ifdef VEOF - s[C_EOF] = td->c_cc[VEOF]; -#endif /* VEOF */ -#ifdef VEOL - s[C_EOL] = td->c_cc[VEOL]; -#endif /* VEOL */ -#ifdef VEOL2 - s[C_EOL2] = td->c_cc[VEOL2]; -#endif /* VEOL2 */ -#ifdef VSWTCH - s[C_SWTCH] = td->c_cc[VSWTCH]; -#endif /* VSWTCH */ -#ifdef VDSWTCH - s[C_DSWTCH] = td->c_cc[VDSWTCH]; -#endif /* VDSWTCH */ -#ifdef VERASE2 - s[C_ERASE2] = td->c_cc[VERASE2]; -#endif /* VERASE2 */ -#ifdef VSTART - s[C_START] = td->c_cc[VSTART]; -#endif /* VSTART */ -#ifdef VSTOP - s[C_STOP] = td->c_cc[VSTOP]; -#endif /* VSTOP */ -#ifdef VWERASE - s[C_WERASE] = td->c_cc[VWERASE]; -#endif /* VWERASE */ -#ifdef VSUSP - s[C_SUSP] = td->c_cc[VSUSP]; -#endif /* VSUSP */ -#ifdef VDSUSP - s[C_DSUSP] = td->c_cc[VDSUSP]; -#endif /* VDSUSP */ -#ifdef VREPRINT - s[C_REPRINT] = td->c_cc[VREPRINT]; -#endif /* VREPRINT */ -#ifdef VDISCARD - s[C_DISCARD] = td->c_cc[VDISCARD]; -#endif /* VDISCARD */ -#ifdef VLNEXT - s[C_LNEXT] = td->c_cc[VLNEXT]; -#endif /* VLNEXT */ -#ifdef VSTATUS - s[C_STATUS] = td->c_cc[VSTATUS]; -#endif /* VSTATUS */ -#ifdef VPAGE - s[C_PAGE] = td->c_cc[VPAGE]; -#endif /* VPAGE */ -#ifdef VPGOFF - s[C_PGOFF] = td->c_cc[VPGOFF]; -#endif /* VPGOFF */ -#ifdef VKILL2 - s[C_KILL2] = td->c_cc[VKILL2]; -#endif /* KILL2 */ -#ifdef VMIN - s[C_MIN] = td->c_cc[VMIN]; -#endif /* VMIN */ -#ifdef VTIME - s[C_TIME] = td->c_cc[VTIME]; -#endif /* VTIME */ -} /* tty__getchar */ - - -/* tty__setchar(): - * Set the tty characters - */ -static void -tty__setchar(struct termios *td, unsigned char *s) -{ - -#ifdef VINTR - td->c_cc[VINTR] = s[C_INTR]; -#endif /* VINTR */ -#ifdef VQUIT - td->c_cc[VQUIT] = s[C_QUIT]; -#endif /* VQUIT */ -#ifdef VERASE - td->c_cc[VERASE] = s[C_ERASE]; -#endif /* VERASE */ -#ifdef VKILL - td->c_cc[VKILL] = s[C_KILL]; -#endif /* VKILL */ -#ifdef VEOF - td->c_cc[VEOF] = s[C_EOF]; -#endif /* VEOF */ -#ifdef VEOL - td->c_cc[VEOL] = s[C_EOL]; -#endif /* VEOL */ -#ifdef VEOL2 - td->c_cc[VEOL2] = s[C_EOL2]; -#endif /* VEOL2 */ -#ifdef VSWTCH - td->c_cc[VSWTCH] = s[C_SWTCH]; -#endif /* VSWTCH */ -#ifdef VDSWTCH - td->c_cc[VDSWTCH] = s[C_DSWTCH]; -#endif /* VDSWTCH */ -#ifdef VERASE2 - td->c_cc[VERASE2] = s[C_ERASE2]; -#endif /* VERASE2 */ -#ifdef VSTART - td->c_cc[VSTART] = s[C_START]; -#endif /* VSTART */ -#ifdef VSTOP - td->c_cc[VSTOP] = s[C_STOP]; -#endif /* VSTOP */ -#ifdef VWERASE - td->c_cc[VWERASE] = s[C_WERASE]; -#endif /* VWERASE */ -#ifdef VSUSP - td->c_cc[VSUSP] = s[C_SUSP]; -#endif /* VSUSP */ -#ifdef VDSUSP - td->c_cc[VDSUSP] = s[C_DSUSP]; -#endif /* VDSUSP */ -#ifdef VREPRINT - td->c_cc[VREPRINT] = s[C_REPRINT]; -#endif /* VREPRINT */ -#ifdef VDISCARD - td->c_cc[VDISCARD] = s[C_DISCARD]; -#endif /* VDISCARD */ -#ifdef VLNEXT - td->c_cc[VLNEXT] = s[C_LNEXT]; -#endif /* VLNEXT */ -#ifdef VSTATUS - td->c_cc[VSTATUS] = s[C_STATUS]; -#endif /* VSTATUS */ -#ifdef VPAGE - td->c_cc[VPAGE] = s[C_PAGE]; -#endif /* VPAGE */ -#ifdef VPGOFF - td->c_cc[VPGOFF] = s[C_PGOFF]; -#endif /* VPGOFF */ -#ifdef VKILL2 - td->c_cc[VKILL2] = s[C_KILL2]; -#endif /* VKILL2 */ -#ifdef VMIN - td->c_cc[VMIN] = s[C_MIN]; -#endif /* VMIN */ -#ifdef VTIME - td->c_cc[VTIME] = s[C_TIME]; -#endif /* VTIME */ -} /* tty__setchar */ - - -/* tty_bind_char(): - * Rebind the editline functions - */ -libedit_private void -tty_bind_char(EditLine *el, int force) -{ - - unsigned char *t_n = el->el_tty.t_c[ED_IO]; - unsigned char *t_o = el->el_tty.t_ed.c_cc; - wchar_t new[2], old[2]; - const ttymap_t *tp; - el_action_t *map, *alt; - const el_action_t *dmap, *dalt; - new[1] = old[1] = '\0'; - - map = el->el_map.key; - alt = el->el_map.alt; - if (el->el_map.type == MAP_VI) { - dmap = el->el_map.vii; - dalt = el->el_map.vic; - } else { - dmap = el->el_map.emacs; - dalt = NULL; - } - - for (tp = tty_map; tp->nch != (wint_t)-1; tp++) { - new[0] = (wchar_t)t_n[tp->nch]; - old[0] = (wchar_t)t_o[tp->och]; - if (new[0] == old[0] && !force) - continue; - /* Put the old default binding back, and set the new binding */ - keymacro_clear(el, map, old); - map[(unsigned char)old[0]] = dmap[(unsigned char)old[0]]; - keymacro_clear(el, map, new); - /* MAP_VI == 1, MAP_EMACS == 0... */ - map[(unsigned char)new[0]] = tp->bind[el->el_map.type]; - if (dalt) { - keymacro_clear(el, alt, old); - alt[(unsigned char)old[0]] = - dalt[(unsigned char)old[0]]; - keymacro_clear(el, alt, new); - alt[(unsigned char)new[0]] = - tp->bind[el->el_map.type + 1]; - } - } -} - - -static tcflag_t * -tty__get_flag(struct termios *t, int kind) { - switch (kind) { - case MD_INP: - return &t->c_iflag; - case MD_OUT: - return &t->c_oflag; - case MD_CTL: - return &t->c_cflag; - case MD_LIN: - return &t->c_lflag; - default: - abort(); - /*NOTREACHED*/ - } -} - - -static tcflag_t -tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind) -{ - f &= ~el->el_tty.t_t[mode][kind].t_clrmask; - f |= el->el_tty.t_t[mode][kind].t_setmask; - return f; -} - - -static void -tty_update_flags(EditLine *el, int kind) -{ - tcflag_t *tt, *ed, *ex; - tt = tty__get_flag(&el->el_tty.t_ts, kind); - ed = tty__get_flag(&el->el_tty.t_ed, kind); - ex = tty__get_flag(&el->el_tty.t_ex, kind); - - if (*tt != *ex && (kind != MD_CTL || *tt != *ed)) { - *ed = tty_update_flag(el, *tt, ED_IO, kind); - *ex = tty_update_flag(el, *tt, EX_IO, kind); - } -} - - -static void -tty_update_char(EditLine *el, int mode, int c) { - if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c))) - && (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c])) - el->el_tty.t_c[mode][c] = el->el_tty.t_c[TS_IO][c]; - if (el->el_tty.t_t[mode][MD_CHAR].t_clrmask & C_SH(c)) - el->el_tty.t_c[mode][c] = el->el_tty.t_vdisable; -} - - -/* tty_rawmode(): - * Set terminal into 1 character at a time mode. - */ -libedit_private int -tty_rawmode(EditLine *el) -{ - - if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO) - return 0; - - if (el->el_flags & EDIT_DISABLED) - return 0; - - if (tty_getty(el, &el->el_tty.t_ts) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - /* - * We always keep up with the eight bit setting and the speed of the - * tty. But we only believe changes that are made to cooked mode! - */ - el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); - el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); - - if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed || - tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { - (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed); - (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed); - (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); - (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); - } - if (tty__cooked_mode(&el->el_tty.t_ts)) { - int i; - - for (i = MD_INP; i <= MD_LIN; i++) - tty_update_flags(el, i); - - if (tty__gettabs(&el->el_tty.t_ex) == 0) - el->el_tty.t_tabs = 0; - else - el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; - - tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); - /* - * Check if the user made any changes. - * If he did, then propagate the changes to the - * edit and execute data structures. - */ - for (i = 0; i < C_NCC; i++) - if (el->el_tty.t_c[TS_IO][i] != - el->el_tty.t_c[EX_IO][i]) - break; - - if (i != C_NCC) { - /* - * Propagate changes only to the unlibedit_private - * chars that have been modified just now. - */ - for (i = 0; i < C_NCC; i++) - tty_update_char(el, ED_IO, i); - - tty_bind_char(el, 0); - tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); - - for (i = 0; i < C_NCC; i++) - tty_update_char(el, EX_IO, i); - - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - } - } - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = ED_IO; - return 0; -} - - -/* tty_cookedmode(): - * Set the tty back to normal mode - */ -libedit_private int -tty_cookedmode(EditLine *el) -{ /* set tty in normal setup */ - - if (el->el_tty.t_mode == EX_IO) - return 0; - - if (el->el_flags & EDIT_DISABLED) - return 0; - - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = EX_IO; - return 0; -} - - -/* tty_quotemode(): - * Turn on quote mode - */ -libedit_private int -tty_quotemode(EditLine *el) -{ - if (el->el_tty.t_mode == QU_IO) - return 0; - - el->el_tty.t_qu = el->el_tty.t_ed; - - tty_setup_flags(el, &el->el_tty.t_qu, QU_IO); - - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = QU_IO; - return 0; -} - - -/* tty_noquotemode(): - * Turn off quote mode - */ -libedit_private int -tty_noquotemode(EditLine *el) -{ - - if (el->el_tty.t_mode != QU_IO) - return 0; - if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, - strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = ED_IO; - return 0; -} - - -/* tty_stty(): - * Stty builtin - */ -libedit_private int -/*ARGSUSED*/ -tty_stty(EditLine *el, int argc __attribute__((__unused__)), - const wchar_t **argv) -{ - const ttymodes_t *m; - char x; - int aflag = 0; - const wchar_t *s, *d; - char name[EL_BUFSIZ]; - struct termios *tios = &el->el_tty.t_ex; - int z = EX_IO; - - if (argv == NULL) - return -1; - strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name)); - name[sizeof(name) - 1] = '\0'; - - while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') - switch (argv[0][1]) { - case 'a': - aflag++; - argv++; - break; - case 'd': - argv++; - tios = &el->el_tty.t_ed; - z = ED_IO; - break; - case 'x': - argv++; - tios = &el->el_tty.t_ex; - z = EX_IO; - break; - case 'q': - argv++; - tios = &el->el_tty.t_ts; - z = QU_IO; - break; - default: - (void) fprintf(el->el_errfile, - "%s: Unknown switch `%lc'.\n", - name, (wint_t)argv[0][1]); - return -1; - } - - if (!argv || !*argv) { - int i = -1; - size_t len = 0, st = 0, cu; - for (m = ttymodes; m->m_name; m++) { - if (m->m_type != i) { - (void) fprintf(el->el_outfile, "%s%s", - i != -1 ? "\n" : "", - el->el_tty.t_t[z][m->m_type].t_name); - i = m->m_type; - st = len = - strlen(el->el_tty.t_t[z][m->m_type].t_name); - } - if (i != -1) { - x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) - ? '+' : '\0'; - - if (el->el_tty.t_t[z][i].t_clrmask & m->m_value) - x = '-'; - } else { - x = '\0'; - } - - if (x != '\0' || aflag) { - - cu = strlen(m->m_name) + (x != '\0') + 1; - - if (len + cu >= - (size_t)el->el_terminal.t_size.h) { - (void) fprintf(el->el_outfile, "\n%*s", - (int)st, ""); - len = st + cu; - } else - len += cu; - - if (x != '\0') - (void) fprintf(el->el_outfile, "%c%s ", - x, m->m_name); - else - (void) fprintf(el->el_outfile, "%s ", - m->m_name); - } - } - (void) fprintf(el->el_outfile, "\n"); - return 0; - } - while (argv && (s = *argv++)) { - const wchar_t *p; - switch (*s) { - case '+': - case '-': - x = (char)*s++; - break; - default: - x = '\0'; - break; - } - d = s; - p = wcschr(s, L'='); - for (m = ttymodes; m->m_name; m++) - if ((p ? strncmp(m->m_name, ct_encode_string(d, - &el->el_scratch), (size_t)(p - d)) : - strcmp(m->m_name, ct_encode_string(d, - &el->el_scratch))) == 0 && - (p == NULL || m->m_type == MD_CHAR)) - break; - - if (!m->m_name) { - (void) fprintf(el->el_errfile, - "%s: Invalid argument `%ls'.\n", name, d); - return -1; - } - if (p) { - int c = ffs((int)m->m_value); - int v = *++p ? parse__escape(&p) : - el->el_tty.t_vdisable; - assert(c != 0); - c--; - c = tty__getcharindex(c); - assert(c != -1); - tios->c_cc[c] = (cc_t)v; - continue; - } - switch (x) { - case '+': - el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value; - el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; - break; - case '-': - el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; - el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value; - break; - default: - el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; - el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; - break; - } - } - - tty_setup_flags(el, tios, z); - if (el->el_tty.t_mode == z) { - if (tty_setty(el, TCSADRAIN, tios) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", - __func__, strerror(errno)); -#endif /* DEBUG_TTY */ - return -1; - } - } - - return 0; -} - - -#ifdef notyet -/* tty_printchar(): - * DEbugging routine to print the tty characters - */ -static void -tty_printchar(EditLine *el, unsigned char *s) -{ - ttyperm_t *m; - int i; - - for (i = 0; i < C_NCC; i++) { - for (m = el->el_tty.t_t; m->m_name; m++) - if (m->m_type == MD_CHAR && C_SH(i) == m->m_value) - break; - if (m->m_name) - (void) fprintf(el->el_errfile, "%s ^%c ", - m->m_name, s[i] + 'A' - 1); - if (i % 5 == 0) - (void) fprintf(el->el_errfile, "\n"); - } - (void) fprintf(el->el_errfile, "\n"); -} -#endif /* notyet */ - - -static void -tty_setup_flags(EditLine *el, struct termios *tios, int mode) -{ - int kind; - for (kind = MD_INP; kind <= MD_LIN; kind++) { - tcflag_t *f = tty__get_flag(tios, kind); - *f = tty_update_flag(el, *f, mode, kind); - } -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tty.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tty.h deleted file mode 100644 index 2603e1a..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/tty.h +++ /dev/null @@ -1,481 +0,0 @@ -/* $NetBSD: tty.h,v 1.21 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)tty.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * el.tty.h: Local terminal header - */ -#ifndef _h_el_tty -#define _h_el_tty - -#include -#include - -/* Define our own since everyone gets it wrong! */ -#define CONTROL(A) ((A) & 037) - -/* - * Aix compatible names - */ -# if defined(VWERSE) && !defined(VWERASE) -# define VWERASE VWERSE -# endif /* VWERSE && !VWERASE */ - -# if defined(VDISCRD) && !defined(VDISCARD) -# define VDISCARD VDISCRD -# endif /* VDISCRD && !VDISCARD */ - -# if defined(VFLUSHO) && !defined(VDISCARD) -# define VDISCARD VFLUSHO -# endif /* VFLUSHO && VDISCARD */ - -# if defined(VSTRT) && !defined(VSTART) -# define VSTART VSTRT -# endif /* VSTRT && ! VSTART */ - -# if defined(VSTAT) && !defined(VSTATUS) -# define VSTATUS VSTAT -# endif /* VSTAT && ! VSTATUS */ - -# ifndef ONLRET -# define ONLRET 0 -# endif /* ONLRET */ - -# ifndef TAB3 -# ifdef OXTABS -# define TAB3 OXTABS -# else -# define TAB3 0 -# endif /* OXTABS */ -# endif /* !TAB3 */ - -# if defined(OXTABS) && !defined(XTABS) -# define XTABS OXTABS -# endif /* OXTABS && !XTABS */ - -# ifndef ONLCR -# define ONLCR 0 -# endif /* ONLCR */ - -# ifndef IEXTEN -# define IEXTEN 0 -# endif /* IEXTEN */ - -# ifndef ECHOCTL -# define ECHOCTL 0 -# endif /* ECHOCTL */ - -# ifndef PARENB -# define PARENB 0 -# endif /* PARENB */ - -# ifndef EXTPROC -# define EXTPROC 0 -# endif /* EXTPROC */ - -# ifndef FLUSHO -# define FLUSHO 0 -# endif /* FLUSHO */ - - -# if defined(VDISABLE) && !defined(_POSIX_VDISABLE) -# define _POSIX_VDISABLE VDISABLE -# endif /* VDISABLE && ! _POSIX_VDISABLE */ - -/* - * Work around ISC's definition of IEXTEN which is - * XCASE! - */ -# ifdef ISC -# if defined(IEXTEN) && defined(XCASE) -# if IEXTEN == XCASE -# undef IEXTEN -# define IEXTEN 0 -# endif /* IEXTEN == XCASE */ -# endif /* IEXTEN && XCASE */ -# if defined(IEXTEN) && !defined(XCASE) -# define XCASE IEXTEN -# undef IEXTEN -# define IEXTEN 0 -# endif /* IEXTEN && !XCASE */ -# endif /* ISC */ - -/* - * Work around convex weirdness where turning off IEXTEN makes us - * lose all postprocessing! - */ -#if defined(convex) || defined(__convex__) -# if defined(IEXTEN) && IEXTEN != 0 -# undef IEXTEN -# define IEXTEN 0 -# endif /* IEXTEN != 0 */ -#endif /* convex || __convex__ */ - -/* - * So that we don't lose job control. - */ -#ifdef __SVR4 -# undef CSWTCH -#endif - -#ifndef _POSIX_VDISABLE -# define _POSIX_VDISABLE ((unsigned char) -1) -#endif /* _POSIX_VDISABLE */ - -#if !defined(CREPRINT) && defined(CRPRNT) -# define CREPRINT CRPRNT -#endif /* !CREPRINT && CRPRNT */ -#if !defined(CDISCARD) && defined(CFLUSH) -# define CDISCARD CFLUSH -#endif /* !CDISCARD && CFLUSH */ - -#ifndef CINTR -# define CINTR CONTROL('c') -#endif /* CINTR */ -#ifndef CQUIT -# define CQUIT 034 /* ^\ */ -#endif /* CQUIT */ -#ifndef CERASE -# define CERASE 0177 /* ^? */ -#endif /* CERASE */ -#ifndef CKILL -# define CKILL CONTROL('u') -#endif /* CKILL */ -#ifndef CEOF -# define CEOF CONTROL('d') -#endif /* CEOF */ -#ifndef CEOL -# define CEOL _POSIX_VDISABLE -#endif /* CEOL */ -#ifndef CEOL2 -# define CEOL2 _POSIX_VDISABLE -#endif /* CEOL2 */ -#ifndef CSWTCH -# define CSWTCH _POSIX_VDISABLE -#endif /* CSWTCH */ -#ifndef CDSWTCH -# define CDSWTCH _POSIX_VDISABLE -#endif /* CDSWTCH */ -#ifndef CERASE2 -# define CERASE2 _POSIX_VDISABLE -#endif /* CERASE2 */ -#ifndef CSTART -# define CSTART CONTROL('q') -#endif /* CSTART */ -#ifndef CSTOP -# define CSTOP CONTROL('s') -#endif /* CSTOP */ -#ifndef CSUSP -# define CSUSP CONTROL('z') -#endif /* CSUSP */ -#ifndef CDSUSP -# define CDSUSP CONTROL('y') -#endif /* CDSUSP */ - -#ifdef hpux - -# ifndef CREPRINT -# define CREPRINT _POSIX_VDISABLE -# endif /* CREPRINT */ -# ifndef CDISCARD -# define CDISCARD _POSIX_VDISABLE -# endif /* CDISCARD */ -# ifndef CLNEXT -# define CLNEXT _POSIX_VDISABLE -# endif /* CLNEXT */ -# ifndef CWERASE -# define CWERASE _POSIX_VDISABLE -# endif /* CWERASE */ - -#else /* !hpux */ - -# ifndef CREPRINT -# define CREPRINT CONTROL('r') -# endif /* CREPRINT */ -# ifndef CDISCARD -# define CDISCARD CONTROL('o') -# endif /* CDISCARD */ -# ifndef CLNEXT -# define CLNEXT CONTROL('v') -# endif /* CLNEXT */ -# ifndef CWERASE -# define CWERASE CONTROL('w') -# endif /* CWERASE */ - -#endif /* hpux */ - -#ifndef CSTATUS -# define CSTATUS CONTROL('t') -#endif /* CSTATUS */ -#ifndef CPAGE -# define CPAGE ' ' -#endif /* CPAGE */ -#ifndef CPGOFF -# define CPGOFF CONTROL('m') -#endif /* CPGOFF */ -#ifndef CKILL2 -# define CKILL2 _POSIX_VDISABLE -#endif /* CKILL2 */ -#ifndef CBRK -# ifndef masscomp -# define CBRK 0377 -# else -# define CBRK '\0' -# endif /* masscomp */ -#endif /* CBRK */ -#ifndef CMIN -# define CMIN CEOF -#endif /* CMIN */ -#ifndef CTIME -# define CTIME CEOL -#endif /* CTIME */ - -/* - * Fix for sun inconsistency. On termio VSUSP and the rest of the - * ttychars > NCC are defined. So we undefine them. - */ -#if defined(TERMIO) || defined(POSIX) -# if defined(POSIX) && defined(NCCS) -# define NUMCC NCCS -# else -# ifdef NCC -# define NUMCC NCC -# endif /* NCC */ -# endif /* POSIX && NCCS */ -# ifdef NUMCC -# ifdef VINTR -# if NUMCC <= VINTR -# undef VINTR -# endif /* NUMCC <= VINTR */ -# endif /* VINTR */ -# ifdef VQUIT -# if NUMCC <= VQUIT -# undef VQUIT -# endif /* NUMCC <= VQUIT */ -# endif /* VQUIT */ -# ifdef VERASE -# if NUMCC <= VERASE -# undef VERASE -# endif /* NUMCC <= VERASE */ -# endif /* VERASE */ -# ifdef VKILL -# if NUMCC <= VKILL -# undef VKILL -# endif /* NUMCC <= VKILL */ -# endif /* VKILL */ -# ifdef VEOF -# if NUMCC <= VEOF -# undef VEOF -# endif /* NUMCC <= VEOF */ -# endif /* VEOF */ -# ifdef VEOL -# if NUMCC <= VEOL -# undef VEOL -# endif /* NUMCC <= VEOL */ -# endif /* VEOL */ -# ifdef VEOL2 -# if NUMCC <= VEOL2 -# undef VEOL2 -# endif /* NUMCC <= VEOL2 */ -# endif /* VEOL2 */ -# ifdef VSWTCH -# if NUMCC <= VSWTCH -# undef VSWTCH -# endif /* NUMCC <= VSWTCH */ -# endif /* VSWTCH */ -# ifdef VDSWTCH -# if NUMCC <= VDSWTCH -# undef VDSWTCH -# endif /* NUMCC <= VDSWTCH */ -# endif /* VDSWTCH */ -# ifdef VERASE2 -# if NUMCC <= VERASE2 -# undef VERASE2 -# endif /* NUMCC <= VERASE2 */ -# endif /* VERASE2 */ -# ifdef VSTART -# if NUMCC <= VSTART -# undef VSTART -# endif /* NUMCC <= VSTART */ -# endif /* VSTART */ -# ifdef VSTOP -# if NUMCC <= VSTOP -# undef VSTOP -# endif /* NUMCC <= VSTOP */ -# endif /* VSTOP */ -# ifdef VWERASE -# if NUMCC <= VWERASE -# undef VWERASE -# endif /* NUMCC <= VWERASE */ -# endif /* VWERASE */ -# ifdef VSUSP -# if NUMCC <= VSUSP -# undef VSUSP -# endif /* NUMCC <= VSUSP */ -# endif /* VSUSP */ -# ifdef VDSUSP -# if NUMCC <= VDSUSP -# undef VDSUSP -# endif /* NUMCC <= VDSUSP */ -# endif /* VDSUSP */ -# ifdef VREPRINT -# if NUMCC <= VREPRINT -# undef VREPRINT -# endif /* NUMCC <= VREPRINT */ -# endif /* VREPRINT */ -# ifdef VDISCARD -# if NUMCC <= VDISCARD -# undef VDISCARD -# endif /* NUMCC <= VDISCARD */ -# endif /* VDISCARD */ -# ifdef VLNEXT -# if NUMCC <= VLNEXT -# undef VLNEXT -# endif /* NUMCC <= VLNEXT */ -# endif /* VLNEXT */ -# ifdef VSTATUS -# if NUMCC <= VSTATUS -# undef VSTATUS -# endif /* NUMCC <= VSTATUS */ -# endif /* VSTATUS */ -# ifdef VPAGE -# if NUMCC <= VPAGE -# undef VPAGE -# endif /* NUMCC <= VPAGE */ -# endif /* VPAGE */ -# ifdef VPGOFF -# if NUMCC <= VPGOFF -# undef VPGOFF -# endif /* NUMCC <= VPGOFF */ -# endif /* VPGOFF */ -# ifdef VKILL2 -# if NUMCC <= VKILL2 -# undef VKILL2 -# endif /* NUMCC <= VKILL2 */ -# endif /* VKILL2 */ -# ifdef VBRK -# if NUMCC <= VBRK -# undef VBRK -# endif /* NUMCC <= VBRK */ -# endif /* VBRK */ -# ifdef VMIN -# if NUMCC <= VMIN -# undef VMIN -# endif /* NUMCC <= VMIN */ -# endif /* VMIN */ -# ifdef VTIME -# if NUMCC <= VTIME -# undef VTIME -# endif /* NUMCC <= VTIME */ -# endif /* VTIME */ -# endif /* NUMCC */ -#endif /* !POSIX */ - -#define C_INTR 0 -#define C_QUIT 1 -#define C_ERASE 2 -#define C_KILL 3 -#define C_EOF 4 -#define C_EOL 5 -#define C_EOL2 6 -#define C_SWTCH 7 -#define C_DSWTCH 8 -#define C_ERASE2 9 -#define C_START 10 -#define C_STOP 11 -#define C_WERASE 12 -#define C_SUSP 13 -#define C_DSUSP 14 -#define C_REPRINT 15 -#define C_DISCARD 16 -#define C_LNEXT 17 -#define C_STATUS 18 -#define C_PAGE 19 -#define C_PGOFF 20 -#define C_KILL2 21 -#define C_BRK 22 -#define C_MIN 23 -#define C_TIME 24 -#define C_NCC 25 -#define C_SH(A) ((unsigned int)(1 << (A))) - -/* - * Terminal dependend data structures - */ -#define EX_IO 0 /* while we are executing */ -#define ED_IO 1 /* while we are editing */ -#define TS_IO 2 /* new mode from terminal */ -#define QU_IO 2 /* used only for quoted chars */ -#define NN_IO 3 /* The number of entries */ - -/* Don't re-order */ -#define MD_INP 0 -#define MD_OUT 1 -#define MD_CTL 2 -#define MD_LIN 3 -#define MD_CHAR 4 -#define MD_NN 5 - -typedef struct { - const char *t_name; - unsigned int t_setmask; - unsigned int t_clrmask; -} ttyperm_t[NN_IO][MD_NN]; - -typedef unsigned char ttychar_t[NN_IO][C_NCC]; - -libedit_private int tty_init(EditLine *); -libedit_private void tty_end(EditLine *); -libedit_private int tty_stty(EditLine *, int, const wchar_t **); -libedit_private int tty_rawmode(EditLine *); -libedit_private int tty_cookedmode(EditLine *); -libedit_private int tty_quotemode(EditLine *); -libedit_private int tty_noquotemode(EditLine *); -libedit_private void tty_bind_char(EditLine *, int); - -typedef struct { - ttyperm_t t_t; - ttychar_t t_c; - struct termios t_or, t_ex, t_ed, t_ts; - int t_tabs; - int t_eight; - speed_t t_speed; - unsigned char t_mode; - unsigned char t_vdisable; - unsigned char t_initialized; -} el_tty_t; - - -#endif /* _h_el_tty */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/unvis.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/unvis.c deleted file mode 100644 index d2c65aa..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/unvis.c +++ /dev/null @@ -1,560 +0,0 @@ -/* $NetBSD: unvis.c,v 1.44 2014/09/26 15:43:36 roy Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: unvis.c,v 1.44 2014/09/26 15:43:36 roy Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ - -#include - -#include -#include -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include -#include - -#ifdef __weak_alias -__weak_alias(strnunvisx,_strnunvisx) -#endif - -#if !HAVE_VIS -/* - * decode driven by state machine - */ -#define S_GROUND 0 /* haven't seen escape char */ -#define S_START 1 /* start decoding special sequence */ -#define S_META 2 /* metachar started (M) */ -#define S_META1 3 /* metachar more, regular char (-) */ -#define S_CTRL 4 /* control char started (^) */ -#define S_OCTAL2 5 /* octal digit 2 */ -#define S_OCTAL3 6 /* octal digit 3 */ -#define S_HEX 7 /* mandatory hex digit */ -#define S_HEX1 8 /* http hex digit */ -#define S_HEX2 9 /* http hex digit 2 */ -#define S_MIME1 10 /* mime hex digit 1 */ -#define S_MIME2 11 /* mime hex digit 2 */ -#define S_EATCRNL 12 /* mime eating CRNL */ -#define S_AMP 13 /* seen & */ -#define S_NUMBER 14 /* collecting number */ -#define S_STRING 15 /* collecting string */ - -#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') -#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) -#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10)) - -/* - * RFC 1866 - */ -static const struct nv { - char name[7]; - uint8_t value; -} nv[] = { - { "AElig", 198 }, /* capital AE diphthong (ligature) */ - { "Aacute", 193 }, /* capital A, acute accent */ - { "Acirc", 194 }, /* capital A, circumflex accent */ - { "Agrave", 192 }, /* capital A, grave accent */ - { "Aring", 197 }, /* capital A, ring */ - { "Atilde", 195 }, /* capital A, tilde */ - { "Auml", 196 }, /* capital A, dieresis or umlaut mark */ - { "Ccedil", 199 }, /* capital C, cedilla */ - { "ETH", 208 }, /* capital Eth, Icelandic */ - { "Eacute", 201 }, /* capital E, acute accent */ - { "Ecirc", 202 }, /* capital E, circumflex accent */ - { "Egrave", 200 }, /* capital E, grave accent */ - { "Euml", 203 }, /* capital E, dieresis or umlaut mark */ - { "Iacute", 205 }, /* capital I, acute accent */ - { "Icirc", 206 }, /* capital I, circumflex accent */ - { "Igrave", 204 }, /* capital I, grave accent */ - { "Iuml", 207 }, /* capital I, dieresis or umlaut mark */ - { "Ntilde", 209 }, /* capital N, tilde */ - { "Oacute", 211 }, /* capital O, acute accent */ - { "Ocirc", 212 }, /* capital O, circumflex accent */ - { "Ograve", 210 }, /* capital O, grave accent */ - { "Oslash", 216 }, /* capital O, slash */ - { "Otilde", 213 }, /* capital O, tilde */ - { "Ouml", 214 }, /* capital O, dieresis or umlaut mark */ - { "THORN", 222 }, /* capital THORN, Icelandic */ - { "Uacute", 218 }, /* capital U, acute accent */ - { "Ucirc", 219 }, /* capital U, circumflex accent */ - { "Ugrave", 217 }, /* capital U, grave accent */ - { "Uuml", 220 }, /* capital U, dieresis or umlaut mark */ - { "Yacute", 221 }, /* capital Y, acute accent */ - { "aacute", 225 }, /* small a, acute accent */ - { "acirc", 226 }, /* small a, circumflex accent */ - { "acute", 180 }, /* acute accent */ - { "aelig", 230 }, /* small ae diphthong (ligature) */ - { "agrave", 224 }, /* small a, grave accent */ - { "amp", 38 }, /* ampersand */ - { "aring", 229 }, /* small a, ring */ - { "atilde", 227 }, /* small a, tilde */ - { "auml", 228 }, /* small a, dieresis or umlaut mark */ - { "brvbar", 166 }, /* broken (vertical) bar */ - { "ccedil", 231 }, /* small c, cedilla */ - { "cedil", 184 }, /* cedilla */ - { "cent", 162 }, /* cent sign */ - { "copy", 169 }, /* copyright sign */ - { "curren", 164 }, /* general currency sign */ - { "deg", 176 }, /* degree sign */ - { "divide", 247 }, /* divide sign */ - { "eacute", 233 }, /* small e, acute accent */ - { "ecirc", 234 }, /* small e, circumflex accent */ - { "egrave", 232 }, /* small e, grave accent */ - { "eth", 240 }, /* small eth, Icelandic */ - { "euml", 235 }, /* small e, dieresis or umlaut mark */ - { "frac12", 189 }, /* fraction one-half */ - { "frac14", 188 }, /* fraction one-quarter */ - { "frac34", 190 }, /* fraction three-quarters */ - { "gt", 62 }, /* greater than */ - { "iacute", 237 }, /* small i, acute accent */ - { "icirc", 238 }, /* small i, circumflex accent */ - { "iexcl", 161 }, /* inverted exclamation mark */ - { "igrave", 236 }, /* small i, grave accent */ - { "iquest", 191 }, /* inverted question mark */ - { "iuml", 239 }, /* small i, dieresis or umlaut mark */ - { "laquo", 171 }, /* angle quotation mark, left */ - { "lt", 60 }, /* less than */ - { "macr", 175 }, /* macron */ - { "micro", 181 }, /* micro sign */ - { "middot", 183 }, /* middle dot */ - { "nbsp", 160 }, /* no-break space */ - { "not", 172 }, /* not sign */ - { "ntilde", 241 }, /* small n, tilde */ - { "oacute", 243 }, /* small o, acute accent */ - { "ocirc", 244 }, /* small o, circumflex accent */ - { "ograve", 242 }, /* small o, grave accent */ - { "ordf", 170 }, /* ordinal indicator, feminine */ - { "ordm", 186 }, /* ordinal indicator, masculine */ - { "oslash", 248 }, /* small o, slash */ - { "otilde", 245 }, /* small o, tilde */ - { "ouml", 246 }, /* small o, dieresis or umlaut mark */ - { "para", 182 }, /* pilcrow (paragraph sign) */ - { "plusmn", 177 }, /* plus-or-minus sign */ - { "pound", 163 }, /* pound sterling sign */ - { "quot", 34 }, /* double quote */ - { "raquo", 187 }, /* angle quotation mark, right */ - { "reg", 174 }, /* registered sign */ - { "sect", 167 }, /* section sign */ - { "shy", 173 }, /* soft hyphen */ - { "sup1", 185 }, /* superscript one */ - { "sup2", 178 }, /* superscript two */ - { "sup3", 179 }, /* superscript three */ - { "szlig", 223 }, /* small sharp s, German (sz ligature) */ - { "thorn", 254 }, /* small thorn, Icelandic */ - { "times", 215 }, /* multiply sign */ - { "uacute", 250 }, /* small u, acute accent */ - { "ucirc", 251 }, /* small u, circumflex accent */ - { "ugrave", 249 }, /* small u, grave accent */ - { "uml", 168 }, /* umlaut (dieresis) */ - { "uuml", 252 }, /* small u, dieresis or umlaut mark */ - { "yacute", 253 }, /* small y, acute accent */ - { "yen", 165 }, /* yen sign */ - { "yuml", 255 }, /* small y, dieresis or umlaut mark */ -}; - -/* - * unvis - decode characters previously encoded by vis - */ -int -unvis(char *cp, int c, int *astate, int flag) -{ - unsigned char uc = (unsigned char)c; - unsigned char st, ia, is, lc; - -/* - * Bottom 8 bits of astate hold the state machine state. - * Top 8 bits hold the current character in the http 1866 nv string decoding - */ -#define GS(a) ((a) & 0xff) -#define SS(a, b) (((uint32_t)(a) << 24) | (b)) -#define GI(a) ((uint32_t)(a) >> 24) - - _DIAGASSERT(cp != NULL); - _DIAGASSERT(astate != NULL); - st = GS(*astate); - - if (flag & UNVIS_END) { - switch (st) { - case S_OCTAL2: - case S_OCTAL3: - case S_HEX2: - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case S_GROUND: - return UNVIS_NOCHAR; - default: - return UNVIS_SYNBAD; - } - } - - switch (st) { - - case S_GROUND: - *cp = 0; - if ((flag & VIS_NOESCAPE) == 0 && c == '\\') { - *astate = SS(0, S_START); - return UNVIS_NOCHAR; - } - if ((flag & VIS_HTTP1808) && c == '%') { - *astate = SS(0, S_HEX1); - return UNVIS_NOCHAR; - } - if ((flag & VIS_HTTP1866) && c == '&') { - *astate = SS(0, S_AMP); - return UNVIS_NOCHAR; - } - if ((flag & VIS_MIMESTYLE) && c == '=') { - *astate = SS(0, S_MIME1); - return UNVIS_NOCHAR; - } - *cp = c; - return UNVIS_VALID; - - case S_START: - switch(c) { - case '\\': - *cp = c; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - *cp = (c - '0'); - *astate = SS(0, S_OCTAL2); - return UNVIS_NOCHAR; - case 'M': - *cp = (char)0200; - *astate = SS(0, S_META); - return UNVIS_NOCHAR; - case '^': - *astate = SS(0, S_CTRL); - return UNVIS_NOCHAR; - case 'n': - *cp = '\n'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 'r': - *cp = '\r'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 'b': - *cp = '\b'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 'a': - *cp = '\007'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 'v': - *cp = '\v'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 't': - *cp = '\t'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 'f': - *cp = '\f'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 's': - *cp = ' '; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 'E': - *cp = '\033'; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - case 'x': - *astate = SS(0, S_HEX); - return UNVIS_NOCHAR; - case '\n': - /* - * hidden newline - */ - *astate = SS(0, S_GROUND); - return UNVIS_NOCHAR; - case '$': - /* - * hidden marker - */ - *astate = SS(0, S_GROUND); - return UNVIS_NOCHAR; - default: - if (isgraph(c)) { - *cp = c; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - } - } - goto bad; - - case S_META: - if (c == '-') - *astate = SS(0, S_META1); - else if (c == '^') - *astate = SS(0, S_CTRL); - else - goto bad; - return UNVIS_NOCHAR; - - case S_META1: - *astate = SS(0, S_GROUND); - *cp |= c; - return UNVIS_VALID; - - case S_CTRL: - if (c == '?') - *cp |= 0177; - else - *cp |= c & 037; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - - case S_OCTAL2: /* second possible octal digit */ - if (isoctal(uc)) { - /* - * yes - and maybe a third - */ - *cp = (*cp << 3) + (c - '0'); - *astate = SS(0, S_OCTAL3); - return UNVIS_NOCHAR; - } - /* - * no - done with current sequence, push back passed char - */ - *astate = SS(0, S_GROUND); - return UNVIS_VALIDPUSH; - - case S_OCTAL3: /* third possible octal digit */ - *astate = SS(0, S_GROUND); - if (isoctal(uc)) { - *cp = (*cp << 3) + (c - '0'); - return UNVIS_VALID; - } - /* - * we were done, push back passed char - */ - return UNVIS_VALIDPUSH; - - case S_HEX: - if (!isxdigit(uc)) - goto bad; - /*FALLTHROUGH*/ - case S_HEX1: - if (isxdigit(uc)) { - *cp = xtod(uc); - *astate = SS(0, S_HEX2); - return UNVIS_NOCHAR; - } - /* - * no - done with current sequence, push back passed char - */ - *astate = SS(0, S_GROUND); - return UNVIS_VALIDPUSH; - - case S_HEX2: - *astate = S_GROUND; - if (isxdigit(uc)) { - *cp = xtod(uc) | (*cp << 4); - return UNVIS_VALID; - } - return UNVIS_VALIDPUSH; - - case S_MIME1: - if (uc == '\n' || uc == '\r') { - *astate = SS(0, S_EATCRNL); - return UNVIS_NOCHAR; - } - if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { - *cp = XTOD(uc); - *astate = SS(0, S_MIME2); - return UNVIS_NOCHAR; - } - goto bad; - - case S_MIME2: - if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { - *astate = SS(0, S_GROUND); - *cp = XTOD(uc) | (*cp << 4); - return UNVIS_VALID; - } - goto bad; - - case S_EATCRNL: - switch (uc) { - case '\r': - case '\n': - return UNVIS_NOCHAR; - case '=': - *astate = SS(0, S_MIME1); - return UNVIS_NOCHAR; - default: - *cp = uc; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - } - - case S_AMP: - *cp = 0; - if (uc == '#') { - *astate = SS(0, S_NUMBER); - return UNVIS_NOCHAR; - } - *astate = SS(0, S_STRING); - /*FALLTHROUGH*/ - - case S_STRING: - ia = *cp; /* index in the array */ - is = GI(*astate); /* index in the string */ - lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */ - - if (uc == ';') - uc = '\0'; - - for (; ia < __arraycount(nv); ia++) { - if (is != 0 && nv[ia].name[is - 1] != lc) - goto bad; - if (nv[ia].name[is] == uc) - break; - } - - if (ia == __arraycount(nv)) - goto bad; - - if (uc != 0) { - *cp = ia; - *astate = SS(is + 1, S_STRING); - return UNVIS_NOCHAR; - } - - *cp = nv[ia].value; - *astate = SS(0, S_GROUND); - return UNVIS_VALID; - - case S_NUMBER: - if (uc == ';') - return UNVIS_VALID; - if (!isdigit(uc)) - goto bad; - *cp += (*cp * 10) + uc - '0'; - return UNVIS_NOCHAR; - - default: - bad: - /* - * decoder in unknown state - (probably uninitialized) - */ - *astate = SS(0, S_GROUND); - return UNVIS_SYNBAD; - } -} - -/* - * strnunvisx - decode src into dst - * - * Number of chars decoded into dst is returned, -1 on error. - * Dst is null terminated. - */ - -int -strnunvisx(char *dst, size_t dlen, const char *src, int flag) -{ - char c; - char t = '\0', *start = dst; - int state = 0; - - _DIAGASSERT(src != NULL); - _DIAGASSERT(dst != NULL); -#define CHECKSPACE() \ - do { \ - if (dlen-- == 0) { \ - errno = ENOSPC; \ - return -1; \ - } \ - } while (/*CONSTCOND*/0) - - while ((c = *src++) != '\0') { - again: - switch (unvis(&t, c, &state, flag)) { - case UNVIS_VALID: - CHECKSPACE(); - *dst++ = t; - break; - case UNVIS_VALIDPUSH: - CHECKSPACE(); - *dst++ = t; - goto again; - case 0: - case UNVIS_NOCHAR: - break; - case UNVIS_SYNBAD: - errno = EINVAL; - return -1; - default: - _DIAGASSERT(/*CONSTCOND*/0); - errno = EINVAL; - return -1; - } - } - if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) { - CHECKSPACE(); - *dst++ = t; - } - CHECKSPACE(); - *dst = '\0'; - return (int)(dst - start); -} - -int -strunvisx(char *dst, const char *src, int flag) -{ - return strnunvisx(dst, (size_t)~0, src, flag); -} - -int -strunvis(char *dst, const char *src) -{ - return strnunvisx(dst, (size_t)~0, src, 0); -} - -int -strnunvis(char *dst, size_t dlen, const char *src) -{ - return strnunvisx(dst, dlen, src, 0); -} -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vi.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vi.c deleted file mode 100644 index 0c37bfb..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vi.c +++ /dev/null @@ -1,1157 +0,0 @@ -/* $NetBSD: vi.c,v 1.62 2016/05/09 21:46:56 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Christos Zoulas of Cornell University. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include "config.h" -#if !defined(lint) && !defined(SCCSID) -#if 0 -static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: vi.c,v 1.62 2016/05/09 21:46:56 christos Exp $"); -#endif -#endif /* not lint && not SCCSID */ - -/* - * vi.c: Vi mode commands. - */ -#include -#include -#include -#include -#include -#include - -#include "el.h" -#include "common.h" -#include "emacs.h" -#include "fcns.h" -#include "vi.h" - -static el_action_t cv_action(EditLine *, wint_t); -static el_action_t cv_paste(EditLine *, wint_t); - -/* cv_action(): - * Handle vi actions. - */ -static el_action_t -cv_action(EditLine *el, wint_t c) -{ - - if (el->el_chared.c_vcmd.action != NOP) { - /* 'cc', 'dd' and (possibly) friends */ - if (c != (wint_t)el->el_chared.c_vcmd.action) - return CC_ERROR; - - if (!(c & YANK)) - cv_undo(el); - cv_yank(el, el->el_line.buffer, - (int)(el->el_line.lastchar - el->el_line.buffer)); - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_vcmd.pos = 0; - if (!(c & YANK)) { - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - } - if (c & INSERT) - el->el_map.current = el->el_map.key; - - return CC_REFRESH; - } - el->el_chared.c_vcmd.pos = el->el_line.cursor; - el->el_chared.c_vcmd.action = c; - return CC_ARGHACK; -} - -/* cv_paste(): - * Paste previous deletion before or after the cursor - */ -static el_action_t -cv_paste(EditLine *el, wint_t c) -{ - c_kill_t *k = &el->el_chared.c_kill; - size_t len = (size_t)(k->last - k->buf); - - if (k->buf == NULL || len == 0) - return CC_ERROR; -#ifdef DEBUG_PASTE - (void) fprintf(el->el_errfile, "Paste: \"%.*ls\"\n", (int)len, - k->buf); -#endif - - cv_undo(el); - - if (!c && el->el_line.cursor < el->el_line.lastchar) - el->el_line.cursor++; - - c_insert(el, (int)len); - if (el->el_line.cursor + len > el->el_line.lastchar) - return CC_ERROR; - (void) memcpy(el->el_line.cursor, k->buf, len * - sizeof(*el->el_line.cursor)); - - return CC_REFRESH; -} - - -/* vi_paste_next(): - * Vi paste previous deletion to the right of the cursor - * [p] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_paste_next(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - return cv_paste(el, 0); -} - - -/* vi_paste_prev(): - * Vi paste previous deletion to the left of the cursor - * [P] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_paste_prev(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - return cv_paste(el, 1); -} - - -/* vi_prev_big_word(): - * Vi move to the previous space delimited word - * [B] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_prev_big_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - - el->el_line.cursor = cv_prev_word(el->el_line.cursor, - el->el_line.buffer, - el->el_state.argument, - cv__isWord); - - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* vi_prev_word(): - * Vi move to the previous word - * [b] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_prev_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - - el->el_line.cursor = cv_prev_word(el->el_line.cursor, - el->el_line.buffer, - el->el_state.argument, - cv__isword); - - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* vi_next_big_word(): - * Vi move to the next space delimited word - * [W] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_next_big_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor >= el->el_line.lastchar - 1) - return CC_ERROR; - - el->el_line.cursor = cv_next_word(el, el->el_line.cursor, - el->el_line.lastchar, el->el_state.argument, cv__isWord); - - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* vi_next_word(): - * Vi move to the next word - * [w] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_next_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor >= el->el_line.lastchar - 1) - return CC_ERROR; - - el->el_line.cursor = cv_next_word(el, el->el_line.cursor, - el->el_line.lastchar, el->el_state.argument, cv__isword); - - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* vi_change_case(): - * Vi change case of character under the cursor and advance one character - * [~] - */ -libedit_private el_action_t -vi_change_case(EditLine *el, wint_t c) -{ - int i; - - if (el->el_line.cursor >= el->el_line.lastchar) - return CC_ERROR; - cv_undo(el); - for (i = 0; i < el->el_state.argument; i++) { - - c = *el->el_line.cursor; - if (iswupper(c)) - *el->el_line.cursor = towlower(c); - else if (iswlower(c)) - *el->el_line.cursor = towupper(c); - - if (++el->el_line.cursor >= el->el_line.lastchar) { - el->el_line.cursor--; - re_fastaddc(el); - break; - } - re_fastaddc(el); - } - return CC_NORM; -} - - -/* vi_change_meta(): - * Vi change prefix command - * [c] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_change_meta(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - /* - * Delete with insert == change: first we delete and then we leave in - * insert mode. - */ - return cv_action(el, DELETE | INSERT); -} - - -/* vi_insert_at_bol(): - * Vi enter insert mode at the beginning of line - * [I] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_insert_at_bol(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_line.cursor = el->el_line.buffer; - cv_undo(el); - el->el_map.current = el->el_map.key; - return CC_CURSOR; -} - - -/* vi_replace_char(): - * Vi replace character under the cursor with the next character typed - * [r] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_replace_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor >= el->el_line.lastchar) - return CC_ERROR; - - el->el_map.current = el->el_map.key; - el->el_state.inputmode = MODE_REPLACE_1; - cv_undo(el); - return CC_ARGHACK; -} - - -/* vi_replace_mode(): - * Vi enter replace mode - * [R] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_replace_mode(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_map.current = el->el_map.key; - el->el_state.inputmode = MODE_REPLACE; - cv_undo(el); - return CC_NORM; -} - - -/* vi_substitute_char(): - * Vi replace character under the cursor and enter insert mode - * [s] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_substitute_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - c_delafter(el, el->el_state.argument); - el->el_map.current = el->el_map.key; - return CC_REFRESH; -} - - -/* vi_substitute_line(): - * Vi substitute entire line - * [S] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_substitute_line(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - cv_undo(el); - cv_yank(el, el->el_line.buffer, - (int)(el->el_line.lastchar - el->el_line.buffer)); - (void) em_kill_line(el, 0); - el->el_map.current = el->el_map.key; - return CC_REFRESH; -} - - -/* vi_change_to_eol(): - * Vi change to end of line - * [C] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_change_to_eol(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - cv_undo(el); - cv_yank(el, el->el_line.cursor, - (int)(el->el_line.lastchar - el->el_line.cursor)); - (void) ed_kill_line(el, 0); - el->el_map.current = el->el_map.key; - return CC_REFRESH; -} - - -/* vi_insert(): - * Vi enter insert mode - * [i] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_insert(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_map.current = el->el_map.key; - cv_undo(el); - return CC_NORM; -} - - -/* vi_add(): - * Vi enter insert mode after the cursor - * [a] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_add(EditLine *el, wint_t c __attribute__((__unused__))) -{ - int ret; - - el->el_map.current = el->el_map.key; - if (el->el_line.cursor < el->el_line.lastchar) { - el->el_line.cursor++; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - ret = CC_CURSOR; - } else - ret = CC_NORM; - - cv_undo(el); - - return (el_action_t)ret; -} - - -/* vi_add_at_eol(): - * Vi enter insert mode at end of line - * [A] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_add_at_eol(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_map.current = el->el_map.key; - el->el_line.cursor = el->el_line.lastchar; - cv_undo(el); - return CC_CURSOR; -} - - -/* vi_delete_meta(): - * Vi delete prefix command - * [d] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_delete_meta(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - return cv_action(el, DELETE); -} - - -/* vi_end_big_word(): - * Vi move to the end of the current space delimited word - * [E] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_end_big_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - - el->el_line.cursor = cv__endword(el->el_line.cursor, - el->el_line.lastchar, el->el_state.argument, cv__isWord); - - if (el->el_chared.c_vcmd.action != NOP) { - el->el_line.cursor++; - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* vi_end_word(): - * Vi move to the end of the current word - * [e] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_end_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - - el->el_line.cursor = cv__endword(el->el_line.cursor, - el->el_line.lastchar, el->el_state.argument, cv__isword); - - if (el->el_chared.c_vcmd.action != NOP) { - el->el_line.cursor++; - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* vi_undo(): - * Vi undo last change - * [u] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_undo(EditLine *el, wint_t c __attribute__((__unused__))) -{ - c_undo_t un = el->el_chared.c_undo; - - if (un.len == -1) - return CC_ERROR; - - /* switch line buffer and undo buffer */ - el->el_chared.c_undo.buf = el->el_line.buffer; - el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer; - el->el_chared.c_undo.cursor = - (int)(el->el_line.cursor - el->el_line.buffer); - el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer); - el->el_line.buffer = un.buf; - el->el_line.cursor = un.buf + un.cursor; - el->el_line.lastchar = un.buf + un.len; - - return CC_REFRESH; -} - - -/* vi_command_mode(): - * Vi enter command mode (use alternative key bindings) - * [] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - /* [Esc] cancels pending action */ - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_vcmd.pos = 0; - - el->el_state.doingarg = 0; - - el->el_state.inputmode = MODE_INSERT; - el->el_map.current = el->el_map.alt; -#ifdef VI_MOVE - if (el->el_line.cursor > el->el_line.buffer) - el->el_line.cursor--; -#endif - return CC_CURSOR; -} - - -/* vi_zero(): - * Vi move to the beginning of line - * [0] - */ -libedit_private el_action_t -vi_zero(EditLine *el, wint_t c) -{ - - if (el->el_state.doingarg) - return ed_argument_digit(el, c); - - el->el_line.cursor = el->el_line.buffer; - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - - -/* vi_delete_prev_char(): - * Vi move to previous character (backspace) - * [^H] in insert mode only - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_line.cursor <= el->el_line.buffer) - return CC_ERROR; - - c_delbefore1(el); - el->el_line.cursor--; - return CC_REFRESH; -} - - -/* vi_list_or_eof(): - * Vi list choices for completion or indicate end of file if empty line - * [^D] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_list_or_eof(EditLine *el, wint_t c) -{ - - if (el->el_line.cursor == el->el_line.lastchar) { - if (el->el_line.cursor == el->el_line.buffer) { - terminal_writec(el, c); /* then do a EOF */ - return CC_EOF; - } else { - /* - * Here we could list completions, but it is an - * error right now - */ - terminal_beep(el); - return CC_ERROR; - } - } else { -#ifdef notyet - re_goto_bottom(el); - *el->el_line.lastchar = '\0'; /* just in case */ - return CC_LIST_CHOICES; -#else - /* - * Just complain for now. - */ - terminal_beep(el); - return CC_ERROR; -#endif - } -} - - -/* vi_kill_line_prev(): - * Vi cut from beginning of line to cursor - * [^U] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_kill_line_prev(EditLine *el, wint_t c __attribute__((__unused__))) -{ - wchar_t *kp, *cp; - - cp = el->el_line.buffer; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.cursor) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer)); - el->el_line.cursor = el->el_line.buffer; /* zap! */ - return CC_REFRESH; -} - - -/* vi_search_prev(): - * Vi search history previous - * [?] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - return cv_search(el, ED_SEARCH_PREV_HISTORY); -} - - -/* vi_search_next(): - * Vi search history next - * [/] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_search_next(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - return cv_search(el, ED_SEARCH_NEXT_HISTORY); -} - - -/* vi_repeat_search_next(): - * Vi repeat current search in the same search direction - * [n] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_repeat_search_next(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_search.patlen == 0) - return CC_ERROR; - else - return cv_repeat_srch(el, el->el_search.patdir); -} - - -/* vi_repeat_search_prev(): - * Vi repeat current search in the opposite search direction - * [N] - */ -/*ARGSUSED*/ -libedit_private el_action_t -vi_repeat_search_prev(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - if (el->el_search.patlen == 0) - return CC_ERROR; - else - return (cv_repeat_srch(el, - el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? - ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY)); -} - - -/* vi_next_char(): - * Vi move to the character specified next - * [f] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_next_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); -} - - -/* vi_prev_char(): - * Vi move to the character specified previous - * [F] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); -} - - -/* vi_to_next_char(): - * Vi move up to the character specified next - * [t] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_to_next_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); -} - - -/* vi_to_prev_char(): - * Vi move up to the character specified previous - * [T] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_to_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); -} - - -/* vi_repeat_next_char(): - * Vi repeat current character search in the same search direction - * [;] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_repeat_next_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, - el->el_state.argument, el->el_search.chatflg); -} - - -/* vi_repeat_prev_char(): - * Vi repeat current character search in the opposite search direction - * [,] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_repeat_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) -{ - el_action_t r; - int dir = el->el_search.chadir; - - r = cv_csearch(el, -dir, el->el_search.chacha, - el->el_state.argument, el->el_search.chatflg); - el->el_search.chadir = dir; - return r; -} - - -/* vi_match(): - * Vi go to matching () {} or [] - * [%] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_match(EditLine *el, wint_t c __attribute__((__unused__))) -{ - const wchar_t match_chars[] = L"()[]{}"; - wchar_t *cp; - size_t delta, i, count; - wchar_t o_ch, c_ch; - - *el->el_line.lastchar = '\0'; /* just in case */ - - i = wcscspn(el->el_line.cursor, match_chars); - o_ch = el->el_line.cursor[i]; - if (o_ch == 0) - return CC_ERROR; - delta = (size_t)(wcschr(match_chars, o_ch) - match_chars); - c_ch = match_chars[delta ^ 1]; - count = 1; - delta = 1 - (delta & 1) * 2; - - for (cp = &el->el_line.cursor[i]; count; ) { - cp += delta; - if (cp < el->el_line.buffer || cp >= el->el_line.lastchar) - return CC_ERROR; - if (*cp == o_ch) - count++; - else if (*cp == c_ch) - count--; - } - - el->el_line.cursor = cp; - - if (el->el_chared.c_vcmd.action != NOP) { - /* NB posix says char under cursor should NOT be deleted - for -ve delta - this is different to netbsd vi. */ - if (delta > 0) - el->el_line.cursor++; - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; -} - -/* vi_undo_line(): - * Vi undo all changes to line - * [U] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - cv_undo(el); - return hist_get(el); -} - -/* vi_to_column(): - * Vi go to specified column - * [|] - * NB netbsd vi goes to screen column 'n', posix says nth character - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_to_column(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_line.cursor = el->el_line.buffer; - el->el_state.argument--; - return ed_next_char(el, 0); -} - -/* vi_yank_end(): - * Vi yank to end of line - * [Y] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - cv_yank(el, el->el_line.cursor, - (int)(el->el_line.lastchar - el->el_line.cursor)); - return CC_REFRESH; -} - -/* vi_yank(): - * Vi yank - * [y] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_yank(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - return cv_action(el, YANK); -} - -/* vi_comment_out(): - * Vi comment out current command - * [#] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__))) -{ - - el->el_line.cursor = el->el_line.buffer; - c_insert(el, 1); - *el->el_line.cursor = '#'; - re_refresh(el); - return ed_newline(el, 0); -} - -/* vi_alias(): - * Vi include shell alias - * [@] - * NB: posix implies that we should enter insert mode, however - * this is against historical precedent... - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_alias(EditLine *el, wint_t c __attribute__((__unused__))) -{ - char alias_name[3]; - const char *alias_text; - - if (el->el_chared.c_aliasfun == NULL) - return CC_ERROR; - - alias_name[0] = '_'; - alias_name[2] = 0; - if (el_getc(el, &alias_name[1]) != 1) - return CC_ERROR; - - alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg, - alias_name); - if (alias_text != NULL) - el_wpush(el, ct_decode_string(alias_text, &el->el_scratch)); - return CC_NORM; -} - -/* vi_to_history_line(): - * Vi go to specified history file line. - * [G] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__))) -{ - int sv_event_no = el->el_history.eventno; - el_action_t rval; - - - if (el->el_history.eventno == 0) { - (void) wcsncpy(el->el_history.buf, el->el_line.buffer, - EL_BUFSIZ); - el->el_history.last = el->el_history.buf + - (el->el_line.lastchar - el->el_line.buffer); - } - - /* Lack of a 'count' means oldest, not 1 */ - if (!el->el_state.doingarg) { - el->el_history.eventno = 0x7fffffff; - hist_get(el); - } else { - /* This is brain dead, all the rest of this code counts - * upwards going into the past. Here we need count in the - * other direction (to match the output of fc -l). - * I could change the world, but this seems to suffice. - */ - el->el_history.eventno = 1; - if (hist_get(el) == CC_ERROR) - return CC_ERROR; - el->el_history.eventno = 1 + el->el_history.ev.num - - el->el_state.argument; - if (el->el_history.eventno < 0) { - el->el_history.eventno = sv_event_no; - return CC_ERROR; - } - } - rval = hist_get(el); - if (rval == CC_ERROR) - el->el_history.eventno = sv_event_no; - return rval; -} - -/* vi_histedit(): - * Vi edit history line with vi - * [v] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_histedit(EditLine *el, wint_t c __attribute__((__unused__))) -{ - int fd; - pid_t pid; - ssize_t st; - int status; - char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; - char *cp = NULL; - size_t len; - wchar_t *line = NULL; - - if (el->el_state.doingarg) { - if (vi_to_history_line(el, 0) == CC_ERROR) - return CC_ERROR; - } - - fd = mkstemp(tempfile); - if (fd < 0) - return CC_ERROR; - len = (size_t)(el->el_line.lastchar - el->el_line.buffer); -#define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX) - cp = el_malloc(TMP_BUFSIZ * sizeof(*cp)); - if (cp == NULL) - goto error; - line = el_malloc(len * sizeof(*line) + 1); - if (line == NULL) - goto error; - wcsncpy(line, el->el_line.buffer, len); - line[len] = '\0'; - wcstombs(cp, line, TMP_BUFSIZ - 1); - cp[TMP_BUFSIZ - 1] = '\0'; - len = strlen(cp); - write(fd, cp, len); - write(fd, "\n", (size_t)1); - pid = fork(); - switch (pid) { - case -1: - goto error; - case 0: - close(fd); - execlp("vi", "vi", tempfile, (char *)NULL); - exit(0); - /*NOTREACHED*/ - default: - while (waitpid(pid, &status, 0) != pid) - continue; - lseek(fd, (off_t)0, SEEK_SET); - st = read(fd, cp, TMP_BUFSIZ - 1); - if (st > 0) { - cp[st] = '\0'; - len = (size_t)(el->el_line.limit - el->el_line.buffer); - len = mbstowcs(el->el_line.buffer, cp, len); - if (len > 0 && el->el_line.buffer[len - 1] == '\n') - --len; - } - else - len = 0; - el->el_line.cursor = el->el_line.buffer; - el->el_line.lastchar = el->el_line.buffer + len; - el_free(cp); - el_free(line); - break; - } - - close(fd); - unlink(tempfile); - /* return CC_REFRESH; */ - return ed_newline(el, 0); -error: - el_free(line); - el_free(cp); - close(fd); - unlink(tempfile); - return CC_ERROR; -} - -/* vi_history_word(): - * Vi append word from previous input line - * [_] - * Who knows where this one came from! - * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_' - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_history_word(EditLine *el, wint_t c __attribute__((__unused__))) -{ - const wchar_t *wp = HIST_FIRST(el); - const wchar_t *wep, *wsp; - int len; - wchar_t *cp; - const wchar_t *lim; - - if (wp == NULL) - return CC_ERROR; - - wep = wsp = NULL; - do { - while (iswspace(*wp)) - wp++; - if (*wp == 0) - break; - wsp = wp; - while (*wp && !iswspace(*wp)) - wp++; - wep = wp; - } while ((!el->el_state.doingarg || --el->el_state.argument > 0) - && *wp != 0); - - if (wsp == NULL || (el->el_state.doingarg && el->el_state.argument != 0)) - return CC_ERROR; - - cv_undo(el); - len = (int)(wep - wsp); - if (el->el_line.cursor < el->el_line.lastchar) - el->el_line.cursor++; - c_insert(el, len + 1); - cp = el->el_line.cursor; - lim = el->el_line.limit; - if (cp < lim) - *cp++ = ' '; - while (wsp < wep && cp < lim) - *cp++ = *wsp++; - el->el_line.cursor = cp; - - el->el_map.current = el->el_map.key; - return CC_REFRESH; -} - -/* vi_redo(): - * Vi redo last non-motion command - * [.] - */ -libedit_private el_action_t -/*ARGSUSED*/ -vi_redo(EditLine *el, wint_t c __attribute__((__unused__))) -{ - c_redo_t *r = &el->el_chared.c_redo; - - if (!el->el_state.doingarg && r->count) { - el->el_state.doingarg = 1; - el->el_state.argument = r->count; - } - - el->el_chared.c_vcmd.pos = el->el_line.cursor; - el->el_chared.c_vcmd.action = r->action; - if (r->pos != r->buf) { - if (r->pos + 1 > r->lim) - /* sanity */ - r->pos = r->lim - 1; - r->pos[0] = 0; - el_wpush(el, r->buf); - } - - el->el_state.thiscmd = r->cmd; - el->el_state.thisch = r->ch; - return (*el->el_map.func[r->cmd])(el, r->ch); -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vis.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vis.c deleted file mode 100644 index 914e7b1..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vis.c +++ /dev/null @@ -1,765 +0,0 @@ -/* $NetBSD: vis.c,v 1.72 2017/02/12 22:37:49 christos Exp $ */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -/*- - * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#include "config.h" - -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: vis.c,v 1.72 2017/02/12 22:37:49 christos Exp $"); -#endif /* LIBC_SCCS and not lint */ -#ifdef __FBSDID -__FBSDID("$FreeBSD$"); -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __weak_alias -__weak_alias(strvisx,_strvisx) -#endif - -#if !HAVE_VIS || !HAVE_SVIS -#include -#include -#include -#include - -/* - * The reason for going through the trouble to deal with character encodings - * in vis(3), is that we use this to safe encode output of commands. This - * safe encoding varies depending on the character set. For example if we - * display ps output in French, we don't want to display French characters - * as M-foo. - */ - -static wchar_t *do_svis(wchar_t *, wint_t, int, wint_t, const wchar_t *); - -#undef BELL -#define BELL L'\a' - -#if defined(LC_C_LOCALE) -#define iscgraph(c) isgraph_l(c, LC_C_LOCALE) -#else -/* Keep it simple for now, no locale stuff */ -#define iscgraph(c) isgraph(c) -#ifdef notyet -#include -static int -iscgraph(int c) { - int rv; - char *ol; - - ol = setlocale(LC_CTYPE, "C"); - rv = isgraph(c); - if (ol) - setlocale(LC_CTYPE, ol); - return rv; -} -#endif -#endif - -#define ISGRAPH(flags, c) \ - (((flags) & VIS_NOLOCALE) ? iscgraph(c) : iswgraph(c)) - -#define iswoctal(c) (((u_char)(c)) >= L'0' && ((u_char)(c)) <= L'7') -#define iswwhite(c) (c == L' ' || c == L'\t' || c == L'\n') -#define iswsafe(c) (c == L'\b' || c == BELL || c == L'\r') -#define xtoa(c) L"0123456789abcdef"[c] -#define XTOA(c) L"0123456789ABCDEF"[c] - -#define MAXEXTRAS 30 - -static const wchar_t char_shell[] = L"'`\";&<>()|{}]\\$!^~"; -static const wchar_t char_glob[] = L"*?[#"; - -#if !HAVE_NBTOOL_CONFIG_H -#ifndef __NetBSD__ -/* - * On NetBSD MB_LEN_MAX is currently 32 which does not fit on any integer - * integral type and it is probably wrong, since currently the maximum - * number of bytes and character needs is 6. Until this is fixed, the - * loops below are using sizeof(uint64_t) - 1 instead of MB_LEN_MAX, and - * the assertion is commented out. - */ -#ifdef __FreeBSD__ -/* - * On FreeBSD including for CTASSERT only works in kernel - * mode. - */ -#ifndef CTASSERT -#define CTASSERT(x) _CTASSERT(x, __LINE__) -#define _CTASSERT(x, y) __CTASSERT(x, y) -#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] -#endif -#endif /* __FreeBSD__ */ -/* -CTASSERT(MB_LEN_MAX <= sizeof(uint64_t)); -*/ -#endif /* !__NetBSD__ */ -#endif - -/* - * This is do_hvis, for HTTP style (RFC 1808) - */ -static wchar_t * -do_hvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) -{ - if (iswalnum(c) - /* safe */ - || c == L'$' || c == L'-' || c == L'_' || c == L'.' || c == L'+' - /* extra */ - || c == L'!' || c == L'*' || c == L'\'' || c == L'(' || c == L')' - || c == L',') - dst = do_svis(dst, c, flags, nextc, extra); - else { - *dst++ = L'%'; - *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); - *dst++ = xtoa((unsigned int)c & 0xf); - } - - return dst; -} - -/* - * This is do_mvis, for Quoted-Printable MIME (RFC 2045) - * NB: No handling of long lines or CRLF. - */ -static wchar_t * -do_mvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) -{ - if ((c != L'\n') && - /* Space at the end of the line */ - ((iswspace(c) && (nextc == L'\r' || nextc == L'\n')) || - /* Out of range */ - (!iswspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) || - /* Specific char to be escaped */ - wcschr(L"#$@[\\]^`{|}~", c) != NULL)) { - *dst++ = L'='; - *dst++ = XTOA(((unsigned int)c >> 4) & 0xf); - *dst++ = XTOA((unsigned int)c & 0xf); - } else - dst = do_svis(dst, c, flags, nextc, extra); - return dst; -} - -/* - * Output single byte of multibyte character. - */ -static wchar_t * -do_mbyte(wchar_t *dst, wint_t c, int flags, wint_t nextc, int iswextra) -{ - if (flags & VIS_CSTYLE) { - switch (c) { - case L'\n': - *dst++ = L'\\'; *dst++ = L'n'; - return dst; - case L'\r': - *dst++ = L'\\'; *dst++ = L'r'; - return dst; - case L'\b': - *dst++ = L'\\'; *dst++ = L'b'; - return dst; - case BELL: - *dst++ = L'\\'; *dst++ = L'a'; - return dst; - case L'\v': - *dst++ = L'\\'; *dst++ = L'v'; - return dst; - case L'\t': - *dst++ = L'\\'; *dst++ = L't'; - return dst; - case L'\f': - *dst++ = L'\\'; *dst++ = L'f'; - return dst; - case L' ': - *dst++ = L'\\'; *dst++ = L's'; - return dst; - case L'\0': - *dst++ = L'\\'; *dst++ = L'0'; - if (iswoctal(nextc)) { - *dst++ = L'0'; - *dst++ = L'0'; - } - return dst; - /* We cannot encode these characters in VIS_CSTYLE - * because they special meaning */ - case L'n': - case L'r': - case L'b': - case L'a': - case L'v': - case L't': - case L'f': - case L's': - case L'0': - case L'M': - case L'^': - case L'$': /* vis(1) -l */ - break; - default: - if (ISGRAPH(flags, c) && !iswoctal(c)) { - *dst++ = L'\\'; - *dst++ = c; - return dst; - } - } - } - if (iswextra || ((c & 0177) == L' ') || (flags & VIS_OCTAL)) { - *dst++ = L'\\'; - *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + L'0'; - *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + L'0'; - *dst++ = (c & 07) + L'0'; - } else { - if ((flags & VIS_NOSLASH) == 0) - *dst++ = L'\\'; - - if (c & 0200) { - c &= 0177; - *dst++ = L'M'; - } - - if (iswcntrl(c)) { - *dst++ = L'^'; - if (c == 0177) - *dst++ = L'?'; - else - *dst++ = c + L'@'; - } else { - *dst++ = L'-'; - *dst++ = c; - } - } - - return dst; -} - -/* - * This is do_vis, the central code of vis. - * dst: Pointer to the destination buffer - * c: Character to encode - * flags: Flags word - * nextc: The character following 'c' - * extra: Pointer to the list of extra characters to be - * backslash-protected. - */ -static wchar_t * -do_svis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) -{ - int iswextra, i, shft; - uint64_t bmsk, wmsk; - - iswextra = wcschr(extra, c) != NULL; - if (!iswextra && (ISGRAPH(flags, c) || iswwhite(c) || - ((flags & VIS_SAFE) && iswsafe(c)))) { - *dst++ = c; - return dst; - } - - /* See comment in istrsenvisx() output loop, below. */ - wmsk = 0; - for (i = sizeof(wmsk) - 1; i >= 0; i--) { - shft = i * NBBY; - bmsk = (uint64_t)0xffLL << shft; - wmsk |= bmsk; - if ((c & wmsk) || i == 0) - dst = do_mbyte(dst, (wint_t)( - (uint64_t)(c & bmsk) >> shft), - flags, nextc, iswextra); - } - - return dst; -} - -typedef wchar_t *(*visfun_t)(wchar_t *, wint_t, int, wint_t, const wchar_t *); - -/* - * Return the appropriate encoding function depending on the flags given. - */ -static visfun_t -getvisfun(int flags) -{ - if (flags & VIS_HTTPSTYLE) - return do_hvis; - if (flags & VIS_MIMESTYLE) - return do_mvis; - return do_svis; -} - -/* - * Expand list of extra characters to not visually encode. - */ -static wchar_t * -makeextralist(int flags, const char *src) -{ - wchar_t *dst, *d; - size_t len; - const wchar_t *s; - - len = strlen(src); - if ((dst = calloc(len + MAXEXTRAS, sizeof(*dst))) == NULL) - return NULL; - - if ((flags & VIS_NOLOCALE) || mbstowcs(dst, src, len) == (size_t)-1) { - size_t i; - for (i = 0; i < len; i++) - dst[i] = (wchar_t)(u_char)src[i]; - d = dst + len; - } else - d = dst + wcslen(dst); - - if (flags & VIS_GLOB) - for (s = char_glob; *s; *d++ = *s++) - continue; - - if (flags & VIS_SHELL) - for (s = char_shell; *s; *d++ = *s++) - continue; - - if (flags & VIS_SP) *d++ = L' '; - if (flags & VIS_TAB) *d++ = L'\t'; - if (flags & VIS_NL) *d++ = L'\n'; - if ((flags & VIS_NOSLASH) == 0) *d++ = L'\\'; - *d = L'\0'; - - return dst; -} - -/* - * istrsenvisx() - * The main internal function. - * All user-visible functions call this one. - */ -static int -istrsenvisx(char **mbdstp, size_t *dlen, const char *mbsrc, size_t mblength, - int flags, const char *mbextra, int *cerr_ptr) -{ - wchar_t *dst, *src, *pdst, *psrc, *start, *extra; - size_t len, olen; - uint64_t bmsk, wmsk; - wint_t c; - visfun_t f; - int clen = 0, cerr, error = -1, i, shft; - char *mbdst, *mdst; - ssize_t mbslength, maxolen; - - _DIAGASSERT(mbdstp != NULL); - _DIAGASSERT(mbsrc != NULL || mblength == 0); - _DIAGASSERT(mbextra != NULL); - - mbslength = (ssize_t)mblength; - /* - * When inputing a single character, must also read in the - * next character for nextc, the look-ahead character. - */ - if (mbslength == 1) - mbslength++; - - /* - * Input (mbsrc) is a char string considered to be multibyte - * characters. The input loop will read this string pulling - * one character, possibly multiple bytes, from mbsrc and - * converting each to wchar_t in src. - * - * The vis conversion will be done using the wide char - * wchar_t string. - * - * This will then be converted back to a multibyte string to - * return to the caller. - */ - - /* Allocate space for the wide char strings */ - psrc = pdst = extra = NULL; - mdst = NULL; - if ((psrc = calloc(mbslength + 1, sizeof(*psrc))) == NULL) - return -1; - if ((pdst = calloc((4 * mbslength) + 1, sizeof(*pdst))) == NULL) - goto out; - if (*mbdstp == NULL) { - if ((mdst = calloc((4 * mbslength) + 1, sizeof(*mdst))) == NULL) - goto out; - *mbdstp = mdst; - } - - mbdst = *mbdstp; - dst = pdst; - src = psrc; - - if (flags & VIS_NOLOCALE) { - /* Do one byte at a time conversion */ - cerr = 1; - } else { - /* Use caller's multibyte conversion error flag. */ - cerr = cerr_ptr ? *cerr_ptr : 0; - } - - /* - * Input loop. - * Handle up to mblength characters (not bytes). We do not - * stop at NULs because we may be processing a block of data - * that includes NULs. - */ - while (mbslength > 0) { - /* Convert one multibyte character to wchar_t. */ - if (!cerr) - clen = mbtowc(src, mbsrc, MB_LEN_MAX); - if (cerr || clen < 0) { - /* Conversion error, process as a byte instead. */ - *src = (wint_t)(u_char)*mbsrc; - clen = 1; - cerr = 1; - } - if (clen == 0) - /* - * NUL in input gives 0 return value. process - * as single NUL byte and keep going. - */ - clen = 1; - /* Advance buffer character pointer. */ - src++; - /* Advance input pointer by number of bytes read. */ - mbsrc += clen; - /* Decrement input byte count. */ - mbslength -= clen; - } - len = src - psrc; - src = psrc; - - /* - * In the single character input case, we will have actually - * processed two characters, c and nextc. Reset len back to - * just a single character. - */ - if (mblength < len) - len = mblength; - - /* Convert extra argument to list of characters for this mode. */ - extra = makeextralist(flags, mbextra); - if (!extra) { - if (dlen && *dlen == 0) { - errno = ENOSPC; - goto out; - } - *mbdst = '\0'; /* can't create extra, return "" */ - error = 0; - goto out; - } - - /* Look up which processing function to call. */ - f = getvisfun(flags); - - /* - * Main processing loop. - * Call do_Xvis processing function one character at a time - * with next character available for look-ahead. - */ - for (start = dst; len > 0; len--) { - c = *src++; - dst = (*f)(dst, c, flags, len >= 1 ? *src : L'\0', extra); - if (dst == NULL) { - errno = ENOSPC; - goto out; - } - } - - /* Terminate the string in the buffer. */ - *dst = L'\0'; - - /* - * Output loop. - * Convert wchar_t string back to multibyte output string. - * If we have hit a multi-byte conversion error on input, - * output byte-by-byte here. Else use wctomb(). - */ - len = wcslen(start); - maxolen = dlen ? *dlen : (wcslen(start) * MB_LEN_MAX + 1); - olen = 0; - for (dst = start; len > 0; len--) { - if (!cerr) - clen = wctomb(mbdst, *dst); - if (cerr || clen < 0) { - /* - * Conversion error, process as a byte(s) instead. - * Examine each byte and higher-order bytes for - * data. E.g., - * 0x000000000000a264 -> a2 64 - * 0x000000001f00a264 -> 1f 00 a2 64 - */ - clen = 0; - wmsk = 0; - for (i = sizeof(wmsk) - 1; i >= 0; i--) { - shft = i * NBBY; - bmsk = (uint64_t)0xffLL << shft; - wmsk |= bmsk; - if ((*dst & wmsk) || i == 0) - mbdst[clen++] = (char)( - (uint64_t)(*dst & bmsk) >> - shft); - } - cerr = 1; - } - /* If this character would exceed our output limit, stop. */ - if (olen + clen > (size_t)maxolen) - break; - /* Advance output pointer by number of bytes written. */ - mbdst += clen; - /* Advance buffer character pointer. */ - dst++; - /* Incrment output character count. */ - olen += clen; - } - - /* Terminate the output string. */ - *mbdst = '\0'; - - if (flags & VIS_NOLOCALE) { - /* Pass conversion error flag out. */ - if (cerr_ptr) - *cerr_ptr = cerr; - } - - free(extra); - free(pdst); - free(psrc); - - return (int)olen; -out: - free(extra); - free(pdst); - free(psrc); - free(mdst); - return error; -} - -static int -istrsenvisxl(char **mbdstp, size_t *dlen, const char *mbsrc, - int flags, const char *mbextra, int *cerr_ptr) -{ - return istrsenvisx(mbdstp, dlen, mbsrc, - mbsrc != NULL ? strlen(mbsrc) : 0, flags, mbextra, cerr_ptr); -} - -#endif - -#if !HAVE_SVIS -/* - * The "svis" variants all take an "extra" arg that is a pointer - * to a NUL-terminated list of characters to be encoded, too. - * These functions are useful e. g. to encode strings in such a - * way so that they are not interpreted by a shell. - */ - -char * -svis(char *mbdst, int c, int flags, int nextc, const char *mbextra) -{ - char cc[2]; - int ret; - - cc[0] = c; - cc[1] = nextc; - - ret = istrsenvisx(&mbdst, NULL, cc, 1, flags, mbextra, NULL); - if (ret < 0) - return NULL; - return mbdst + ret; -} - -char * -snvis(char *mbdst, size_t dlen, int c, int flags, int nextc, const char *mbextra) -{ - char cc[2]; - int ret; - - cc[0] = c; - cc[1] = nextc; - - ret = istrsenvisx(&mbdst, &dlen, cc, 1, flags, mbextra, NULL); - if (ret < 0) - return NULL; - return mbdst + ret; -} - -int -strsvis(char *mbdst, const char *mbsrc, int flags, const char *mbextra) -{ - return istrsenvisxl(&mbdst, NULL, mbsrc, flags, mbextra, NULL); -} - -int -strsnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags, const char *mbextra) -{ - return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, mbextra, NULL); -} - -int -strsvisx(char *mbdst, const char *mbsrc, size_t len, int flags, const char *mbextra) -{ - return istrsenvisx(&mbdst, NULL, mbsrc, len, flags, mbextra, NULL); -} - -int -strsnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, - const char *mbextra) -{ - return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, mbextra, NULL); -} - -int -strsenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, - const char *mbextra, int *cerr_ptr) -{ - return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, mbextra, cerr_ptr); -} -#endif - -#if !HAVE_VIS -/* - * vis - visually encode characters - */ -char * -vis(char *mbdst, int c, int flags, int nextc) -{ - char cc[2]; - int ret; - - cc[0] = c; - cc[1] = nextc; - - ret = istrsenvisx(&mbdst, NULL, cc, 1, flags, "", NULL); - if (ret < 0) - return NULL; - return mbdst + ret; -} - -char * -nvis(char *mbdst, size_t dlen, int c, int flags, int nextc) -{ - char cc[2]; - int ret; - - cc[0] = c; - cc[1] = nextc; - - ret = istrsenvisx(&mbdst, &dlen, cc, 1, flags, "", NULL); - if (ret < 0) - return NULL; - return mbdst + ret; -} - -/* - * strvis - visually encode characters from src into dst - * - * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NULL, - * is returned. - */ - -int -strvis(char *mbdst, const char *mbsrc, int flags) -{ - return istrsenvisxl(&mbdst, NULL, mbsrc, flags, "", NULL); -} - -int -strnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags) -{ - return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, "", NULL); -} - -int -stravis(char **mbdstp, const char *mbsrc, int flags) -{ - *mbdstp = NULL; - return istrsenvisxl(mbdstp, NULL, mbsrc, flags, "", NULL); -} - -/* - * strvisx - visually encode characters from src into dst - * - * Dst must be 4 times the size of src to account for possible - * expansion. The length of dst, not including the trailing NULL, - * is returned. - * - * Strvisx encodes exactly len characters from src into dst. - * This is useful for encoding a block of data. - */ - -int -strvisx(char *mbdst, const char *mbsrc, size_t len, int flags) -{ - return istrsenvisx(&mbdst, NULL, mbsrc, len, flags, "", NULL); -} - -int -strnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags) -{ - return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, "", NULL); -} - -int -strenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, - int *cerr_ptr) -{ - return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, "", cerr_ptr); -} -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vis.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vis.h deleted file mode 100644 index 3042d4f..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/vis.h +++ /dev/null @@ -1,116 +0,0 @@ -/* $NetBSD: vis.h,v 1.24 2016/01/14 20:42:14 christos Exp $ */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. - * - * @(#)vis.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _VIS_H_ -#define _VIS_H_ - -/* - * to select alternate encoding format - */ -#define VIS_OCTAL 0x0001 /* use octal \ddd format */ -#define VIS_CSTYLE 0x0002 /* use \[nrft0..] where appropiate */ - -/* - * to alter set of characters encoded (default is to encode all - * non-graphic except space, tab, and newline). - */ -#define VIS_SP 0x0004 /* also encode space */ -#define VIS_TAB 0x0008 /* also encode tab */ -#define VIS_NL 0x0010 /* also encode newline */ -#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) -#define VIS_SAFE 0x0020 /* only encode "unsafe" characters */ - -/* - * other - */ -#define VIS_NOSLASH 0x0040 /* inhibit printing '\' */ -#define VIS_HTTP1808 0x0080 /* http-style escape % hex hex */ -#define VIS_HTTPSTYLE 0x0080 /* http-style escape % hex hex */ -#define VIS_MIMESTYLE 0x0100 /* mime-style escape = HEX HEX */ -#define VIS_HTTP1866 0x0200 /* http-style &#num; or &string; */ -#define VIS_NOESCAPE 0x0400 /* don't decode `\' */ -#define _VIS_END 0x0800 /* for unvis */ -#define VIS_GLOB 0x1000 /* encode glob(3) magic characters */ -#define VIS_SHELL 0x2000 /* encode shell special characters [not glob] */ -#define VIS_META (VIS_WHITE | VIS_GLOB | VIS_SHELL) -#define VIS_NOLOCALE 0x4000 /* encode using the C locale */ - -/* - * unvis return codes - */ -#define UNVIS_VALID 1 /* character valid */ -#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ -#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ -#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ -#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ - -/* - * unvis flags - */ -#define UNVIS_END _VIS_END /* no more characters */ - -__BEGIN_DECLS -char *vis(char *, int, int, int); -char *nvis(char *, size_t, int, int, int); - -char *svis(char *, int, int, int, const char *); -char *snvis(char *, size_t, int, int, int, const char *); - -int strvis(char *, const char *, int); -int stravis(char **, const char *, int); -int strnvis(char *, size_t, const char *, int); - -int strsvis(char *, const char *, int, const char *); -int strsnvis(char *, size_t, const char *, int, const char *); - -int strvisx(char *, const char *, size_t, int); -int strnvisx(char *, size_t, const char *, size_t, int); -int strenvisx(char *, size_t, const char *, size_t, int, int *); - -int strsvisx(char *, const char *, size_t, int, const char *); -int strsnvisx(char *, size_t, const char *, size_t, int, const char *); -int strsenvisx(char *, size_t, const char *, size_t , int, const char *, - int *); - -int strunvis(char *, const char *); -int strnunvis(char *, size_t, const char *); - -int strunvisx(char *, const char *, int); -int strnunvisx(char *, size_t, const char *, int); - -#ifndef __LIBC12_SOURCE__ -int unvis(char *, int, int *, int); -#endif -__END_DECLS - -#endif /* !_VIS_H_ */ diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/wcsdup.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/wcsdup.c deleted file mode 100644 index 2a77375..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/c-libedit/wcsdup.c +++ /dev/null @@ -1,43 +0,0 @@ -/* $NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $ */ - -/* - * Copyright (C) 2006 Aleksey Cheusov - * - * This material is provided "as is", with absolutely no warranty expressed - * or implied. Any use is at your own risk. - * - * Permission to use or copy this software for any purpose is hereby granted - * without fee. Permission to modify the code and to distribute modified - * code is also granted without any restrictions. - */ - -#ifndef HAVE_WCSDUP - -#include "config.h" - -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $"); -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -wchar_t * -wcsdup(const wchar_t *str) -{ - wchar_t *copy; - size_t len; - - _DIAGASSERT(str != NULL); - - len = wcslen(str) + 1; - copy = malloc(len * sizeof (wchar_t)); - - if (!copy) - return NULL; - - return wmemcpy(copy, str, len); -} - -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/fncomplete.patch b/cockroach/patches/github.com/knz/go-libedit/unix/src/fncomplete.patch deleted file mode 100644 index edb4ee9..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/fncomplete.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- a/c-libedit/filecomplete.c -+++ b/c-libedit/filecomplete.c -@@ -405,7 +405,11 @@ fn_complete(EditLine *el, - char **(*attempted_completion_function)(const char *, int, int), - const wchar_t *word_break, const wchar_t *special_prefixes, - const char *(*app_func)(const char *), size_t query_items, -- int *completion_type, int *over, int *point, int *end) -+ int *completion_type, int *over, int *point, int *end, -+ const wchar_t *(*bsd_unused0)(const wchar_t *, const wchar_t *), -+ wchar_t *(*bsd_unused1)(const wchar_t *), -+ char *(*bsd_unused2)(const char *) -+ ) - { - const LineInfoW *li; - wchar_t *temp; -@@ -567,5 +571,5 @@ _el_fn_complete(EditLine *el, int ch __attribute__((__unused__))) - { - return (unsigned char)fn_complete(el, NULL, NULL, - break_chars, NULL, NULL, (size_t)100, -- NULL, NULL, NULL, NULL); -+ NULL, NULL, NULL, NULL, NULL, NULL, NULL); - } -diff --git a/unix/src/c-libedit/filecomplete.h b/unix/src/c-libedit/filecomplete.h -index 7e93b9e..fc1ca97 100644 ---- a/c-libedit/filecomplete.h -+++ b/c-libedit/filecomplete.h -@@ -35,7 +35,11 @@ int fn_complete(EditLine *, - char *(*)(const char *, int), - char **(*)(const char *, int, int), - const wchar_t *, const wchar_t *, const char *(*)(const char *), size_t, -- int *, int *, int *, int *); -+ int *, int *, int *, int *, -+ const wchar_t *(*)(const wchar_t *, const wchar_t *), -+ wchar_t *(*)(const wchar_t *), -+ char *(*)(const char *) -+ ); - - void fn_display_match_list(EditLine *, char **, size_t, size_t); - char *fn_tilde_expand(const char *); -diff --git a/unix/src/c-libedit/readline.c b/unix/src/c-libedit/readline.c -index 74a7615..f62aeaa 100644 ---- a/c-libedit/readline.c -+++ b/c-libedit/readline.c -@@ -1873,7 +1873,7 @@ rl_complete(int ignore __attribute__((__unused__)), int invoking_key) - _rl_completion_append_character_function, - (size_t)rl_completion_query_items, - &rl_completion_type, &rl_attempted_completion_over, -- &rl_point, &rl_end); -+ &rl_point, &rl_end, NULL, NULL, NULL); - - - } diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-chared.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-chared.c deleted file mode 100644 index bfb82bb..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-chared.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "chared.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-chartype.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-chartype.c deleted file mode 100644 index 9c0d8c3..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-chartype.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "chartype.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-common.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-common.c deleted file mode 100644 index 2a13c5b..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-common.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "common.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-el.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-el.c deleted file mode 100644 index 8b65c98..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-el.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "el.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-eln.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-eln.c deleted file mode 100644 index 1b2ff72..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-eln.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "eln.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-emacs.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-emacs.c deleted file mode 100644 index 55cb4b6..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-emacs.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "emacs.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-filecomplete.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-filecomplete.c deleted file mode 100644 index 60247ef..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-filecomplete.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "filecomplete.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-hist.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-hist.c deleted file mode 100644 index c902ca4..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-hist.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "hist.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-history.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-history.c deleted file mode 100644 index 99bf931..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-history.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "history.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-historyn.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-historyn.c deleted file mode 100644 index d1a8a15..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-historyn.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "historyn.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-keymacro.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-keymacro.c deleted file mode 100644 index e836273..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-keymacro.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "keymacro.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-map.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-map.c deleted file mode 100644 index 4ec44e9..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-map.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "map.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-parse.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-parse.c deleted file mode 100644 index b594eef..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-parse.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "parse.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-prompt.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-prompt.c deleted file mode 100644 index 60591b6..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-prompt.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "prompt.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-read.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-read.c deleted file mode 100644 index 01300cd..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-read.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "read.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-readline.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-readline.c deleted file mode 100644 index 98da7e1..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-readline.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "readline.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-refresh.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-refresh.c deleted file mode 100644 index 1c22aac..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-refresh.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "refresh.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-search.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-search.c deleted file mode 100644 index 5f8d76c..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-search.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "search.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-sig.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-sig.c deleted file mode 100644 index 40685cb..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-sig.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "sig.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-strlcat.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-strlcat.c deleted file mode 100644 index 0c80b13..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-strlcat.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "strlcat.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-strlcpy.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-strlcpy.c deleted file mode 100644 index 394b0a7..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-strlcpy.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "strlcpy.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-terminal.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-terminal.c deleted file mode 100644 index 4a91894..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-terminal.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "terminal.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tokenizer.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tokenizer.c deleted file mode 100644 index 6749c9f..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tokenizer.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "tokenizer.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tokenizern.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tokenizern.c deleted file mode 100644 index 199b26f..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tokenizern.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "tokenizern.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tty.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tty.c deleted file mode 100644 index beeb6f3..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-tty.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "tty.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-unvis.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-unvis.c deleted file mode 100644 index 5e2231b..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-unvis.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "unvis.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-vi.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-vi.c deleted file mode 100644 index ca023fa..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-vi.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "vi.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-vis.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-vis.c deleted file mode 100644 index 1264354..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-vis.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "vis.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-wcsdup.c b/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-wcsdup.c deleted file mode 100644 index da2897b..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/libedit-wcsdup.c +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef GO_LIBEDIT_NO_BUILD -#include "wcsdup.c" -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/refresh.sh b/cockroach/patches/github.com/knz/go-libedit/unix/src/refresh.sh deleted file mode 100755 index 13e5319..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/refresh.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -set -euxo pipefail - -rm -f ../shim/*.c -rm -f ../wrap-*.c -rm -rf c-libedit -git add -u .. - -rm -rf libbsd[-_]* libedit[-_]* build - -apt-get source libbsd0 -apt-get source libedit - -mkdir build -(cd build \ - && export ac_cv_func_secure_getenv=no \ - && export ac_cv_func___secure_getenv=no \ - && export ac_cv_header_sys_cdefs_h=no \ - && export ac_cv_header_curses_h=no \ - && export ac_cv_header_ncurses_h=no \ - && ../libedit-*/configure \ - && make SUBDIRS=src) - -mkdir -p c-libedit/linux-build c-libedit/editline - -cp -a libedit-*/src/editline c-libedit/ -cp -a libedit-*/src/*.[ch] c-libedit/ -cp -a build/config.h build/src/*.h c-libedit/linux-build/ - -# This Linux readline is out of sync with the main BSD repo. The Newer -# BSD readlines have 3 extra arguments on fn_complete(). Make them -# exist so that the C calls don't crash. -patch -p1 ../libedit-$i - echo "#include \"$i\"">>../libedit-$i - echo "#endif">>../libedit-$i - echo "// Nothing to see here.">../../shim/libedit-$i - echo "#include \"libedit-$i\"">../../wrap-$i - done) - -git add ../shim/*.c -git add ../wrap-*.c -git add libedit-*.c -git add c-libedit diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/secure_getenv.patch b/cockroach/patches/github.com/knz/go-libedit/unix/src/secure_getenv.patch deleted file mode 100644 index c384e37..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/secure_getenv.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/c-libedit/el.c -+++ b/c-libedit/el.c -@@ -66,15 +66,23 @@ __RCSID("$NetBSD: el.c,v 1.92 2016/05/22 19:44:26 christos Exp $"); - # define secure_getenv __secure_getenv - # define HAVE_SECURE_GETENV 1 - # else --# ifdef HAVE_ISSETUGID --# include --# else -+# include -+# ifndef HAVE_ISSETUGID - # undef issetugid --# define issetugid() 1 -+# define issetugid() (getuid() != geteuid() || getgid() != getegid()) - # endif - # endif - #endif - -+#if !defined(HAVE_SECURE_GETENV) && defined(__GLIBC__) -+# if __GLIBC__ >= 2 -+# if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 17) -+# define secure_getenv __secure_getenv -+# endif -+# define HAVE_SECURE_GETENV 1 -+# endif -+#endif -+ - #ifndef HAVE_SECURE_GETENV - char *secure_getenv(char const *name) - { diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/src/termcap.h b/cockroach/patches/github.com/knz/go-libedit/unix/src/termcap.h deleted file mode 100644 index 2c33f00..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/src/termcap.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FAKE_TERMCAP_H -#define FAKE_TERMCAP_H - -// This header file is provided so as to avoid a dependency on the -// ncurses development headers. These are the only functions used by -// libedit. - -extern char * tgetstr (const char *, char **); -extern char * tgoto (const char *, int, int); -extern int tgetent (char *, const char *); -extern int tgetflag (const char *); -extern int tgetnum (const char *); -extern int tputs (const char *, int, int (*)(int)); - - -#endif diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/stub_find_word_to_complete.i b/cockroach/patches/github.com/knz/go-libedit/unix/stub_find_word_to_complete.i deleted file mode 100644 index c6fa83f..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/stub_find_word_to_complete.i +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jaromir Dolecek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -// These functions are auxiliaries for the code in -// stub_fn_complete.i. - -static wchar_t * -find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer, - const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length) -{ - /* We now look backwards for the start of a filename/variable word */ - const wchar_t *ctemp = cursor; - int cursor_at_quote; - size_t len; - wchar_t *temp; - - /* if the cursor is placed at a slash or a quote, we need to find the - * word before it - */ - if (ctemp > buffer) { - switch (ctemp[-1]) { - case '\\': - case '\'': - case '"': - cursor_at_quote = 1; - ctemp--; - break; - default: - cursor_at_quote = 0; - } - } else - cursor_at_quote = 0; - - while (ctemp > buffer - && !wcschr(word_break, ctemp[-1]) - && (!special_prefixes || !wcschr(special_prefixes, ctemp[-1]))) - ctemp--; - - len = (size_t) (cursor - ctemp - cursor_at_quote); - temp = malloc((len + 1) * sizeof(*temp)); - if (temp == NULL) - return NULL; - (void) wcsncpy(temp, ctemp, len); - temp[len] = '\0'; - if (cursor_at_quote) - len++; - *length = len; - return temp; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/stub_fn_complete.i b/cockroach/patches/github.com/knz/go-libedit/unix/stub_fn_complete.i deleted file mode 100644 index 66890ab..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/stub_fn_complete.i +++ /dev/null @@ -1,165 +0,0 @@ -// This is a stub provided for compatibility with macOS Mojave and -// other possible systems that have decided they didn't want to export -// the true fn_complete(). -// This stub does not perform filename completion and does not -// offer a selection menu. It also does not offer compatibility -// with readline() (via the completion_type argument). - -#include "stub_find_word_to_complete.i" - -static char *multibyte_to_singlebyte(wchar_t *line); -static wchar_t *singlebyte_to_multibyte(char *line); - -static -int fn_complete( - EditLine *el, - char *(*complet_func)(const char *, int), // ignored - char **(*attempted_completion_function)(const char *, int, int), - const wchar_t *word_break, - const wchar_t *special_prefixes, // ignored - const char *(*app_func)(const char *), // ignored - size_t query_items, - int *completion_type, // ignored - int *over, // ignored - int *point, // ignored - int *end, // ignored - const wchar_t *(*find_word_start_func)(const wchar_t *, const wchar_t *), // ignored - wchar_t *(*dequoting_func)(const wchar_t *), // ignored - char *(*quoting_func)(const char *) // ignored - ) -{ - char *completion_prefix; - size_t completion_prefix_len; - wchar_t *temp; - int cur_off; - char **matches; - int retval = CC_NORM; - - if (!attempted_completion_function) - /* nothing to do. We don't support file completion here. */ - goto out; - - const LineInfoW *li = el_wline(el); - - /* - * isolate the completion prefix. - */ - temp = find_word_to_complete( - li->cursor, - li->buffer, word_break, special_prefixes, - &completion_prefix_len); - if (temp == NULL) - /* nothing to do. */ - goto out; - - completion_prefix = multibyte_to_singlebyte(temp); - - /* - * compute the completion matches. - */ - - /* cursor offset from begin of the line. */ - cur_off = (int)(li->cursor - li->buffer); - /* compute the completion matches. */ - matches = (*attempted_completion_function)( - completion_prefix, cur_off - (int)completion_prefix_len, cur_off); - - if (!matches) - /* nothing to do any more. */ - goto out; - - int single_match = matches[2] == NULL && - (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0); - - if (matches[0][0] != '\0') { - /* clear the completion prefix. */ - el_deletestr(el, (int) completion_prefix_len); - - /* compute the completion to display. */ - wchar_t *completion = singlebyte_to_multibyte(matches[0]); - if (!completion) - goto out; - - /* print it. */ - el_winsertstr(el, completion); - free(completion); - - if (single_match) - /* insert a space after the match. */ - el_winsertstr(el, L" "); - - /* show the completion result upon returning. */ - retval = CC_REFRESH; - } - if (!single_match && matches[0][0]) - /* some common match but not complete match. - * inform the user the input is still incomplete. */ - el_beep(el); - -out: - /* - * release resources and complete. - */ - if (matches) { - for (size_t i = 0; matches[i]; i++) - free(matches[i]); - free(matches); - } - if (completion_prefix) { - free(completion_prefix); - } - if (temp) { - free(temp); - } - return retval; -} - -char *multibyte_to_singlebyte(wchar_t *s) { - char *buf = NULL; - size_t i = 0; - size_t bufsz = 0; - do { - /* the +1 below is to make space for the final NUL byte */ - if (i + MB_LEN_MAX + 1 >= bufsz) { - /* out of space. */ - bufsz = (bufsz == 0 ? 1024 : bufsz * 2); - char *newbuf = realloc(buf, bufsz); - if (newbuf == NULL) { - free(buf); - return NULL; - } - buf = newbuf; - } - if (!*s) - /* nothing remaining to convert. */ - break; - - /* convert one character */ - int l = wctomb(buf + i, *s); - if (l < 0) { - /* reset the converter */ - wctomb(NULL, L'\0'); - free(buf); - return NULL; - } - i += l; - s++; - } while(1); - buf[i] = '\0'; - return buf; -} - -wchar_t *singlebyte_to_multibyte(char *s) { - /* compute the multibyte len. */ - size_t len = mbstowcs(NULL, s, 0); - if (len == (size_t)-1) - return NULL; - - /* make space. len does not count the final NUL so we need to add it here. */ - len++; - wchar_t * r = malloc(len * sizeof(wchar_t)); - if (r) - /* do the actual conversion. */ - mbstowcs(r, s, len); - return r; -} diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-chared.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-chared.c deleted file mode 100644 index 5cc5579..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-chared.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-chared.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-chartype.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-chartype.c deleted file mode 100644 index 59932c0..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-chartype.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-chartype.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-common.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-common.c deleted file mode 100644 index 10b7635..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-common.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-common.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-el.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-el.c deleted file mode 100644 index 1ee71c4..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-el.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-el.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-eln.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-eln.c deleted file mode 100644 index b5a2916..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-eln.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-eln.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-emacs.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-emacs.c deleted file mode 100644 index 1f73308..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-emacs.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-emacs.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-filecomplete.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-filecomplete.c deleted file mode 100644 index 46746dc..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-filecomplete.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-filecomplete.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-hist.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-hist.c deleted file mode 100644 index 7013fcc..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-hist.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-hist.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-history.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-history.c deleted file mode 100644 index 0993622..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-history.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-history.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-historyn.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-historyn.c deleted file mode 100644 index e17c084..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-historyn.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-historyn.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-keymacro.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-keymacro.c deleted file mode 100644 index c3f20ea..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-keymacro.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-keymacro.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-map.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-map.c deleted file mode 100644 index 2f52d2d..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-map.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-map.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-parse.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-parse.c deleted file mode 100644 index f2e1b77..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-parse.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-parse.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-prompt.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-prompt.c deleted file mode 100644 index 16c367b..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-prompt.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-prompt.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-read.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-read.c deleted file mode 100644 index e2dacab..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-read.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-read.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-readline.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-readline.c deleted file mode 100644 index 3316524..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-readline.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-readline.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-refresh.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-refresh.c deleted file mode 100644 index 9d9ef88..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-refresh.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-refresh.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-search.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-search.c deleted file mode 100644 index a9cdbbf..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-search.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-search.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-sig.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-sig.c deleted file mode 100644 index 43c20bb..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-sig.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-sig.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-strlcat.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-strlcat.c deleted file mode 100644 index 68568d1..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-strlcat.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-strlcat.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-strlcpy.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-strlcpy.c deleted file mode 100644 index df0110e..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-strlcpy.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-strlcpy.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-terminal.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-terminal.c deleted file mode 100644 index 108db8d..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-terminal.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-terminal.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tokenizer.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tokenizer.c deleted file mode 100644 index 8ab1b9e..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tokenizer.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-tokenizer.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tokenizern.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tokenizern.c deleted file mode 100644 index acc4b10..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tokenizern.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-tokenizern.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tty.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tty.c deleted file mode 100644 index 163ff03..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-tty.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-tty.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-unvis.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-unvis.c deleted file mode 100644 index 8a72fd0..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-unvis.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-unvis.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-vi.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-vi.c deleted file mode 100644 index 372b12d..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-vi.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-vi.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-vis.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-vis.c deleted file mode 100644 index aef27e7..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-vis.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-vis.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-wcsdup.c b/cockroach/patches/github.com/knz/go-libedit/unix/wrap-wcsdup.c deleted file mode 100644 index c22d54d..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/unix/wrap-wcsdup.c +++ /dev/null @@ -1 +0,0 @@ -#include "libedit-wcsdup.c" diff --git a/cockroach/patches/github.com/knz/go-libedit/version_check.go b/cockroach/patches/github.com/knz/go-libedit/version_check.go deleted file mode 100644 index b89191a..0000000 --- a/cockroach/patches/github.com/knz/go-libedit/version_check.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2019 Raphael 'kena' Poss -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. - -// +build !go1.11 - -package libedit - -func init() { - panic("go-libedit requires go1.11+") -} diff --git a/cockroach/patches/github.com/knz/strtime/.gitignore b/cockroach/patches/github.com/knz/strtime/.gitignore deleted file mode 100644 index daf913b..0000000 --- a/cockroach/patches/github.com/knz/strtime/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/cockroach/patches/github.com/knz/strtime/LICENSE b/cockroach/patches/github.com/knz/strtime/LICENSE deleted file mode 100644 index 94d3410..0000000 --- a/cockroach/patches/github.com/knz/strtime/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -BSD 2-Clause License - -Copyright (c) 2017, kena -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. - -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 HOLDER 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. diff --git a/cockroach/patches/github.com/knz/strtime/README.md b/cockroach/patches/github.com/knz/strtime/README.md deleted file mode 100644 index b24f3ac..0000000 --- a/cockroach/patches/github.com/knz/strtime/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# strtime: stable strptime / strftime for Go - -`strftime` and `strptime` are functions found in nearly all C -library implementations but with slightly different behaviors on each -platform. - -To provide identical behavior on all platforms where Go is supported, -this **strtime** package provides two functions `Strftime` and -`Strptime` which can be used *in lieu* of the platform's native C -implementation. - -To achieve this **strtime**: - -- embeds and extends a `Strftime` function in Go, using an - implementation originally from `leekchan`'s - [timeutil](https://github.com/leekchan/timeutil) package, which - performs the format conversion natively in Go and is licensed under - the terms of the standard MIT license; and -- embeds the standard FreeBSD implementation of `strptime` in - C. FreeBSD's implementation is mature, robust, has the widest format - specifier coverage, and its code is reusable under the terms of the - permissive BSD license. - -**strtime** is itself offered under the terms of the 2-clause BSD license. - -# How to use - -~~~ go -func Strptime(value string, layout string) (time.Time, error) -func Strftime(t time.Time, layout string) (string, error) -~~~ - -Examples: - -~~~ go - start := "2016-10-20" - t, _ := strtime.Strptime(start, "%Y-%m-%d") - end, _ := strtime.Strftime(t, "%Y-%m-%d") - Fmt.Println(start, end) -~~~ - -# Supported format specifiers - -| Format | Description | Notes -|--------|-------------|--------- -| `%a` | Short week day ("mon", "tue", etc) | -| `%A` | Long week day ("monday", "tuesday", etc) | -| `%b` | Short month name ("jan", "feb" etc) | -| `%B` | Long month name ("january", "february" etc) | -| `%c` | Equivalent to `%a %b %e %H:%M:%S %Y` | -| `%C` | Century | Only reliable for years -9999 to 9999 -| `%d` | Day of month 01-31 | -| `%D` | Equivalent to `%m/%d/%y` | -| `%e` | Like `%d` but leading zeros are replaced by a space. | -| `%f` | Fractional part of a second with nanosecond precision, e.g. "`123`" is 123ms; "`123456`" is 123456µs, etc. | `Strftime` always formats using 6 digits. -| `%F` | Equivalent to `%Y-%m-%d` | -| `%h` | Equivalent to `%b` | -| `%H` | Hours 00-23 | See also `%k` -| `%I` | Hours 01-12 | See also `%p`, `%l` -| `%j` | Day of year 000-366 | -| `%k` | Hours 0-23 (padded with spaces) | See also `%H` -| `%l` | Hours 1-12 (padded with spaces) | See also `%I` -| `%m` | Month 01-12 | -| `%M` | Minutes 00-59 | -| `%n` | A newline character | -| `%p` | AM/PM | Only valid when placed after hour-related specifiers. See also `%I`, `%l` -| `%r` | Equivalent to `%I:%M:%S %p` | -| `%R` | Equivalent to `%H:%M` | See also `%T` -| `%s` | Number of seconds since 1970-01-01 00:00:00 +0000 (UTC) | -| `%S` | Seconds 00-59 | -| `%t` | A tab character | -| `%T` | Equivalent to `%H:%M:%S` | See also `%R` -| `%u` | The day of the week as a decimal, range 1 to 7, Monday being 1 | See also `%w` -| `%U` | The week number of the current year as a decimal number, range 00 to 53, starting with the first Sunday as the first day of week 01 | See also `%W` -| `%w` | The day of the week as a decimal, range 0 to 6, Sunday being 1 | See also `%u` -| `%W` | The week number of the current year as a decimal number, range 00 to 53, starting with the first Monday as the first day of week 01 | See also `%U` -| `%x` | Equivalent to `%D` | -| `%X` | Equivalent to `%T` | -| `%y` | Year without a century 00-99 | Years 00-68 are 2000-2068 -| `%Y` | Year including the century | -| `%z` | Time zone offset +/-NNNN | `Strftime` always prints `+0000` -| `%Z` | `UTC` or `GMT` | `Strftime` always prints `UTC` diff --git a/cockroach/patches/github.com/knz/strtime/bsdshim.h b/cockroach/patches/github.com/knz/strtime/bsdshim.h deleted file mode 100644 index 61ea94a..0000000 --- a/cockroach/patches/github.com/knz/strtime/bsdshim.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef BSDSHIM_H -#define BSDSHIM_H - -#include -#include -#include - -#define locale_t int - -#ifdef isspace_l -#undef isspace_l -#endif -#define isspace_l(A, _) isspace(A) -#ifdef isdigit_l -#undef isdigit_l -#endif -#define isdigit_l(A, _) isdigit(A) -#ifdef isupper_l -#undef isupper_l -#endif -#define isupper_l(A, _) isupper(A) -#ifdef strtol_l -#undef strtol_l -#endif -#define strtol_l(A, B, C, _) strtol(A, B, C) - -#ifdef isleap -#undef isleap -#endif -#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) - -#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ - -#define SECSPERMIN 60 -#define MINSPERHOUR 60 -#define HOURSPERDAY 24 -#define DAYSPERWEEK 7 -#define DAYSPERNYEAR 365 -#define DAYSPERLYEAR 366 -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) -#define MONSPERYEAR 12 - -#define TM_SUNDAY 0 -#define TM_MONDAY 1 -#define TM_TUESDAY 2 -#define TM_WEDNESDAY 3 -#define TM_THURSDAY 4 -#define TM_FRIDAY 5 -#define TM_SATURDAY 6 - -#define TM_JANUARY 0 -#define TM_FEBRUARY 1 -#define TM_MARCH 2 -#define TM_APRIL 3 -#define TM_MAY 4 -#define TM_JUNE 5 -#define TM_JULY 6 -#define TM_AUGUST 7 -#define TM_SEPTEMBER 8 -#define TM_OCTOBER 9 -#define TM_NOVEMBER 10 -#define TM_DECEMBER 11 - -#define TM_YEAR_BASE 1900 - -#define EPOCH_YEAR 1970 -#define EPOCH_WDAY TM_THURSDAY - -struct mytm { - int tm_sec; /* seconds after the minute [0-60] */ - int tm_min; /* minutes after the hour [0-59] */ - int tm_hour; /* hours since midnight [0-23] */ - int tm_mday; /* day of the month [1-31] */ - int tm_mon; /* months since January [0-11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday [0-6] */ - int tm_yday; /* days since January 1 [0-365] */ - int tm_isdst; /* Daylight Savings Time flag */ - long tm_gmtoff; /* offset from UTC in seconds */ - char *tm_zone; /* timezone abbreviation */ - long tm_nsec; /* nanoseconds */ -}; - -static int -mystrcasecmp(const char *s1, const char *s2) -{ - const unsigned char - *us1 = (const unsigned char *)s1, - *us2 = (const unsigned char *)s2; - - while (tolower(*us1) == tolower(*us2++)) - if (*us1++ == '\0') - return (0); - return (tolower(*us1) - tolower(*--us2)); -} - -#ifdef strcasecmp_l -#undef strcasecmp_l -#endif -#define strcasecmp_l(A, B, _) mystrcasecmp(A, B) - -static int -mystrncasecmp(const char *s1, const char *s2, size_t n) -{ - if (n != 0) { - const unsigned char - *us1 = (const unsigned char *)s1, - *us2 = (const unsigned char *)s2; - - do { - if (tolower(*us1) != tolower(*us2++)) - return (tolower(*us1) - tolower(*--us2)); - if (*us1++ == '\0') - break; - } while (--n != 0); - } - return (0); -} -#ifdef strncasecmp_l -#undef strncasecmp_l -#endif -#define strncasecmp_l(A, B, C, _) mystrncasecmp(A, B, C) - -#ifdef gmtime_r -#undef gmtime_r -#endif -extern struct mytm* mygmtime_r(const time_t* timep, struct mytm* tm); -#define gmtime_r(A, B) mygmtime_r(A, B) - - -#endif diff --git a/cockroach/patches/github.com/knz/strtime/gmtime_r.c b/cockroach/patches/github.com/knz/strtime/gmtime_r.c deleted file mode 100644 index 5c00324..0000000 --- a/cockroach/patches/github.com/knz/strtime/gmtime_r.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Taken from FreeBSD src / lib / libc / stdtime / localtime.c 1.43 revision. - * localtime.c 7.78. - * tzfile.h 1.8 - * adapted to be replacement gmtime_r. - */ -// #include "config.h" -// -// #ifdef HAVE_TIME_H -#include -// #endif -// -// #define MONSPERYEAR 12 -// #define DAYSPERNYEAR 365 -// #define DAYSPERLYEAR 366 -// #define SECSPERMIN 60 -// #define SECSPERHOUR (60*60) -// #define SECSPERDAY (24*60*60) -// #define DAYSPERWEEK 7 -// #define TM_SUNDAY 0 -// #define TM_MONDAY 1 -// #define TM_TUESDAY 2 -// #define TM_WEDNESDAY 3 -// #define TM_THURSDAY 4 -// #define TM_FRIDAY 5 -// #define TM_SATURDAY 6 -// -// #define TM_YEAR_BASE 1900 -// -// #define EPOCH_YEAR 1970 -// #define EPOCH_WDAY TM_THURSDAY -// -// #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) - -#include "bsdshim.h" - -static const int mon_lengths[2][MONSPERYEAR] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; - -static const int year_lengths[2] = { - DAYSPERNYEAR, DAYSPERLYEAR -}; - -static void -timesub(timep, offset, tmp) -const time_t * const timep; -const long offset; -struct mytm * const tmp; -{ - long days; - long rem; - long y; - int yleap; - const int * ip; - - days = *timep / SECSPERDAY; - rem = *timep % SECSPERDAY; - rem += (offset); - while (rem < 0) { - rem += SECSPERDAY; - --days; - } - while (rem >= SECSPERDAY) { - rem -= SECSPERDAY; - ++days; - } - tmp->tm_hour = (int) (rem / SECSPERHOUR); - rem = rem % SECSPERHOUR; - tmp->tm_min = (int) (rem / SECSPERMIN); - /* - ** A positive leap second requires a special - ** representation. This uses "... ??:59:60" et seq. - */ - tmp->tm_sec = (int) (rem % SECSPERMIN) ; - tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); - if (tmp->tm_wday < 0) - tmp->tm_wday += DAYSPERWEEK; - y = EPOCH_YEAR; -#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) - while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { - long newy; - - newy = y + days / DAYSPERNYEAR; - if (days < 0) - --newy; - days -= (newy - y) * DAYSPERNYEAR + - LEAPS_THRU_END_OF(newy - 1) - - LEAPS_THRU_END_OF(y - 1); - y = newy; - } - tmp->tm_year = y - TM_YEAR_BASE; - tmp->tm_yday = (int) days; - ip = mon_lengths[yleap]; - for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) - days = days - (long) ip[tmp->tm_mon]; - tmp->tm_mday = (int) (days + 1); - tmp->tm_isdst = 0; -} - -/* -* Re-entrant version of gmtime. -*/ -struct mytm * mygmtime_r(const time_t* timep, struct mytm *tm) -{ - timesub(timep, 0L, tm); - return tm; -} diff --git a/cockroach/patches/github.com/knz/strtime/strftime.go b/cockroach/patches/github.com/knz/strtime/strftime.go deleted file mode 100644 index 0009ede..0000000 --- a/cockroach/patches/github.com/knz/strtime/strftime.go +++ /dev/null @@ -1,217 +0,0 @@ -// strftime.go -// -// Copyright (c) 2017 Cockroach Labs -// Copyright (c) 2015 Kyoung-chan Lee (leekchan@gmail.com) -// -// 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. - -package strtime - -// Code taken over from github.com/leekchan/timeutil and extended. - -import ( - "fmt" - "strings" - "time" -) - -var longDayNames = []string{ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", -} - -var shortDayNames = []string{ - "Sun", - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat", -} - -var shortMonthNames = []string{ - "---", - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec", -} - -var longMonthNames = []string{ - "---", - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", -} - -func weekNumber(t time.Time, char int) int { - weekday := int(t.Weekday()) - - if char == 'W' { - // Monday as the first day of the week - if weekday == 0 { - weekday = 6 - } else { - weekday -= 1 - } - } - - return (t.YearDay() + 6 - weekday) / 7 -} - -// Strftime formats time.Date according to the directives in the given format string. The directives begins with a percent (%) character. -func Strftime(t time.Time, f string) (string, error) { - var result []string - format := []rune(f) - - add := func(str string) { - result = append(result, str) - } - - for i := 0; i < len(format); i++ { - switch format[i] { - case '%': - if i < len(format)-1 { - switch format[i+1] { - case 'a': - add(shortDayNames[t.Weekday()]) - case 'A': - add(longDayNames[t.Weekday()]) - case 'b', 'h': - add(shortMonthNames[t.Month()]) - case 'B': - add(longMonthNames[t.Month()]) - case 'c': - add(t.Format("Mon Jan 2 15:04:05 2006")) - case 'C': - add(fmt.Sprintf("%02d", t.Year()/100)) - case 'd': - add(fmt.Sprintf("%02d", t.Day())) - case 'D', 'x': - add(fmt.Sprintf("%02d/%02d/%02d", t.Month(), t.Day(), t.Year()%100)) - case 'e': - add(fmt.Sprintf("%2d", t.Day())) - case 'f': - add(fmt.Sprintf("%06d", t.Nanosecond()/1000)) - case 'F': - add(fmt.Sprintf("%04d-%02d-%02d", t.Year(), t.Month(), t.Day())) - case 'H': - add(fmt.Sprintf("%02d", t.Hour())) - case 'I': - if t.Hour() == 0 { - add(fmt.Sprintf("%02d", 12)) - } else if t.Hour() > 12 { - add(fmt.Sprintf("%02d", t.Hour()-12)) - } else { - add(fmt.Sprintf("%02d", t.Hour())) - } - case 'j': - add(fmt.Sprintf("%03d", t.YearDay())) - case 'k': - add(fmt.Sprintf("%2d", t.Hour())) - case 'l': - if t.Hour() == 0 { - add(fmt.Sprintf("%2d", 12)) - } else if t.Hour() > 12 { - add(fmt.Sprintf("%2d", t.Hour()-12)) - } else { - add(fmt.Sprintf("%2d", t.Hour())) - } - case 'm': - add(fmt.Sprintf("%02d", t.Month())) - case 'M': - add(fmt.Sprintf("%02d", t.Minute())) - case 'n': - add("\n") - case 'p': - if t.Hour() < 12 { - add("AM") - } else { - add("PM") - } - case 'r': - s, _ := Strftime(t, "%I:%M:%S %p") - add(s) - case 'R': - add(fmt.Sprintf("%02d:%02d", t.Hour(), t.Minute())) - case 's': - add(fmt.Sprintf("%d", t.Unix())) - case 'S': - add(fmt.Sprintf("%02d", t.Second())) - case 't': - add("\t") - case 'T', 'X': - add(fmt.Sprintf("%02d:%02d:%02d", t.Hour(), t.Minute(), t.Second())) - case 'u': - w := t.Weekday() - if w == 0 { - w = 7 - } - add(fmt.Sprintf("%d", w)) - case 'U': - add(fmt.Sprintf("%02d", weekNumber(t, 'U'))) - case 'w': - add(fmt.Sprintf("%d", t.Weekday())) - case 'W': - add(fmt.Sprintf("%02d", weekNumber(t, 'W'))) - case 'y': - add(fmt.Sprintf("%02d", t.Year()%100)) - case 'Y': - add(fmt.Sprintf("%02d", t.Year())) - case 'z': - add(t.Format("-0700")) - case 'Z': - add(t.Format("MST")) - case '%': - add("%") - default: - return "", fmt.Errorf("invalid format code: %c", format[i+1]) - } - i += 1 - } - default: - add(string(format[i])) - } - } - - return strings.Join(result, ""), nil -} diff --git a/cockroach/patches/github.com/knz/strtime/strptime.c b/cockroach/patches/github.com/knz/strtime/strptime.c deleted file mode 100644 index 0c4c21b..0000000 --- a/cockroach/patches/github.com/knz/strtime/strptime.c +++ /dev/null @@ -1,744 +0,0 @@ -/*- - * Copyright (c) 2014 Gary Mills - * Copyright 2011, Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 1994 Powerdog Industries. All rights reserved. - * - * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``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 POWERDOG INDUSTRIES 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. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of Powerdog Industries. - */ - -// #include -// #ifndef lint -// #ifndef NOID -// static char copyright[] __unused = -// "@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; -// static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; -// #endif /* !defined NOID */ -// #endif /* not lint */ -// __FBSDID("$FreeBSD: stable/10/lib/libc/stdtime/strptime.c 273290 2014-10-19 21:16:24Z ache $"); - -#include "bsdshim.h" - -// #include "namespace.h" -// #include -#include -//#include -#include -#include -#include -// #include -// #include "un-namespace.h" -// #include "libc_private.h" -#include "timelocal.h" -// #include "tzfile.h" -#ifdef __sun -#include -#endif - -static char * _strptime(const char *, const char *, struct mytm *, int *, locale_t); - -#define asizeof(a) (sizeof(a) / sizeof((a)[0])) - -#define FLAG_NONE (1 << 0) -#define FLAG_YEAR (1 << 1) -#define FLAG_MONTH (1 << 2) -#define FLAG_YDAY (1 << 3) -#define FLAG_MDAY (1 << 4) -#define FLAG_WDAY (1 << 5) - -/* - * Calculate the week day of the first day of a year. Valid for - * the Gregorian calendar, which began Sept 14, 1752 in the UK - * and its colonies. Ref: - * http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week - */ - -static int -first_wday_of(int year) -{ - return (((2 * (3 - (year / 100) % 4)) + (year % 100) + - ((year % 100) / 4) + (isleap(year) ? 6 : 0) + 1) % 7); -} - -static char * -_strptime(const char *buf, const char *fmt, struct mytm *tm, int *GMTp, - locale_t locale) -{ - char c; - const char *ptr; - int day_offset = -1, wday_offset; - int week_offset; - int i, len; - int flags; - int Ealternative, Oalternative; - const struct lc_time_T *tptr = __get_current_time_locale(locale); - static int start_of_month[2][13] = { - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, - {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} - }; - - flags = FLAG_NONE; - - ptr = fmt; - while (*ptr != 0) { - c = *ptr++; - - if (c != '%') { - if (isspace_l((unsigned char)c, locale)) - while (*buf != 0 && - isspace_l((unsigned char)*buf, locale)) - buf++; - else if (c != *buf++) - return (NULL); - continue; - } - - Ealternative = 0; - Oalternative = 0; -label: - c = *ptr++; - switch (c) { - case '%': - if (*buf++ != '%') - return (NULL); - break; - - case '+': - buf = _strptime(buf, tptr->date_fmt, tm, GMTp, locale); - if (buf == NULL) - return (NULL); - flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; - break; - - case 'C': - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - /* XXX This will break for 3-digit centuries. */ - len = 2; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 19) - return (NULL); - - tm->tm_year = i * 100 - TM_YEAR_BASE; - flags |= FLAG_YEAR; - - break; - - case 'c': - buf = _strptime(buf, tptr->c_fmt, tm, GMTp, locale); - if (buf == NULL) - return (NULL); - flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; - break; - - case 'D': - buf = _strptime(buf, "%m/%d/%y", tm, GMTp, locale); - if (buf == NULL) - return (NULL); - flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; - break; - - case 'E': - // CockroachDB: unsupported - return (NULL); - if (Ealternative || Oalternative) - break; - Ealternative++; - goto label; - - case 'O': - // CockroachDB: unsupported - return (NULL); - if (Ealternative || Oalternative) - break; - Oalternative++; - goto label; - - case 'F': - buf = _strptime(buf, "%Y-%m-%d", tm, GMTp, locale); - if (buf == NULL) - return (NULL); - flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; - break; - - case 'R': - buf = _strptime(buf, "%H:%M", tm, GMTp, locale); - if (buf == NULL) - return (NULL); - break; - - case 'r': - buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp, locale); - if (buf == NULL) - return (NULL); - break; - - case 'T': - buf = _strptime(buf, "%H:%M:%S", tm, GMTp, locale); - if (buf == NULL) - return (NULL); - break; - - case 'X': - buf = _strptime(buf, tptr->X_fmt, tm, GMTp, locale); - if (buf == NULL) - return (NULL); - break; - - case 'x': - buf = _strptime(buf, tptr->x_fmt, tm, GMTp, locale); - if (buf == NULL) - return (NULL); - flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; - break; - - case 'j': - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = 3; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++){ - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 1 || i > 366) - return (NULL); - - tm->tm_yday = i - 1; - flags |= FLAG_YDAY; - - break; - - case 'f': - /* CockroachDB extension: microseconds */ - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = 6; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++){ - i *= 10; - i += *buf - '0'; - len--; - } - while (len) { - i *= 10; - len--; - } - - tm->tm_nsec = i * 1000; - - break; - - case 'M': - case 'S': - if (*buf == 0 || - isspace_l((unsigned char)*buf, locale)) - break; - - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = 2; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++){ - i *= 10; - i += *buf - '0'; - len--; - } - - if (c == 'M') { - if (i > 59) - return (NULL); - tm->tm_min = i; - } else { - if (i > 60) - return (NULL); - tm->tm_sec = i; - } - - break; - - case 'H': - case 'I': - case 'k': - case 'l': - /* - * Of these, %l is the only specifier explicitly - * documented as not being zero-padded. However, - * there is no harm in allowing zero-padding. - * - * XXX The %l specifier may gobble one too many - * digits if used incorrectly. - */ - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = 2; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (c == 'H' || c == 'k') { - if (i > 23) - return (NULL); - } else if (i > 12) - return (NULL); - - tm->tm_hour = i; - - break; - - case 'p': - /* - * XXX This is bogus if parsed before hour-related - * specifiers. - */ - len = strlen(tptr->am); - if (strncasecmp_l(buf, tptr->am, len, locale) == 0) { - if (tm->tm_hour > 12) - return (NULL); - if (tm->tm_hour == 12) - tm->tm_hour = 0; - buf += len; - break; - } - - len = strlen(tptr->pm); - if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) { - if (tm->tm_hour > 12) - return (NULL); - if (tm->tm_hour != 12) - tm->tm_hour += 12; - buf += len; - break; - } - - return (NULL); - - case 'A': - case 'a': - for (i = 0; i < asizeof(tptr->weekday); i++) { - len = strlen(tptr->weekday[i]); - if (strncasecmp_l(buf, tptr->weekday[i], - len, locale) == 0) - break; - len = strlen(tptr->wday[i]); - if (strncasecmp_l(buf, tptr->wday[i], - len, locale) == 0) - break; - } - if (i == asizeof(tptr->weekday)) - return (NULL); - - buf += len; - tm->tm_wday = i; - flags |= FLAG_WDAY; - break; - - case 'U': - case 'W': - /* - * XXX This is bogus, as we can not assume any valid - * information present in the tm structure at this - * point to calculate a real value, so just check the - * range for now. - */ - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = 2; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i > 53) - return (NULL); - - if (c == 'U') - day_offset = TM_SUNDAY; - else - day_offset = TM_MONDAY; - - - week_offset = i; - - break; - - case 'w': - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - i = *buf - '0'; - if (i > 6) - return (NULL); - - tm->tm_wday = i; - flags |= FLAG_WDAY; - - break; - - case 'u': - // CockroachDB extension of the FreeBSD code - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - i = *buf - '0'; - if (i < 1 || i > 7) - return (NULL); - if (i == 7) - i = 0; - - tm->tm_wday = i; - flags |= FLAG_WDAY; - - break; - - case 'e': - /* - * With %e format, our strftime(3) adds a blank space - * before single digits. - */ - if (*buf != 0 && - isspace_l((unsigned char)*buf, locale)) - buf++; - /* FALLTHROUGH */ - case 'd': - /* - * The %e specifier was once explicitly documented as - * not being zero-padded but was later changed to - * equivalent to %d. There is no harm in allowing - * such padding. - * - * XXX The %e specifier may gobble one too many - * digits if used incorrectly. - */ - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = 2; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i > 31) - return (NULL); - - tm->tm_mday = i; - flags |= FLAG_MDAY; - - break; - - case 'B': - case 'b': - case 'h': - for (i = 0; i < asizeof(tptr->month); i++) { - if (Oalternative) { - if (c == 'B') { - len = strlen(tptr->alt_month[i]); - if (strncasecmp_l(buf, - tptr->alt_month[i], - len, locale) == 0) - break; - } - } else { - len = strlen(tptr->month[i]); - if (strncasecmp_l(buf, tptr->month[i], - len, locale) == 0) - break; - } - } - /* - * Try the abbreviated month name if the full name - * wasn't found and Oalternative was not requested. - */ - if (i == asizeof(tptr->month) && !Oalternative) { - for (i = 0; i < asizeof(tptr->month); i++) { - len = strlen(tptr->mon[i]); - if (strncasecmp_l(buf, tptr->mon[i], - len, locale) == 0) - break; - } - } - if (i == asizeof(tptr->month)) - return (NULL); - - tm->tm_mon = i; - buf += len; - flags |= FLAG_MONTH; - - break; - - case 'm': - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = 2; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 1 || i > 12) - return (NULL); - - tm->tm_mon = i - 1; - flags |= FLAG_MONTH; - - break; - - case 's': - { - char *cp; - int sverrno; - long n; - time_t t; - - sverrno = errno; - errno = 0; - n = strtol_l(buf, &cp, 10, locale); - if (errno == ERANGE || (long)(t = n) != n) { - errno = sverrno; - return (NULL); - } - errno = sverrno; - buf = cp; - if (gmtime_r(&t, tm) == NULL) - return (NULL); - *GMTp = 1; - flags |= FLAG_YDAY | FLAG_WDAY | FLAG_MONTH | - FLAG_MDAY | FLAG_YEAR; - } - break; - - case 'Y': - case 'y': - if (*buf == 0 || - isspace_l((unsigned char)*buf, locale)) - break; - - if (!isdigit_l((unsigned char)*buf, locale)) - return (NULL); - - len = (c == 'Y') ? 4 : 2; - for (i = 0; len && *buf != 0 && - isdigit_l((unsigned char)*buf, locale); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (c == 'Y') - i -= TM_YEAR_BASE; - if (c == 'y' && i < 69) - i += 100; - if (i < 0) - return (NULL); - - tm->tm_year = i; - flags |= FLAG_YEAR; - - break; - - case 'Z': - { - const char *cp; - char *zonestr; - - for (cp = buf; *cp && - isupper_l((unsigned char)*cp, locale); ++cp) { - /*empty*/} - if (cp - buf) { - zonestr = alloca(cp - buf + 1); - strncpy(zonestr, buf, cp - buf); - zonestr[cp - buf] = '\0'; - //tzset(); - if (0 == strcmp(zonestr, "GMT") || - 0 == strcmp(zonestr, "UTC")) { - *GMTp = 1; - // } else if (0 == strcmp(zonestr, tzname[0])) { - // tm->tm_isdst = 0; - // } else if (0 == strcmp(zonestr, tzname[1])) { - // tm->tm_isdst = 1; - } else { - return (NULL); - } - buf += cp - buf; - } - } - break; - - case 'z': - { - int sign = 1; - - if (*buf != '+') { - if (*buf == '-') - sign = -1; - else - return (NULL); - } - - buf++; - i = 0; - for (len = 4; len > 0; len--) { - if (isdigit_l((unsigned char)*buf, locale)) { - i *= 10; - i += *buf - '0'; - buf++; - } else - return (NULL); - } - - tm->tm_hour -= sign * (i / 100); - tm->tm_min -= sign * (i % 100); - *GMTp = 1; - } - break; - - case 'n': - case 't': - while (isspace_l((unsigned char)*buf, locale)) - buf++; - break; - - default: - return (NULL); - } - } - - if (!(flags & FLAG_YDAY) && (flags & FLAG_YEAR)) { - if ((flags & (FLAG_MONTH | FLAG_MDAY)) == - (FLAG_MONTH | FLAG_MDAY)) { - tm->tm_yday = start_of_month[isleap(tm->tm_year + - TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1); - flags |= FLAG_YDAY; - } else if (day_offset != -1) { - /* Set the date to the first Sunday (or Monday) - * of the specified week of the year. - */ - if (!(flags & FLAG_WDAY)) { - tm->tm_wday = day_offset; - flags |= FLAG_WDAY; - } - tm->tm_yday = (7 - - first_wday_of(tm->tm_year + TM_YEAR_BASE) + - day_offset) % 7 + (week_offset - 1) * 7 + - tm->tm_wday - day_offset; - flags |= FLAG_YDAY; - } - } - - if ((flags & (FLAG_YEAR | FLAG_YDAY)) == (FLAG_YEAR | FLAG_YDAY)) { - if (!(flags & FLAG_MONTH)) { - i = 0; - while (tm->tm_yday >= - start_of_month[isleap(tm->tm_year + - TM_YEAR_BASE)][i]) - i++; - if (i > 12) { - i = 1; - tm->tm_yday -= - start_of_month[isleap(tm->tm_year + - TM_YEAR_BASE)][12]; - tm->tm_year++; - } - tm->tm_mon = i - 1; - flags |= FLAG_MONTH; - } - if (!(flags & FLAG_MDAY)) { - tm->tm_mday = tm->tm_yday - - start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)] - [tm->tm_mon] + 1; - flags |= FLAG_MDAY; - } - if (!(flags & FLAG_WDAY)) { - i = 0; - wday_offset = first_wday_of(tm->tm_year); - while (i++ <= tm->tm_yday) { - if (wday_offset++ >= 6) - wday_offset = 0; - } - tm->tm_wday = wday_offset; - flags |= FLAG_WDAY; - } - } - - return ((char *)buf); -} - -// char * -// strptime_l(const char * __restrict buf, const char * __restrict fmt, -// struct tm * __restrict tm, locale_t loc) -// { -// char *ret; -// int gmt; -// FIX_LOCALE(loc); -// -// gmt = 0; -// ret = _strptime(buf, fmt, tm, &gmt, loc); -// if (ret && gmt) { -// time_t t = timegm(tm); -// -// localtime_r(&t, tm); -// } -// -// return (ret); -// } -// -// char * -// strptime(const char * __restrict buf, const char * __restrict fmt, -// struct mytm * __restrict tm) -// { -// return strptime_l(buf, fmt, tm, 0); -// } -// -// - -int bsd_strptime(const char *s, const char *format, struct mytm *tm) -{ - int unused = 0; - return 0 != _strptime(s, format, tm, &unused, 0); -} diff --git a/cockroach/patches/github.com/knz/strtime/time.go b/cockroach/patches/github.com/knz/strtime/time.go deleted file mode 100644 index 82701c5..0000000 --- a/cockroach/patches/github.com/knz/strtime/time.go +++ /dev/null @@ -1,35 +0,0 @@ -package strtime - -import ( - "time" - "unsafe" - - "github.com/pkg/errors" -) - -// #include -// #include "bsdshim.h" -// extern int bsd_strptime(const char *s, const char *format, struct mytm *tm); -import "C" - -func Strptime(value string, layout string) (time.Time, error) { - cValue := C.CString(value) - defer C.free(unsafe.Pointer(cValue)) - cLayout := C.CString(layout) - defer C.free(unsafe.Pointer(cLayout)) - var cTime C.struct_mytm - - if r, err := C.bsd_strptime(cValue, cLayout, &cTime); r == 0 || err != nil { - return time.Time{}, errors.Wrapf(err, "could not parse %s as %s", value, layout) - } - return time.Date( - int(cTime.tm_year)+1900, - time.Month(cTime.tm_mon+1), - int(cTime.tm_mday), - int(cTime.tm_hour), - int(cTime.tm_min), - int(cTime.tm_sec), - int(cTime.tm_nsec), - time.FixedZone(C.GoString(cTime.tm_zone), int(cTime.tm_gmtoff)), - ), nil -} diff --git a/cockroach/patches/github.com/knz/strtime/time_nocgo.go b/cockroach/patches/github.com/knz/strtime/time_nocgo.go deleted file mode 100644 index fa63236..0000000 --- a/cockroach/patches/github.com/knz/strtime/time_nocgo.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !cgo - -package strtime - -import ( - "errors" - "time" -) - -func Strptime(value string, layout string) (time.Time, error) { - return time.Time{}, errors.New("cgo required") -} diff --git a/cockroach/patches/github.com/knz/strtime/timelocal.c b/cockroach/patches/github.com/knz/strtime/timelocal.c deleted file mode 100644 index fb220d7..0000000 --- a/cockroach/patches/github.com/knz/strtime/timelocal.c +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 2001 Alexey Zelkin - * Copyright (c) 1997 FreeBSD Inc. - * All rights reserved. - * - * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ - -// #include -// __FBSDID("$FreeBSD: stable/10/lib/libc/stdtime/timelocal.c 267798 2014-06-23 15:03:51Z pfg $"); -// -// #include -// -// #include "ldpart.h" -#include "timelocal.h" -// -// struct xlocale_time { -// struct xlocale_component header; -// char *buffer; -// struct lc_time_T locale; -// }; -// -// struct xlocale_time __xlocale_global_time; -// -// #define LCTIME_SIZE (sizeof(struct lc_time_T) / sizeof(char *)) - -const struct lc_time_T _C_time_locale = { - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }, { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, { - "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" - }, { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }, - - /* X_fmt */ - "%H:%M:%S", - - /* - * x_fmt - * Since the C language standard calls for - * "date, using locale's date format," anything goes. - * Using just numbers (as here) makes Quakers happier; - * it's also compatible with SVR4. - */ - "%m/%d/%y", - - /* - * c_fmt - */ - "%a %b %e %H:%M:%S %Y", - - /* am */ - "AM", - - /* pm */ - "PM", - - /* date_fmt */ - "%a %b %e %H:%M:%S %Z %Y", - - /* alt_month - * Standalone months forms for %OB - */ - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, - - /* md_order - * Month / day order in dates - */ - "md", - - /* ampm_fmt - * To determine 12-hour clock format time (empty, if N/A) - */ - "%I:%M:%S %p" -}; - -// static void destruct_time(void *v) -// { -// struct xlocale_time *l = v; -// if (l->buffer) -// free(l->buffer); -// free(l); -// } -// -// #include -// struct lc_time_T * -// __get_current_time_locale(locale_t loc) -// { -// return (loc->using_time_locale -// ? &((struct xlocale_time *)loc->components[XLC_TIME])->locale -// : (struct lc_time_T *)&_C_time_locale); -// } -// -// static int -// time_load_locale(struct xlocale_time *l, int *using_locale, const char *name) -// { -// struct lc_time_T *time_locale = &l->locale; -// return (__part_load_locale(name, using_locale, -// &l->buffer, "LC_TIME", -// LCTIME_SIZE, LCTIME_SIZE, -// (const char **)time_locale)); -// } -// int -// __time_load_locale(const char *name) -// { -// return time_load_locale(&__xlocale_global_time, -// &__xlocale_global_locale.using_time_locale, name); -// } -// void* __time_load(const char* name, locale_t loc) -// { -// struct xlocale_time *new = calloc(sizeof(struct xlocale_time), 1); -// new->header.header.destructor = destruct_time; -// if (time_load_locale(new, &loc->using_time_locale, name) == _LDP_ERROR) -// { -// xlocale_release(new); -// return NULL; -// } -// return new; -// } -// -// diff --git a/cockroach/patches/github.com/knz/strtime/timelocal.h b/cockroach/patches/github.com/knz/strtime/timelocal.h deleted file mode 100644 index 7f69bbb..0000000 --- a/cockroach/patches/github.com/knz/strtime/timelocal.h +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 1997-2002 FreeBSD Project. - * All rights reserved. - * - * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD: stable/10/lib/libc/stdtime/timelocal.h 227753 2011-11-20 14:45:42Z theraven $ - */ - -#ifndef _TIMELOCAL_H_ -#define _TIMELOCAL_H_ -// #include "xlocale_private.h" -// #include -#include "bsdshim.h" - -/* - * Private header file for the strftime and strptime localization - * stuff. - */ -struct lc_time_T { - const char *mon[12]; - const char *month[12]; - const char *wday[7]; - const char *weekday[7]; - const char *X_fmt; - const char *x_fmt; - const char *c_fmt; - const char *am; - const char *pm; - const char *date_fmt; - const char *alt_month[12]; - const char *md_order; - const char *ampm_fmt; -}; - -extern const struct lc_time_T _C_time_locale; - -#define __get_current_time_locale(X) (&_C_time_locale) -// int __time_load_locale(const char *); - -#endif /* !_TIMELOCAL_H_ */ diff --git a/cockroach/patches/stderr_redirect_illumos.go b/cockroach/patches/stderr_redirect_illumos.go deleted file mode 100644 index f6ab3fd..0000000 --- a/cockroach/patches/stderr_redirect_illumos.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2020 The Cockroach Authors. -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -// +build illumos - -package log - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// dupFD is used to initialize OrigStderr (see stderr_redirect.go). -func dupFD(fd uintptr) (uintptr, error) { - // Warning: failing to set FD_CLOEXEC causes the duplicated file descriptor - // to leak into subprocesses created by exec.Command. If the file descriptor - // is a pipe, these subprocesses will hold the pipe open (i.e., prevent - // EOF), potentially beyond the lifetime of this process. - // - // This can break go test's timeouts. go test usually spawns a test process - // with its stdin and stderr streams hooked up to pipes; if the test process - // times out, it sends a SIGKILL and attempts to read stdin and stderr to - // completion. If the test process has itself spawned long-lived - // subprocesses that hold references to the stdin or stderr pipes, go test - // will hang until the subprocesses exit, rather defeating the purpose of - // a timeout. - nfd, err := unix.FcntlInt(fd, unix.F_DUPFD_CLOEXEC, 0) - if err != nil { - return 0, err - } - return uintptr(nfd), nil -} - -// redirectStderr is used to redirect internal writes to fd 2 to the -// specified file. This is needed to ensure that harcoded writes to fd -// 2 by e.g. the Go runtime are redirected to a log file of our -// choosing. -// -// We also override os.Stderr for those other parts of Go which use -// that and not fd 2 directly. -func redirectStderr(f *os.File) error { - if err := unix.Dup2(int(f.Fd()), unix.Stderr); err != nil { - return err - } - os.Stderr = f - return nil -} diff --git a/cockroach/patches/sysutil_illumos.go b/cockroach/patches/sysutil_illumos.go deleted file mode 100644 index 6c89a75..0000000 --- a/cockroach/patches/sysutil_illumos.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2018 The Cockroach Authors. -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -// +build illumos - -//lint:file-ignore Unconvert (redundant conversions are necessary for cross-platform compatibility) - -package sysutil - -import ( - "fmt" - "syscall" - - "golang.org/x/sys/unix" -) - -// ProcessIdentity returns a string describing the user and group that this -// process is running as. -func ProcessIdentity() string { - return fmt.Sprintf("uid %d euid %d gid %d egid %d", - unix.Getuid(), unix.Geteuid(), unix.Getgid(), unix.Getegid()) -} - - -// IsCrossDeviceLinkErrno checks whether the given error object (as -// extracted from an *os.LinkError) is a cross-device link/rename -// error. -func IsCrossDeviceLinkErrno(errno error) bool { - return errno == syscall.EXDEV -}