This simply compiles, passes tests, but is only able open a handle.
This commit does not contain the full bindings.
---
Makefile.am | 2 +
configure.ac | 32 ++++
generator/GoLang.ml | 150 ++++++++++++++++++
generator/GoLang.mli | 19 +++
generator/Makefile.am | 2 +
generator/generator.ml | 3 +
golang/Makefile.am | 58 +++++++
golang/config-test.go | 34 ++++
golang/examples/LICENSE-FOR-EXAMPLES | 38 +++++
golang/examples/Makefile.am | 21 +++
golang/run-tests.sh | 24 +++
golang/src/libguestfs.org/libnbd/.gitignore | 1 +
.../libnbd/libnbd_010_load_test.go | 25 +++
.../libnbd/libnbd_100_handle_test.go | 29 ++++
run.in | 17 ++
15 files changed, 455 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index bf2db68..a9f13ca 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,6 +43,8 @@ SUBDIRS = \
ocaml \
ocaml/examples \
ocaml/tests \
+ golang \
+ golang/examples \
interop \
fuzzing \
bash \
diff --git a/configure.ac b/configure.ac
index 9fd284b..36617fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -403,6 +403,34 @@ AS_IF([test "x$enable_python" != "xno"],[
AM_CONDITIONAL([HAVE_PYTHON],
[test "x$PYTHON" != "xno" && test
"x$have_python_module" = "x1" ])
+dnl Golang.
+AC_ARG_ENABLE([golang],
+ AS_HELP_STRING([--disable-golang], [disable Go language bindings]),
+ [],
+ [enable_golang=yes])
+AS_IF([test "x$enable_golang" != "xno"],[
+ AC_CHECK_PROG([GOLANG],[go],[go],[no])
+ AS_IF([test "x$GOLANG" != "xno"],[
+ AC_MSG_CHECKING([if $GOLANG is usable])
+ AS_IF([$GOLANG run $srcdir/golang/config-test.go 2>&AS_MESSAGE_LOG_FD],[
+ AC_MSG_RESULT([yes])
+
+ # Substitute some golang environment.
+ GOOS=`$GOLANG env GOOS`
+ GOARCH=`$GOLANG env GOARCH`
+ GOROOT=`$GOLANG env GOROOT`
+ AC_SUBST([GOOS])
+ AC_SUBST([GOARCH])
+ AC_SUBST([GOROOT])
+ ],[
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([golang ($GOLANG) is installed but not usable])
+ GOLANG=no
+ ])
+ ])
+],[GOLANG=no])
+AM_CONDITIONAL([HAVE_GOLANG],[test "x$GOLANG" != "xno"])
+
dnl Produce output files.
AC_CONFIG_HEADERS([config.h])
@@ -423,6 +451,8 @@ AC_CONFIG_FILES([Makefile
fuse/Makefile
fuzzing/Makefile
generator/Makefile
+ golang/Makefile
+ golang/examples/Makefile
include/Makefile
interop/Makefile
lib/Makefile
@@ -472,6 +502,8 @@ feature "Bash tab completion .................... " \
echo
echo "Language bindings:"
echo
+feature "Go ..................................... " \
+ test "x$HAVE_GOLANG_TRUE" = "x"
feature "OCaml .................................. " \
test "x$HAVE_OCAML_TRUE" = "x"
feature "Python ................................. " \
diff --git a/generator/GoLang.ml b/generator/GoLang.ml
new file mode 100644
index 0000000..1b8f20b
--- /dev/null
+++ b/generator/GoLang.ml
@@ -0,0 +1,150 @@
+(* nbd client library in userspace: generator
+ * Copyright (C) 2013-2020 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *)
+
+(* Go language bindings. *)
+
+open Printf
+
+open API
+open Utils
+
+let generate_golang_libnbd_go () =
+ generate_header CStyle;
+
+ pr "\
+package libnbd
+
+/*
+#cgo CFLAGS:
+#cgo LDFLAGS: -lnbd
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include \"libnbd.h\"
+
+struct error {
+ char *error;
+ int errnum;
+};
+
+static void
+save_error (struct error *err)
+{
+ err->error = strdup (nbd_get_error ());
+ err->errnum = nbd_get_errno ();
+}
+
+static void
+free_error (struct error *err)
+{
+ free (err->error);
+}
+
+static struct nbd_handle *
+_nbd_create_wrapper (struct error *err)
+{
+ struct nbd_handle *r;
+
+ r = nbd_create ();
+ if (r == NULL)
+ save_error (err);
+ return r;
+}
+
+// There must be no blank line between end comment and import!
+//
https://github.com/golang/go/issues/9733
+*/
+import \"C\"
+
+import (
+ \"fmt\"
+ \"runtime\"
+ \"syscall\"
+)
+
+/* Handle. */
+type Libnbd struct {
+ h *C.struct_nbd_handle
+}
+
+/* Convert handle to string (just for debugging). */
+func (h *Libnbd) String () string {
+ return \"&Libnbd{}\"
+}
+
+/* All functions (except Close) return ([result,] LibnbdError). */
+type LibnbdError struct {
+ Op string // operation which failed
+ Errmsg string // string (nbd_get_error)
+ Errno syscall.Errno // errno (nbd_get_errno)
+}
+
+func (e *LibnbdError) String() string {
+ if e.Errno != 0 {
+ return fmt.Sprintf (\"%%s: %%s\", e.Op, e.Errmsg);
+ } else {
+ return fmt.Sprintf (\"%%s: %%s: %%s\", e.Op, e.Errmsg, e.Errno);
+ }
+}
+
+/* Implement the error interface */
+func (e *LibnbdError) Error() string {
+ return e.String()
+}
+
+func get_error (op string, c_err C.struct_error) *LibnbdError {
+ errmsg := C.GoString (c_err.error)
+ errno := syscall.Errno (c_err.errnum)
+ return &LibnbdError{ Op : op, Errmsg : errmsg, Errno : errno }
+}
+
+func closed_handle_error (op string) *LibnbdError {
+ return &LibnbdError{ Op : op, Errmsg : \"handle is closed\",
+ Errno : syscall.Errno (0) }
+}
+
+/* Create a new handle. */
+func Create () (*Libnbd, error) {
+ c_err := C.struct_error{}
+ c_h := C._nbd_create_wrapper (&c_err)
+ if c_h == nil {
+ err := get_error (\"create\", c_err)
+ C.free_error (&c_err)
+ return nil, err
+ }
+ h := &Libnbd{h : c_h}
+ // Finalizers aren't guaranteed to run, but try having one anyway ...
+ runtime.SetFinalizer (h, (*Libnbd).Close)
+ return h, nil
+}
+
+/* Close the handle. */
+func (h *Libnbd) Close () *LibnbdError {
+ if h.h == nil {
+ return closed_handle_error (\"close\")
+ }
+ C.nbd_close (h.h)
+ h.h = nil
+ return nil
+}
+
+";
diff --git a/generator/GoLang.mli b/generator/GoLang.mli
new file mode 100644
index 0000000..b8ec1b5
--- /dev/null
+++ b/generator/GoLang.mli
@@ -0,0 +1,19 @@
+(* nbd client library in userspace: generator
+ * Copyright (C) 2013-2020 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *)
+
+val generate_golang_libnbd_go : unit -> unit
diff --git a/generator/Makefile.am b/generator/Makefile.am
index e499ca8..0389d70 100644
--- a/generator/Makefile.am
+++ b/generator/Makefile.am
@@ -57,6 +57,8 @@ sources = \
Python.ml \
OCaml.mli \
OCaml.ml \
+ GoLang.mli \
+ GoLang.ml \
generator.ml \
$(NULL)
diff --git a/generator/generator.ml b/generator/generator.ml
index 1c97492..817c032 100755
--- a/generator/generator.ml
+++ b/generator/generator.ml
@@ -55,3 +55,6 @@ let () =
output_to "ocaml/NBD.mli" OCaml.generate_ocaml_nbd_mli;
output_to "ocaml/NBD.ml" OCaml.generate_ocaml_nbd_ml;
output_to "ocaml/nbd-c.c" OCaml.generate_ocaml_nbd_c;
+
+ output_to "golang/src/libguestfs.org/libnbd/libnbd.go"
+ GoLang.generate_golang_libnbd_go;
diff --git a/golang/Makefile.am b/golang/Makefile.am
new file mode 100644
index 0000000..47234ff
--- /dev/null
+++ b/golang/Makefile.am
@@ -0,0 +1,58 @@
+# nbd client library in userspace
+# Copyright (C) 2013-2020 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+include $(top_srcdir)/subdir-rules.mk
+
+#
http://golang.org/doc/code.html#Organization
+pkg =
libguestfs.org/libnbd
+
+source_files = \
+ src/$(pkg)/libnbd.go \
+ src/$(pkg)/libnbd_*_test.go
+
+generator_built = \
+ $(source_files)
+
+EXTRA_DIST = \
+ src/$(pkg)/.gitignore \
+ $(generator_built) \
+ config-test.go \
+ run-tests.sh
+
+if HAVE_GOLANG
+
+golangpkgdir = $(GOROOT)/pkg/$(GOOS)_$(GOARCH)/$(pkg)
+golangsrcdir = $(GOROOT)/src/pkg/$(pkg)
+
+golangpkg_DATA = \
+ pkg/$(GOOS)_$(GOARCH)/$(pkg).a
+
+pkg/$(GOOS)_$(GOARCH)/$(pkg).a: src/$(pkg)/libnbd.go
+ $(top_builddir)/run $(GOLANG) install $(pkg)
+
+golangsrc_DATA = $(source_files)
+
+TESTS_ENVIRONMENT = pkg=$(pkg) LIBNBD_DEBUG=1
+LOG_COMPILER = $(top_builddir)/run
+TESTS = run-tests.sh
+
+endif
+
+CLEANFILES += src/$(pkg)/*~
+
+clean-local:
+ rm -rf pkg
diff --git a/golang/config-test.go b/golang/config-test.go
new file mode 100644
index 0000000..e104c71
--- /dev/null
+++ b/golang/config-test.go
@@ -0,0 +1,34 @@
+/* libnbd Go configuration test
+ * Copyright (C) 2013-2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This is called from ./configure to check that golang works
+ * and is above the minimum required version.
+ */
+
+package main
+
+func main() {
+ /* XXX Check for minimum runtime.Version() >= "go1.1.1"
+ * Unfortunately go version numbers are not easy to parse.
+ * They have the 3 formats "goX.Y.Z", "release.rN" or
+ * "weekly.YYYY-MM-DD". The latter two formats are mostly
+ * useless, and the first one is hard to parse. See also
+ * cmpGoVersion in
+ *
http://web.archive.org/web/20130402235148/http://golang.org/src/cmd/go/ge...
+ */
+}
diff --git a/golang/examples/LICENSE-FOR-EXAMPLES b/golang/examples/LICENSE-FOR-EXAMPLES
new file mode 100644
index 0000000..4986466
--- /dev/null
+++ b/golang/examples/LICENSE-FOR-EXAMPLES
@@ -0,0 +1,38 @@
+The files in the golang/examples/ directory are licensed under this
+very permissive BSD license. This means that you can copy, use, adapt
+and modify them without any significant restrictions. You can also
+combine them with proprietary code or include them in code that is
+distributed under other open source licenses.
+
+----------------------------------------------------------------------
+
+libnbd examples
+Copyright (C) 2013-2020 Red Hat Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+* Neither the name of Red Hat 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 RED HAT 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 RED HAT 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/golang/examples/Makefile.am b/golang/examples/Makefile.am
new file mode 100644
index 0000000..90498ab
--- /dev/null
+++ b/golang/examples/Makefile.am
@@ -0,0 +1,21 @@
+# nbd client library in userspace
+# Copyright (C) 2013-2020 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+include $(top_srcdir)/subdir-rules.mk
+
+EXTRA_DIST = \
+ LICENSE-FOR-EXAMPLES
diff --git a/golang/run-tests.sh b/golang/run-tests.sh
new file mode 100755
index 0000000..a155819
--- /dev/null
+++ b/golang/run-tests.sh
@@ -0,0 +1,24 @@
+#!/bin/sh -
+# nbd client library in userspace
+# Copyright (C) 2013-2020 Red Hat Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+set -e
+
+# The -count=1 parameter is the "idiomatic way to bypass test caching".
+#
https://golang.org/doc/go1.10#test
+# The -v option enables verbose output.
+$GOLANG test -count=1 -v $pkg
diff --git
a/golang/src/libguestfs.org/libnbd/.gitignore
b/golang/src/libguestfs.org/libnbd/.gitignore
new file mode 100644
index 0000000..a2ce7eb
--- /dev/null
+++
b/golang/src/libguestfs.org/libnbd/.gitignore
@@ -0,0 +1 @@
+/libnbd.go
diff --git
a/golang/src/libguestfs.org/libnbd/libnbd_010_load_test.go
b/golang/src/libguestfs.org/libnbd/libnbd_010_load_test.go
new file mode 100644
index 0000000..24cfe66
--- /dev/null
+++
b/golang/src/libguestfs.org/libnbd/libnbd_010_load_test.go
@@ -0,0 +1,25 @@
+/* libnbd golang tests
+ * Copyright (C) 2013-2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package libnbd
+
+import "testing"
+
+func Test010Load (t *testing.T) {
+ /* Nothing - just test that the library can be linked to. */
+}
diff --git
a/golang/src/libguestfs.org/libnbd/libnbd_100_handle_test.go
b/golang/src/libguestfs.org/libnbd/libnbd_100_handle_test.go
new file mode 100644
index 0000000..a3d933d
--- /dev/null
+++
b/golang/src/libguestfs.org/libnbd/libnbd_100_handle_test.go
@@ -0,0 +1,29 @@
+/* libnbd golang tests
+ * Copyright (C) 2013-2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package libnbd
+
+import "testing"
+
+func Test100Handle (t *testing.T) {
+ h, err := Create ()
+ if err != nil {
+ t.Errorf ("could not create handle: %s", err)
+ }
+ h.Close ()
+}
diff --git a/run.in b/run.in
index 0411c85..9ffece5 100755
--- a/run.in
+++ b/run.in
@@ -78,6 +78,23 @@ export PYTHONPATH
prepend CAML_LD_LIBRARY_PATH "$b/ocaml"
export CAML_LD_LIBRARY_PATH
+# For golang.
+export GOLANG="@GOLANG@"
+prepend GOPATH "$b/golang"
+export GOPATH
+if [ -z "$CGO_CFLAGS" ]; then
+ CGO_CFLAGS="-I$s/include -I$b"
+else
+ CGO_CFLAGS="$CGO_CFLAGS -I$s/include -I$b"
+fi
+export CGO_CFLAGS
+if [ -z "$CGO_LDFLAGS" ]; then
+ CGO_LDFLAGS="-L$b/lib/.libs"
+else
+ CGO_LDFLAGS="$CGO_LDFLAGS -L$b/lib/.libs"
+fi
+export CGO_LDFLAGS
+
# This is a cheap way to find some use-after-free and uninitialized
# read problems when using glibc.
export MALLOC_CHECK_=1
--
2.25.0