summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2016-01-19 22:28:51 -0800
committerAlex Crichton <alex@alexcrichton.com>2016-01-19 22:28:51 -0800
commit7ce8eba6f2fb0d3215cda1fca60aa658c321f3da (patch)
treecd252357664bcb628967114c84c39e861470da35
parent2575794dd7a4905d4e58bdb926a8bf1963ea3af3 (diff)
parentbb6f198a201af6a078067d170642cbe77069393d (diff)
downloadrust-libc-7ce8eba6f2fb0d3215cda1fca60aa658c321f3da.tar.gz
Merge pull request #139 from alexcrichton/freebsd
FreeBSD and OpenBSD CI
-rw-r--r--.travis.yml6
-rw-r--r--ci/README.md159
-rw-r--r--ci/Vagrantfile38
-rw-r--r--ci/run-qemu.sh38
-rw-r--r--ci/run-travis.sh92
-rw-r--r--ci/run.sh6
-rw-r--r--libc-test/Cargo.lock12
-rw-r--r--libc-test/build-generated.rs15
-rw-r--r--libc-test/build.rs17
-rw-r--r--libc-test/generate-files/Cargo.lock108
-rw-r--r--libc-test/generate-files/Cargo.toml16
-rw-r--r--libc-test/run-generated-Cargo.toml19
-rw-r--r--libc-test/src/main-generated.rs9
-rw-r--r--src/unix/bsd/apple/mod.rs27
-rw-r--r--src/unix/bsd/freebsdlike/dragonfly.rs5
-rw-r--r--src/unix/bsd/freebsdlike/freebsd.rs3
-rw-r--r--src/unix/bsd/freebsdlike/mod.rs23
-rw-r--r--src/unix/bsd/mod.rs42
-rw-r--r--src/unix/bsd/openbsdlike/mod.rs14
19 files changed, 546 insertions, 103 deletions
diff --git a/.travis.yml b/.travis.yml
index 333fb22562..fad3d5d73d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -48,6 +48,12 @@ matrix:
- os: linux
env: TARGET=x86_64-rumprun-netbsd DOCKER=alexcrichton/rust-libc-rumprun:2015-11-27
rust: nightly-2015-09-27
+ - os: linux
+ env: TARGET=x86_64-unknown-freebsd QEMU=freebsd.qcow2
+ rust: nightly
+ - os: linux
+ env: TARGET=x86_64-unknown-openbsd QEMU=openbsd.qcow2
+ rust: nightly
notifications:
email:
on_success: never
diff --git a/ci/README.md b/ci/README.md
index 5b4c681c25..13c7c8da52 100644
--- a/ci/README.md
+++ b/ci/README.md
@@ -8,11 +8,6 @@ this project.
First up, let's talk about the files in this directory:
-* `msys2.ps1` - a PowerShell script which is used to install MSYS2 on the
- AppVeyor bots. As of this writing MSYS2 isn't installed by default, and this
- script will install the right version/arch of msys2 in preparation of using
- the contained C compiler to compile C shims.
-
* `run-travis.sh` - a shell script run by all Travis builders, this is
responsible for setting up the rest of the environment such as installing new
packages, downloading Rust target libraries, etc.
@@ -30,6 +25,11 @@ First up, let's talk about the files in this directory:
* `landing-page-*.html` - used by `dox.sh` to generate a landing page for all
architectures' documentation.
+* `run-qemu.sh` - see discussion about QEMU below
+
+* `mips`, `rumprun` - instructions to build the docker image for each respective
+ CI target
+
# CI Systems
Currently this repository leverages a combination of Travis CI and AppVeyor for
@@ -38,11 +38,14 @@ running tests. The triples tested are:
* AppVeyor
* `{i686,x86_64}-pc-windows-{msvc,gnu}`
* Travis
- * `{i686,x86_64,mips,aarch64}-unknown-linux-gnu`
- * `x86_64-unknown-linux-musl`
- * `arm-unknown-linux-gnueabihf`
- * `arm-linux-androideabi`
- * `{i686,x86_64}-apple-{darwin,ios}`
+ * `{i686,x86_64,mips,aarch64}-unknown-linux-gnu`
+ * `x86_64-unknown-linux-musl`
+ * `arm-unknown-linux-gnueabihf`
+ * `arm-linux-androideabi`
+ * `{i686,x86_64}-apple-{darwin,ios}`
+ * `x86_64-rumprun-netbsd`
+ * `x86_64-unknown-freebsd`
+ * `x86_64-unknown-openbsd`
The Windows triples are all pretty standard, they just set up their environment
then run tests, no need for downloading any extra target libs (we just download
@@ -54,15 +57,147 @@ The remaining architectures look like:
* Android runs in a [docker image][android-docker] with an emulator, the NDK,
and the SDK already set up. The entire build happens within the docker image.
-* The MIPS, ARM, and AArch64 builds all use QEMU to run the generated binary to
- actually verify the tests pass.
+* The MIPS, ARM, and AArch64 builds all use the QEMU userspace emulator to run
+ the generated binary to actually verify the tests pass.
* The MUSL build just has to download a MUSL compiler and target libraries and
then otherwise runs tests normally.
* iOS builds need an extra linker flag currently, but beyond that they're built
as standard as everything else.
+* The rumprun target builds an entire kernel from the test suite and then runs
+ it inside QEMU using the serial console to test whether it succeeded or
+ failed.
+* The BSD builds, currently OpenBSD and FreeBSD, use QEMU to boot up a system
+ and compile/run tests. More information on that below.
[android-docker]: https://github.com/rust-lang/rust-buildbot/blob/master/slaves/android/Dockerfile
+## QEMU
+
+Lots of the architectures tested here use QEMU in the tests, so it's worth going
+over all the crazy capabilities QEMU has and the various flavors in which we use
+it!
+
+First up, QEMU has userspace emulation where it doesn't boot a full kernel, it
+just runs a binary from another architecture (using the `qemu-<arch>` wrappers).
+We provide it the runtime path for the dynamically loaded system libraries,
+however. This strategy is used for all Linux architectures that aren't intel.
+Note that one downside of this QEMU system is that threads are barely
+implemented, so we're careful to not spawn many threads.
+
+For the rumprun target the only output is a kernel image, so we just use that
+plus the `rumpbake` command to create a full kernel image which is then run from
+within QEMU.
+
+Finally, the fun part, the BSDs. Quite a few hoops are jumped through to get CI
+working for these platforms, but the gist of it looks like:
+
+* Cross compiling from Linux to any of the BSDs seems to be quite non-standard.
+ We may be able to get it working but it might be difficult at that point to
+ ensure that the libc definitions align with what you'd get on the BSD itself.
+ As a result, we try to do compiles within the BSD distro.
+* On Travis we can't run a VM-in-a-VM, so we resort to userspace emulation
+ (QEMU).
+* Unfortunately on Travis we also can't use KVM, so the emulation is super slow.
+
+With all that in mind, the way BSD is tested looks like:
+
+1. Download a pre-prepared image for the OS being tested.
+2. Generate the tests for the OS being tested. This involves running the `ctest`
+ library over libc to generate a Rust file and a C file which will then be
+ compiled into the final test.
+3. Generate a disk image which will later be mounted by the OS being tested.
+ This image is mostly just the libc directory, but some modifications are made
+ to compile the generated files from step 2.
+4. The kernel is booted in QEMU, and it is configured to detect the libc-test
+ image being available, run the test script, and then shut down afterwards.
+5. Look for whether the tests passed in the serial console output of the kernel.
+
+There's some pretty specific instructions for setting up each image (detailed
+below), but the main gist of this is that we must avoid a vanilla `cargo run`
+inside of the `libc-test` directory (which is what it's intended for) because
+that would compile `syntex_syntax`, a large library, with userspace emulation.
+This invariably times out on Travis, so we can't do that.
+
+Once all those hoops are jumped through, however, we can be happy that we're
+testing almost everything!
+
+Below are some details of how to set up the initial OS images which are
+downloaded. Each image must be enabled have input/output over the serial
+console, log in automatically at the serial console, detect if a second drive in
+QEMU is available, and if so mount it, run a script (it'll specifically be
+`run-qemu.sh` in this folder which is copied into the generated image talked
+about above), and then shut down.
+
+### QEMU setup - FreeBSD
+
+1. Download CD installer (most minimal is fine)
+2. `qemu-img create -f qcow2 foo.qcow2 2G`
+3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
+4. run installer
+5. `echo 'console="comconsole"' >> /boot/loader.conf`
+6. `echo 'autoboot_delay="0"' >> /boot/loader.conf`
+7. look at /etc/ttys, see what getty argument is for ttyu0
+8. edit /etc/gettytab, look for ttyu0 argument, prepend `:al=root` to line
+ beneath
+
+(note that the current image has a `freebsd` user, but this isn't really
+necessary)
+
+Once that's done, arrange for this script to run at login:
+
+```
+#!/bin/sh
+
+sudo kldload ext2fs
+[ -e /dev/vtbd1 ] || exit 0
+sudo mount -t ext2fs /dev/vtbd1 /mnt
+sh /mnt/run.sh /mnt
+sudo poweroff
+```
+
+Helpful links
+
+* https://en.wikibooks.org/wiki/QEMU/Images
+* https://blog.nekoconeko.nl/blog/2015/06/04/creating-an-openstack-freebsd-image.html
+* https://www.freebsd.org/doc/handbook/serialconsole-setup.html
+
+
+### QEMU setup - OpenBSD
+
+1. Download CD installer
+2. `qemu-img create -f qcow2 foo.qcow2 2G`
+3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
+4. run installer
+5. `echo 'set tty com0' >> /etc/boot.conf`
+6. `echo 'boot' >> /etc/boot.conf`
+7. Modify /etc/ttys, change the `tty00` at the end from 'unknown off' to
+ 'vt220 on secure'
+8. Modify same line in /etc/ttys to have `"/root/foo.sh"` as the shell
+9. Add this script to `/root/foo.sh`
+
+```
+#!/bin/sh
+exec 1>/dev/tty00
+exec 2>&1
+
+if mount -t ext2fs /dev/sd1c /mnt; then
+ sh /mnt/run.sh /mnt
+ shutdown -ph now
+fi
+
+# limited shell...
+exec /bin/sh < /dev/tty00
+```
+
+10. `chmod +x /root/foo.sh`
+
+Helpful links:
+
+* https://en.wikibooks.org/wiki/QEMU/Images
+* http://www.openbsd.org/faq/faq7.html#SerCon
+
+# Questions?
+
Hopefully that's at least somewhat of an introduction to everything going on
here, and feel free to ping @alexcrichton with questions!
diff --git a/ci/Vagrantfile b/ci/Vagrantfile
deleted file mode 100644
index 70cfcf3284..0000000000
--- a/ci/Vagrantfile
+++ /dev/null
@@ -1,38 +0,0 @@
-# A vagrant configuration file for running tests on BSD-like machines
-#
-# Note that this was originally intended to later be used to run tests on
-# Travis, but it didn't work out. Regardless this has stuck around! You can run
-# tests in FreeBSD via:
-#
-# git clone https://github.com/alexcrichton/libc
-# cd libc/ci
-# vagrant up freebsd
-# vagrant ssh freebsd
-# ...
-# cd /vagrant/libc-test
-# cargo run
-#
-# And "that's it"! You look up instructions on Vagrant's website for how to
-# install vagrant.
-
-Vagrant.configure(2) do |config|
- # For a complete reference, please see the online documentation at
- # https://docs.vagrantup.com.
-
- config.vm.synced_folder "..", "/vagrant"
-
- config.vm.define :freebsd do |bsd|
- bsd.vm.box = "arkadi/freebsd-10.1-amd64"
- bsd.vm.provision :shell, inline: 'yes | sudo pkg install rust cargo'
- bsd.vm.provider "virtualbox" do |vb|
- vb.memory = "2048"
- end
- end
-
- config.vm.define :openbsd do |bsd|
- bsd.vm.box = "bodgit/openbsd-5.7-amd64"
- bsd.vm.provider "virtualbox" do |vb|
- vb.memory = "2048"
- end
- end
-end
diff --git a/ci/run-qemu.sh b/ci/run-qemu.sh
new file mode 100644
index 0000000000..78da64aa8f
--- /dev/null
+++ b/ci/run-qemu.sh
@@ -0,0 +1,38 @@
+# Initial script which is run inside of all qemu images. The first argument to
+# this script (as arranged by the qemu image itself) is the path to where the
+# libc crate is mounted.
+#
+# For qemu images we currently need to install Rust manually as this wasn't done
+# by the initial run-travis.sh script
+#
+# FIXME: feels like run-travis.sh should be responsible for downloading the
+# compiler.
+
+set -ex
+
+ROOT=$1
+cp -r $ROOT/libc /tmp/libc
+cd /tmp/libc
+
+TARGET=$(cat $ROOT/TARGET)
+
+case $TARGET in
+ *-freebsd)
+ sudo pkg install -y rust cargo
+ ;;
+
+ *-openbsd)
+ pkg_add rust curl gcc-4.8.4p4
+ curl https://static.rust-lang.org/cargo-dist/2015-04-02/cargo-nightly-x86_64-unknown-openbsd.tar.gz | \
+ tar xzf - -C /tmp
+ export PATH=$PATH:/tmp/cargo-nightly-x86_64-unknown-openbsd/cargo/bin
+ export CC=egcc
+ ;;
+
+ *)
+ echo "Unknown target: $TARGET"
+ exit 1
+ ;;
+esac
+
+exec sh ci/run.sh $TARGET
diff --git a/ci/run-travis.sh b/ci/run-travis.sh
index 75ce8ba1d8..4e9d92f60f 100644
--- a/ci/run-travis.sh
+++ b/ci/run-travis.sh
@@ -1,6 +1,8 @@
# Entry point for all travis builds, this will set up the Travis environment by
# downloading any dependencies. It will then execute the `run.sh` script to
# build and execute all tests.
+#
+# For a full description of how all tests are run, see `ci/README.md`
set -ex
@@ -26,9 +28,84 @@ install() {
fi
}
+# If we're going to run tests inside of a qemu image, then we don't need any of
+# the scripts below. Instead, download the image, prepare a filesystem which has
+# the current state of this repository, and then run the image.
+#
+# It's assume that all images, when run with two disks, will run the `run.sh`
+# script from the second which we place inside.
+if [ "$QEMU" != "" ]; then
+ # Acquire QEMU and the base OS image
+ install qemu-kvm
+ tmpdir=/tmp/qemu-img-creation
+ mkdir -p $tmpdir
+ if [ ! -f $tmpdir/$QEMU ]; then
+ curl https://people.mozilla.org/~acrichton/libc-test/qemu/$QEMU.gz | \
+ gunzip -d > $tmpdir/$QEMU
+ fi
+
+ # Generate all.{c,rs} on the host which will be compiled inside QEMU. Do this
+ # here because compiling syntex_syntax in QEMU would time out basically
+ # everywhere.
+ rm -rf $tmpdir/generated
+ mkdir -p $tmpdir/generated
+ CARGO_TARGET_DIR=$tmpdir/generated-build \
+ cargo build --manifest-path libc-test/generate-files/Cargo.toml
+ (cd libc-test && TARGET=$TARGET OUT_DIR=$tmpdir/generated SKIP_COMPILE=1 \
+ $tmpdir/generated-build/debug/generate-files)
+
+ # Create a mount a fresh new filesystem image that we'll later pass to QEMU,
+ # this contains the checkout of libc and will be able to run all tests
+ rm -f $tmpdir/libc-test.img
+ dd if=/dev/null of=$tmpdir/libc-test.img bs=1M seek=5
+ mkfs.ext2 -F $tmpdir/libc-test.img
+ rm -rf $tmpdir/mount
+ mkdir $tmpdir/mount
+ sudo mount -t ext2 -o loop $tmpdir/libc-test.img $tmpdir/mount
+
+ # Copy this folder into the mounted image, the `run.sh` entry point, and
+ # overwrite the standard libc-test Cargo.toml with the overlay one which will
+ # assume the all.{c,rs} test files have already been generated
+ sudo mkdir $tmpdir/mount/libc
+ sudo cp -r * $tmpdir/mount/libc/
+ sudo cp ci/run-qemu.sh $tmpdir/mount/run.sh
+ echo $TARGET | sudo tee -a $tmpdir/mount/TARGET
+ sudo cp $tmpdir/generated/* $tmpdir/mount/libc/libc-test
+ sudo cp libc-test/run-generated-Cargo.toml $tmpdir/mount/libc/libc-test/Cargo.toml
+
+ sudo umount $tmpdir/mount
+
+ # If we can use kvm, prefer that, otherwise just fall back to user-space
+ # emulation.
+ if kvm-ok; then
+ program="sudo kvm"
+ else
+ program=qemu-system-x86_64
+ fi
+
+ # Pass -snapshot to prevent tampering with the disk images, this helps when
+ # running this script in development. The two drives are then passed next,
+ # first is the OS and second is the one we just made. Next the network is
+ # configured to work (I'm not entirely sure how), and then finally we turn off
+ # graphics and redirect the serial console output to out.log.
+ $program \
+ -m 1024 \
+ -snapshot \
+ -drive if=virtio,file=$tmpdir/$QEMU \
+ -drive if=virtio,file=$tmpdir/libc-test.img \
+ -net nic,model=virtio \
+ -net user \
+ -nographic \
+ -vga none 2>&1 | tee out.log
+ exec grep "^PASSED .* tests" out.log
+fi
+
mkdir -p .cargo
cp ci/cargo-config .cargo/config
+# Next up we need to install the standard library for the version of Rust that
+# we're testing. Get fancy targets from the EXTRA_TARGETS URL and otherwise get
+# all others from the official distribution.
if [ "$TRAVIS" = "true" ]; then
case "$TARGET" in
*-apple-ios | *-rumprun-*)
@@ -53,10 +130,14 @@ if [ "$TRAVIS" = "true" ]; then
esac
fi
-# Pull a pre-built docker image for testing android, then run tests entirely
-# within that image. Note that this is using the same rustc installation that
-# travis has (sharing it via `-v`) and otherwise the tests run entirely within
-# the container.
+# If we're testing with a docker image, then run tests entirely within that
+# image. Note that this is using the same rustc installation that travis has
+# (sharing it via `-v`) and otherwise the tests run entirely within the
+# container.
+#
+# For the docker build we mount the entire current directory at /checkout, set
+# up some environment variables to let it run, and then run the standard run.sh
+# script.
if [ "$DOCKER" != "" ]; then
args=""
@@ -81,6 +162,8 @@ if [ "$DOCKER" != "" ]; then
ci/run.sh $TARGET
fi
+# If we're not running docker or qemu, then we may still need some packages
+# and/or tools with various configurations here and there.
case "$TARGET" in
x86_64-unknown-linux-musl)
install musl-tools
@@ -111,6 +194,7 @@ case "$TARGET" in
esac
+# Finally, if we've gotten this far, actually run the tests.
sh ci/run.sh $TARGET
if [ "$TARGET" = "x86_64-unknown-linux-gnu" ] && \
diff --git a/ci/run.sh b/ci/run.sh
index 14985be912..706bf7a1d1 100644
--- a/ci/run.sh
+++ b/ci/run.sh
@@ -47,11 +47,7 @@ case "$TARGET" in
grep "^PASSED .* tests" /tmp/out
;;
- *-apple-ios)
- libc-test/target/$TARGET/debug/libc-test
- ;;
-
*)
- cargo run --manifest-path libc-test/Cargo.toml --target $TARGET
+ libc-test/target/$TARGET/debug/libc-test
;;
esac
diff --git a/libc-test/Cargo.lock b/libc-test/Cargo.lock
index f4678de593..2b4a4dbeb4 100644
--- a/libc-test/Cargo.lock
+++ b/libc-test/Cargo.lock
@@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ctest"
version = "0.1.0"
-source = "git+https://github.com/alexcrichton/ctest#4e3a8027b540b79769fcd3945a6de9f1e5edf8e0"
+source = "git+https://github.com/alexcrichton/ctest#7703b51086cce2d9a703b103d0695b36653b8cab"
dependencies = [
"gcc 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -54,19 +54,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.2.4"
[[package]]
name = "libc"
version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -81,7 +81,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/libc-test/build-generated.rs b/libc-test/build-generated.rs
new file mode 100644
index 0000000000..41b562723f
--- /dev/null
+++ b/libc-test/build-generated.rs
@@ -0,0 +1,15 @@
+// This build script is distinct from the standard build.rs as it is only used
+// for the BSDs which run a stripped down version. The `all.c` file is assumed
+// to have been already generated for this build script.
+
+extern crate gcc;
+
+fn main() {
+ gcc::Config::new()
+ .file("all.c")
+ .flag("-Wall")
+ .flag("-Wextra")
+ .flag("-Werror")
+ .flag("-Wno-type-limits")
+ .compile("liball.a");
+}
diff --git a/libc-test/build.rs b/libc-test/build.rs
index 1a071e68ae..d703e336e3 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -101,10 +101,11 @@ fn main() {
} else if !windows {
cfg.header("glob.h");
cfg.header("ifaddrs.h");
- if !openbsd {
+ cfg.header("sys/statvfs.h");
+
+ if !openbsd && !freebsd {
cfg.header("sys/quota.h");
}
- cfg.header("sys/statvfs.h");
if !musl {
cfg.header("sys/sysctl.h");
@@ -159,6 +160,7 @@ fn main() {
if freebsd {
cfg.header("pthread_np.h");
cfg.header("sched.h");
+ cfg.header("ufs/ufs/quota.h");
}
if netbsd {
@@ -364,6 +366,11 @@ fn main() {
// [3]: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/sys/eventfd.h;h=6295f32e937e779e74318eb9d3bdbe76aef8a8f3;hb=4e42b5b8f89f0e288e68be7ad70f9525aebc2cff#l34
"eventfd" if linux => true,
+ // The `uname` funcion in freebsd is now an inline wrapper that
+ // delegates to another, but the symbol still exists, so don't check
+ // the symbol.
+ "uname" if freebsd => true,
+
_ => false,
}
});
@@ -406,5 +413,9 @@ fn main() {
}
});
- cfg.generate("../src/lib.rs", "all.rs");
+ if env::var("SKIP_COMPILE").is_ok() {
+ cfg.generate_files("../src/lib.rs", "all.rs");
+ } else {
+ cfg.generate("../src/lib.rs", "all.rs");
+ }
}
diff --git a/libc-test/generate-files/Cargo.lock b/libc-test/generate-files/Cargo.lock
new file mode 100644
index 0000000000..b7a16f752c
--- /dev/null
+++ b/libc-test/generate-files/Cargo.lock
@@ -0,0 +1,108 @@
+[root]
+name = "generate-files"
+version = "0.1.0"
+dependencies = [
+ "ctest 0.1.0 (git+https://github.com/alexcrichton/ctest)",
+]
+
+[[package]]
+name = "advapi32-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "bitflags"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "ctest"
+version = "0.1.0"
+source = "git+https://github.com/alexcrichton/ctest#7703b51086cce2d9a703b103d0695b36653b8cab"
+dependencies = [
+ "gcc 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syntex_syntax 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "gcc"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "kernel32-sys"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "libc"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libc"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "log"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-serialize"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "syntex_syntax"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "term"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-build"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
diff --git a/libc-test/generate-files/Cargo.toml b/libc-test/generate-files/Cargo.toml
new file mode 100644
index 0000000000..9615a63d49
--- /dev/null
+++ b/libc-test/generate-files/Cargo.toml
@@ -0,0 +1,16 @@
+# Cargo.toml which is used to just generate the all.{c,rs} files used to test
+# some platforms. These files are then combined with the overlay files commented
+# in the above directory as well to assemble a libc-test project which will
+# compile/run all tests.
+
+[package]
+name = "generate-files"
+version = "0.1.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+
+[[bin]]
+name = "generate-files"
+path = "../build.rs"
+
+[dependencies]
+ctest = { git = "https://github.com/alexcrichton/ctest" }
diff --git a/libc-test/run-generated-Cargo.toml b/libc-test/run-generated-Cargo.toml
new file mode 100644
index 0000000000..64862a51a1
--- /dev/null
+++ b/libc-test/run-generated-Cargo.toml
@@ -0,0 +1,19 @@
+# Note that this Cargo.toml is not used by default, it is only intended to be
+# used on the BSDs where it is too expensive to compile syntex_syntax in a QEMU
+# emulator without KVM. Scripts will move this file into place on the BSD CI.
+
+[package]
+name = "libc-test"
+version = "0.1.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+build = "build-generated.rs"
+
+[dependencies]
+libc = { path = ".." }
+
+[[bin]]
+name = "libc-test"
+path = "src/main-generated.rs"
+
+[build-dependencies]
+gcc = "0.3"
diff --git a/libc-test/src/main-generated.rs b/libc-test/src/main-generated.rs
new file mode 100644
index 0000000000..608fe4ead9
--- /dev/null
+++ b/libc-test/src/main-generated.rs
@@ -0,0 +1,9 @@
+// Note that this main file is meant to mirror `main.rs` but is only used on the
+// BSDs where the generated location of `all.rs` is slightly different
+
+#![allow(bad_style, improper_ctypes)]
+extern crate libc;
+
+use libc::*;
+
+include!("../all.rs");
diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs
index 406acd1011..e8f97e4ede 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -242,6 +242,14 @@ s! {
pub c_ispeed: ::speed_t,
pub c_ospeed: ::speed_t,
}
+
+ pub struct flock {
+ pub l_start: ::off_t,
+ pub l_len: ::off_t,
+ pub l_pid: ::pid_t,
+ pub l_type: ::c_short,
+ pub l_whence: ::c_short,
+ }
}
pub const EXIT_FAILURE: ::c_int = 1;
@@ -305,6 +313,9 @@ pub const F_LOCK: ::c_int = 1;
pub const F_TEST: ::c_int = 3;
pub const F_TLOCK: ::c_int = 2;
pub const F_ULOCK: ::c_int = 0;
+pub const F_GETLK: ::c_int = 7;
+pub const F_SETLK: ::c_int = 8;
+pub const F_SETLKW: ::c_int = 9;
pub const SIGHUP: ::c_int = 1;
pub const SIGINT: ::c_int = 2;
pub const SIGQUIT: ::c_int = 3;
@@ -803,6 +814,19 @@ pub const NOTE_VM_PRESSURE_SUDDEN_TERMINATE: ::uint32_t = 0x20000000;
pub const NOTE_VM_PRESSURE_TERMINATE: ::uint32_t = 0x40000000;
pub const NOTE_PCTRLMASK: ::uint32_t = 0xfff00000;
+pub const NL0: ::c_int = 0x00000000;
+pub const NL1: ::c_int = 0x00000100;
+pub const TAB0: ::c_int = 0x00000000;
+pub const TAB1: ::c_int = 0x00000400;
+pub const TAB2: ::c_int = 0x00000800;
+pub const CR0: ::c_int = 0x00000000;
+pub const CR1: ::c_int = 0x00001000;
+pub const CR2: ::c_int = 0x00002000;
+pub const CR3: ::c_int = 0x00003000;
+pub const FF0: ::c_int = 0x00000000;
+pub const FF1: ::c_int = 0x00004000;
+pub const BS0: ::c_int = 0x00000000;
+pub const BS1: ::c_int = 0x00008000;
pub const TAB3: ::c_int = 0x00000004;
pub const VT0: ::c_int = 0x00000000;
pub const VT1: ::c_int = 0x00010000;
@@ -811,6 +835,9 @@ pub const CRTSCTS: ::tcflag_t = 0x00030000;
pub const NI_MAXHOST: ::socklen_t = 1025;
+pub const Q_GETQUOTA: ::c_int = 0x300;
+pub const Q_SETQUOTA: ::c_int = 0x400;
+
extern {
pub fn getnameinfo(sa: *const ::sockaddr,
salen: ::socklen_t,
diff --git a/src/unix/bsd/freebsdlike/dragonfly.rs b/src/unix/bsd/freebsdlike/dragonfly.rs
index 6b874f0b1f..0cdc128f49 100644
--- a/src/unix/bsd/freebsdlike/dragonfly.rs
+++ b/src/unix/bsd/freebsdlike/dragonfly.rs
@@ -1,8 +1,13 @@
+pub type fsblkcnt_t = ::c_uint;
+pub type fsfilcnt_t = ::c_uint;
+
pub const PTHREAD_STACK_MIN: ::size_t = 1024;
pub const KERN_PROC_PATHNAME: ::c_int = 9;
pub const SIGSTKSZ: ::size_t = 40960;
pub const MADV_INVAL: ::c_int = 10;
+pub const HW_AVAILCPU: ::c_int = 25;
+
extern {
pub fn __dfly_error() -> *const ::c_int;
}
diff --git a/src/unix/bsd/freebsdlike/freebsd.rs b/src/unix/bsd/freebsdlike/freebsd.rs
index 9e6d985f9d..ab2d6fc6e1 100644
--- a/src/unix/bsd/freebsdlike/freebsd.rs
+++ b/src/unix/bsd/freebsdlike/freebsd.rs
@@ -1,3 +1,6 @@
+pub type fsblkcnt_t = ::uint64_t;
+pub type fsfilcnt_t = ::uint64_t;
+
pub const PTHREAD_STACK_MIN: ::size_t = 2048;
pub const KERN_PROC_PATHNAME: ::c_int = 12;
pub const SIGSTKSZ: ::size_t = 34816;
diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index d41829ceb2..d7c99ee61f 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -12,8 +12,6 @@ pub type pthread_mutexattr_t = *mut ::c_void;
pub type pthread_cond_t = *mut ::c_void;
pub type pthread_rwlock_t = *mut ::c_void;
pub type pthread_key_t = ::c_int;
-pub type fsblkcnt_t = ::c_uint;
-pub type fsfilcnt_t = ::c_uint;
pub type tcflag_t = ::c_uint;
pub type speed_t = ::c_uint;
@@ -24,7 +22,7 @@ s! {
pub d_fileno: u32,
pub d_reclen: u16,
pub d_type: u8,
- pub d_namelen: u8,
+ pub d_namlen: u8,
pub d_name: [::c_char; 256],
}
@@ -85,7 +83,7 @@ s! {
}
pub struct stack_t {
- pub ss_sp: *mut ::c_void,
+ pub ss_sp: *mut ::c_char,
pub ss_size: ::size_t,
pub ss_flags: ::c_int,
}
@@ -132,6 +130,15 @@ s! {
pub c_ispeed: ::speed_t,
pub c_ospeed: ::speed_t,
}
+
+ pub struct flock {
+ pub l_start: ::off_t,
+ pub l_len: ::off_t,
+ pub l_pid: ::pid_t,
+ pub l_type: ::c_short,
+ pub l_whence: ::c_short,
+ pub l_sysid: ::c_int,
+ }
}
pub const EXIT_FAILURE: ::c_int = 1;
@@ -194,6 +201,9 @@ pub const F_TEST: ::c_int = 3;
pub const F_TLOCK: ::c_int = 2;
pub const F_ULOCK: ::c_int = 0;
pub const F_DUPFD_CLOEXEC: ::c_int = 17;
+pub const F_GETLK: ::c_int = 11;
+pub const F_SETLK: ::c_int = 12;
+pub const F_SETLKW: ::c_int = 13;
pub const SIGHUP: ::c_int = 1;
pub const SIGINT: ::c_int = 2;
pub const SIGQUIT: ::c_int = 3;
@@ -555,10 +565,11 @@ pub const FD_SETSIZE: usize = 1024;
pub const ST_NOSUID: ::c_ulong = 2;
-pub const HW_AVAILCPU: ::c_int = 25;
-
pub const NI_MAXHOST: ::size_t = 1025;
+pub const Q_GETQUOTA: ::c_int = 0x700;
+pub const Q_SETQUOTA: ::c_int = 0x800;
+
extern {
pub fn getnameinfo(sa: *const ::sockaddr,
salen: ::socklen_t,
diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs
index 704a7bdb62..027033bcec 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
pub type c_char = i8;
pub type wchar_t = i32;
pub type off_t = i64;
@@ -60,6 +62,11 @@ s! {
}
pub struct fd_set {
+ #[cfg(all(target_pointer_width = "64",
+ target_os = "freebsd"))]
+ fds_bits: [i64; FD_SETSIZE / 64],
+ #[cfg(not(all(target_pointer_width = "64",
+ target_os = "freebsd")))]
fds_bits: [i32; FD_SETSIZE / 32],
}
@@ -95,14 +102,6 @@ s! {
pub msg_flags: ::c_int,
}
- pub struct flock {
- pub l_start: ::off_t,
- pub l_len: ::off_t,
- pub l_pid: ::pid_t,
- pub l_type: ::c_short,
- pub l_whence: ::c_short,
- }
-
pub struct fsid_t {
__fsid_val: [::int32_t; 2],
}
@@ -185,10 +184,7 @@ pub const O_FSYNC: ::c_int = 0x80;
pub const O_NDELAY: ::c_int = 0x4;
pub const O_NOFOLLOW: ::c_int = 0x100;
-pub const F_GETLK: ::c_int = 7;
pub const F_GETOWN: ::c_int = 5;
-pub const F_SETLK: ::c_int = 8;
-pub const F_SETLKW: ::c_int = 9;
pub const F_SETOWN: ::c_int = 6;
pub const MNT_FORCE: ::c_int = 0x80000;
@@ -196,8 +192,6 @@ pub const MNT_FORCE: ::c_int = 0x80000;
pub const Q_SYNC: ::c_int = 0x600;
pub const Q_QUOTAON: ::c_int = 0x100;
pub const Q_QUOTAOFF: ::c_int = 0x200;
-pub const Q_GETQUOTA: ::c_int = 0x300;
-pub const Q_SETQUOTA: ::c_int = 0x400;
pub const TCIOFF: ::c_int = 3;
pub const TCION: ::c_int = 4;
@@ -209,19 +203,6 @@ pub const TCIOFLUSH: ::c_int = 3;
pub const TCSANOW: ::c_int = 0;
pub const TCSADRAIN: ::c_int = 1;
pub const TCSAFLUSH: ::c_int = 2;
-pub const NL0: ::c_int = 0x00000000;
-pub const NL1: ::c_int = 0x00000100;
-pub const TAB0: ::c_int = 0x00000000;
-pub const TAB1: ::c_int = 0x00000400;
-pub const TAB2: ::c_int = 0x00000800;
-pub const CR0: ::c_int = 0x00000000;
-pub const CR1: ::c_int = 0x00001000;
-pub const CR2: ::c_int = 0x00002000;
-pub const CR3: ::c_int = 0x00003000;
-pub const FF0: ::c_int = 0x00000000;
-pub const FF1: ::c_int = 0x00004000;
-pub const BS0: ::c_int = 0x00000000;
-pub const BS1: ::c_int = 0x00008000;
pub const VEOF: usize = 0;
pub const VEOL: usize = 1;
pub const VEOL2: usize = 2;
@@ -284,19 +265,22 @@ pub const WNOHANG: ::c_int = 1;
f! {
pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
+ let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
let fd = fd as usize;
- (*set).fds_bits[fd / 32] &= !(1 << (fd % 32));
+ (*set).fds_bits[fd / bits] &= !(1 << (fd % bits));
return
}
pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool {
+ let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
let fd = fd as usize;
- return ((*set).fds_bits[fd / 32] & (1 << (fd % 32))) != 0
+ return ((*set).fds_bits[fd / bits] & (1 << (fd % bits))) != 0
}
pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
+ let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
let fd = fd as usize;
- (*set).fds_bits[fd / 32] |= 1 << (fd % 32);
+ (*set).fds_bits[fd / bits] |= 1 << (fd % bits);
return
}
diff --git a/src/unix/bsd/openbsdlike/mod.rs b/src/unix/bsd/openbsdlike/mod.rs
index 72d681c86d..b1bf2cafe1 100644
--- a/src/unix/bsd/openbsdlike/mod.rs
+++ b/src/unix/bsd/openbsdlike/mod.rs
@@ -41,6 +41,14 @@ s! {
pub c_ispeed: ::c_int,
pub c_ospeed: ::c_int,
}
+
+ pub struct flock {
+ pub l_start: ::off_t,
+ pub l_len: ::off_t,
+ pub l_pid: ::pid_t,
+ pub l_type: ::c_short,
+ pub l_whence: ::c_short,
+ }
}
pub const EXIT_FAILURE : ::c_int = 1;
@@ -100,6 +108,9 @@ pub const F_LOCK : ::c_int = 1;
pub const F_TEST : ::c_int = 3;
pub const F_TLOCK : ::c_int = 2;
pub const F_ULOCK : ::c_int = 0;
+pub const F_GETLK: ::c_int = 7;
+pub const F_SETLK: ::c_int = 8;
+pub const F_SETLKW: ::c_int = 9;
pub const SIGHUP : ::c_int = 1;
pub const SIGINT : ::c_int = 2;
pub const SIGQUIT : ::c_int = 3;
@@ -354,6 +365,9 @@ pub const _SC_FSYNC : ::c_int = 29;
pub const KERN_PROC_ARGV: ::c_int = 1;
+pub const Q_GETQUOTA: ::c_int = 0x300;
+pub const Q_SETQUOTA: ::c_int = 0x400;
+
extern {
pub fn mincore(addr: *mut ::c_void, len: ::size_t,
vec: *mut ::c_char) -> ::c_int;