summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.config38
-rw-r--r--.my_build_settings6
-rw-r--r--Makefile88
-rw-r--r--kernel/Makefile6
-rw-r--r--kernel/kernel.mak49
-rw-r--r--kernel/testcases/Makefile60
-rw-r--r--kernel/testcases/dma/Makefile18
-rw-r--r--kernel/testcases/dma/kernel_space/Makefile4
-rw-r--r--kernel/testcases/dma/kernel_space/dma_test_lib.c477
-rw-r--r--kernel/testcases/dma/kernel_space/dma_test_lib.h105
-rw-r--r--kernel/testcases/dma/kernel_space/dma_test_module.c2587
-rw-r--r--kernel/testcases/dma/user-space/Makefile26
-rw-r--r--kernel/testcases/dma/user-space/dma.c156
-rwxr-xr-xkernel/testcases/dma/user-space/dma_test_all.sh81
-rw-r--r--ltp_framework/ChangeLog1
-rwxr-xr-xltp_framework/IDcheck.sh189
-rwxr-xr-xltp_framework/bin/ltp-panbin0 -> 61493 bytes
-rw-r--r--ltp_framework/include/Makefile45
-rw-r--r--ltp_framework/include/cleanup.c45
-rw-r--r--ltp_framework/include/compiler.h18
-rw-r--r--ltp_framework/include/config.h293
-rw-r--r--ltp_framework/include/config.h.default251
-rw-r--r--ltp_framework/include/config.h.in292
-rw-r--r--ltp_framework/include/dataascii.h65
-rw-r--r--ltp_framework/include/databin.h44
-rw-r--r--ltp_framework/include/file_lock.h46
-rw-r--r--ltp_framework/include/forker.h63
-rw-r--r--ltp_framework/include/libtestsuite.h20
-rw-r--r--ltp_framework/include/ltp_signal.h109
-rw-r--r--ltp_framework/include/mk/automake.mk117
-rw-r--r--ltp_framework/include/mk/config.mk82
-rw-r--r--ltp_framework/include/mk/config.mk.default76
-rw-r--r--ltp_framework/include/mk/config.mk.in82
-rw-r--r--ltp_framework/include/mk/env_post.mk104
-rw-r--r--ltp_framework/include/mk/env_pre.mk144
-rw-r--r--ltp_framework/include/mk/features.mk55
-rw-r--r--ltp_framework/include/mk/features.mk.default55
-rw-r--r--ltp_framework/include/mk/features.mk.in55
-rw-r--r--ltp_framework/include/mk/functions.mk76
-rw-r--r--ltp_framework/include/mk/generic_leaf_target.inc106
-rw-r--r--ltp_framework/include/mk/generic_leaf_target.mk24
-rw-r--r--ltp_framework/include/mk/generic_trunk_target.inc97
-rw-r--r--ltp_framework/include/mk/generic_trunk_target.mk24
-rw-r--r--ltp_framework/include/mk/gitignore.mk51
-rw-r--r--ltp_framework/include/mk/lib.mk64
-rw-r--r--ltp_framework/include/mk/man.mk37
-rw-r--r--ltp_framework/include/mk/testcases.mk55
-rw-r--r--ltp_framework/include/open_flags.h73
-rw-r--r--ltp_framework/include/pattern.h90
-rw-r--r--ltp_framework/include/random_range.h45
-rw-r--r--ltp_framework/include/rmobj.h12
-rw-r--r--ltp_framework/include/safe_macros.h139
-rw-r--r--ltp_framework/include/search_path.h36
-rw-r--r--ltp_framework/include/stamp-h11
-rw-r--r--ltp_framework/include/str_to_bytes.h39
-rw-r--r--ltp_framework/include/string_to_tokens.h48
-rw-r--r--ltp_framework/include/swaponoff.h18
-rw-r--r--ltp_framework/include/system_specific_hugepages_info.h30
-rw-r--r--ltp_framework/include/system_specific_process_info.h29
-rw-r--r--ltp_framework/include/test.h253
-rw-r--r--ltp_framework/include/tlibio.h161
-rw-r--r--ltp_framework/include/usctest.h323
-rw-r--r--ltp_framework/include/write_log.h170
-rw-r--r--ltp_framework/lib/Makefile45
-rw-r--r--ltp_framework/lib/cloner.c111
-rw-r--r--ltp_framework/lib/dataascii.c217
-rw-r--r--ltp_framework/lib/databin.c297
-rw-r--r--ltp_framework/lib/datapid.c373
-rw-r--r--ltp_framework/lib/file_lock.c208
-rw-r--r--ltp_framework/lib/forker.c281
-rw-r--r--ltp_framework/lib/get_high_address.c40
-rw-r--r--ltp_framework/lib/get_path.c100
-rw-r--r--ltp_framework/lib/libltp.abin0 -> 264326 bytes
-rw-r--r--ltp_framework/lib/libtestsuite.c164
-rw-r--r--ltp_framework/lib/ltp.pc10
-rw-r--r--ltp_framework/lib/ltp.pc.in10
-rw-r--r--ltp_framework/lib/mount_utils.c213
-rw-r--r--ltp_framework/lib/open_flags.c330
-rw-r--r--ltp_framework/lib/parse_opts.c879
-rw-r--r--ltp_framework/lib/pattern.c168
-rw-r--r--ltp_framework/lib/random_range.c917
-rw-r--r--ltp_framework/lib/rmobj.c211
-rw-r--r--ltp_framework/lib/safe_macros.c312
-rw-r--r--ltp_framework/lib/search_path.c277
-rw-r--r--ltp_framework/lib/self_exec.c218
-rw-r--r--ltp_framework/lib/str_to_bytes.c210
-rw-r--r--ltp_framework/lib/string_to_tokens.c109
-rw-r--r--ltp_framework/lib/system_specific_hugepages_info.c93
-rw-r--r--ltp_framework/lib/system_specific_process_info.c88
-rw-r--r--ltp_framework/lib/tlibio.c2084
-rw-r--r--ltp_framework/lib/tst_cwd_has_free.c22
-rw-r--r--ltp_framework/lib/tst_is_cwd.c52
-rw-r--r--ltp_framework/lib/tst_kvercmp.c68
-rw-r--r--ltp_framework/lib/tst_res.c812
-rw-r--r--ltp_framework/lib/tst_sig.c271
-rw-r--r--ltp_framework/lib/tst_tmpdir.c405
-rw-r--r--ltp_framework/lib/write_log.c503
-rwxr-xr-xltp_framework/runltp1005
-rwxr-xr-xltp_framework/ver_linux89
99 files changed, 19145 insertions, 0 deletions
diff --git a/.config b/.config
new file mode 100644
index 0000000..ffce626
--- /dev/null
+++ b/.config
@@ -0,0 +1,38 @@
+#
+# Automatically generated make config: don't edit
+# Wed Mar 28 23:45:55 2012
+#
+#CONFIG_LTP=y
+CONFIG_LTP_STE_TESTCASES=y
+# CONFIG_LTP_ALSA_I2C is not set
+# CONFIG_LTP_SENSORS_AB8500 is not set
+CONFIG_LTP_DMA=y
+# CONFIG_LTP_METATEST is not set
+# CONFIG_LTP_EXAMPLE is not set
+# CONFIG_LTP_RTC is not set
+# CONFIG_LTP_BLUETOOTH is not set
+# CONFIG_LTP_GPIO is not set
+# CONFIG_LTP_MCDE is not set
+# CONFIG_LTP_B2R2 is not set
+# CONFIG_LTP_UART is not set
+# CONFIG_LTP_SSP is not set
+# CONFIG_LTP_SHRM is not set
+# CONFIG_LTP_I2C is not set
+# CONFIG_LTP_DLP is not set
+# CONFIG_LTP_MMC is not set
+# CONFIG_LTP_EMMC_FILESYSTEM_MMC_VALIDATION_LTP is not set
+# CONFIG_LTP_MSP is not set
+# CONFIG_LTP_ALS is not set
+# CONFIG_LTP_LSM303DLH is not set
+# CONFIG_LTP_LPS001WP is not set
+# CONFIG_LTP_L3G4200D is not set
+# CONFIG_LTP_PROXIMITY is not set
+# CONFIG_LTP_POWER is not set
+# CONFIG_LTP_TEE is not set
+# CONFIG_LTP_TIMER is not set
+# CONFIG_LTP_HSI is not set
+# CONFIG_LTP_LED is not set
+# CONFIG_LTP_VIBRATOR is not set
+# CONFIG_LTP_L2CACHE is not set
+# CONFIG_LTP_STE_SYSTEMTEST_TESTCASES is not set
+# CONFIG_LTP_COMMUNITY_TESTCASES is not set
diff --git a/.my_build_settings b/.my_build_settings
new file mode 100644
index 0000000..0ff1a12
--- /dev/null
+++ b/.my_build_settings
@@ -0,0 +1,6 @@
+#ARCH=arm
+#CROSS_PREFIX=arm-linux-gnueabi
+#CROSS_COMPILE=arm-linux-gnueabi-
+#KERNEL_OUTPUT=/home/kalle/projects/snowball/kernel
+#DESTDIR=/home/kalle/projects/snowball/my_install
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..96bbb9b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,88 @@
+# Standalone build file for LTP
+
+# Edit .my_build_settings to set proper values for these variables
+# ARCH /* arm */
+# CROSS_PREFIX /* arm-none-linux-gnueabi */
+# CROSS_COMPILE /* arm-none-linux-gnueabi- */
+# KERNEL_OUTPUT /* kernel build directory */
+# DESTDIR /* installation output directory */
+-include .my_build_settings
+ARCH ?= arm
+KERNEL_OUTPUT ?= /lib/modules/$(shell uname -r)/build
+DESTDIR ?= $(CURDIR)/../ste_test_install_dir
+
+# Default config file
+LTP_CONFIG ?= defconfig
+# Number of parallell make jobs
+JOBS ?= 1
+# ------------
+
+# TODO: remove this export and pass command line variables to make instead.
+# Setting CC is required in order to build userspace parts of kernel tests.
+export CC=$(CROSS_COMPILE)gcc
+# --------------------
+
+# The following variables should have ok default values
+# ----------------
+
+# tempdir can't be changed easily because it is hardcoded in the Makefiles
+TEMPDIR := $(CURDIR)/tempdir
+
+# Local script directory
+SCRIPT_DIR := $(CURDIR)/scripts
+BUILD_PREFIX := i386-pc-linux-gnu
+HOST_PREFIX := $(CROSS_PREFIX)
+TARGET_PREFIX := $(CROSS_PREFIX)
+# ----------------
+
+# Pass variables to make
+MAKEFLAGS :=
+MAKEFLAGS += CROSS_COMPILE=$(CROSS_COMPILE)
+MAKEFLAGS += CROSS_PREFIX=$(CROSS_PREFIX)
+MAKEFLAGS += ARCH=$(ARCH)
+MAKEFLAGS += KERNEL_OUTPUT=$(KERNEL_OUTPUT)
+MAKEFLAGS += KERNELDIR=$(KERNEL_OUTPUT)
+MAKEFLAGS += DESTDIR=$(DESTDIR)
+MAKEFLAGS += TEMPDIR=$(TEMPDIR)
+MAKEFLAGS += HOST_PREFIX=$(HOST_PREFIX)
+MAKEFLAGS += TARGET_PREFIX=$(TARGET_PREFIX)
+MAKEFLAGS += CONFIG_LTP_STE_TESTCASES=$(CONFIG_LTP_STE_TESTCASES)
+MAKEFLAGS += JOBS=$(JOBS)
+MAKEFLAGS += SCRIPT_DIR=$(SCRIPT_DIR)
+
+# TODO: Replace this export and pass value via make
+export LTP_TEST_CONFIG_FILE=$(CURDIR)/.config
+.PHONY help:
+help: FORCE
+ @echo "Please read the Makefile for a list of make targets."
+ @echo "Overview of build flow:"
+ @echo "1. make menuconfig OR make config (set default configuration."
+ @echo " Check the defaults to make sure this is what you want"
+ @echo "2. make tests (builds the out of tree tests according to the config from step #1"
+ @echo "3. make install (installs the out of tree tests built in step #3"
+ @echo "4. make clean (remove build content, doesn't uninstall content from step #4"
+
+menuconfig: FORCE
+ $(MAKE) -r --directory=$(CURDIR)/kconfig mconf
+ $(CURDIR)/kconfig/mconf $(CURDIR)/config/Kconfig
+
+.PHONY config:
+config: FORCE
+ cp config/$(LTP_CONFIG) .config
+
+# Build the out of tree tests
+.PHONY tests:
+tests: FORCE
+ $(MAKE) --directory=kernel -f kernel.mak $(MAKEFLAGS) build
+
+# Install the out of tree tests
+.PHONY install:
+install: FORCE
+ $(MAKE) --directory=kernel -f kernel.mak $(MAKEFLAGS) install
+ cp -r $(CURDIR)/ltp_framework/* $(DESTDIR)/opt/ltp
+
+.PHONY: clean
+clean:
+ $(MAKE) --directory=kernel -f kernel.mak $(MAKEFLAGS) clean
+
+FORCE:
diff --git a/kernel/Makefile b/kernel/Makefile
new file mode 100644
index 0000000..0cbe200
--- /dev/null
+++ b/kernel/Makefile
@@ -0,0 +1,6 @@
+-include $(abspath $(TOPLEVEL)/../../ltp/.config)
+ifeq ($(realpath $(TOPLEVEL)/../../ltp/.config),)
+include $(LTP_TEST_CONFIG_FILE)
+endif
+
+obj-$(CONFIG_LTP_STE_TESTCASES) += testcases/
diff --git a/kernel/kernel.mak b/kernel/kernel.mak
new file mode 100644
index 0000000..840da0b
--- /dev/null
+++ b/kernel/kernel.mak
@@ -0,0 +1,49 @@
+# Compile this package with small thumb code -
+# not all packages work with this, then you have to comment
+# this out or patch the package.
+ifdef USE_THUMB
+ CFLAGS := -mthumb -mthumb-interwork $(CFLAGS)
+endif
+
+BUILD_ROOT := testcases
+KERNELDIR ?= ../../kernel
+
+.PHONY: build
+build: build-modules build-userspace
+
+.PHONY: build-modules
+build-modules: kernel.mak
+ echo "$@"
+ $(MAKE) --directory=$(KERNEL_OUTPUT) M=$(shell pwd) -j$(JOBS) modules
+
+.PHONY: build-userspace
+build-userspace: kernel.mak
+ echo "$@"
+ $(MAKE) --directory=$(BUILD_ROOT) -j$(JOBS) all
+
+
+.PHONY: install
+install: install-modules install-userspace
+
+.PHONY: install-modules
+install-modules: build-modules
+ echo "$@"
+ifneq ($(CROSS_COMPILE),)
+ $(MAKE) --directory=$(KERNEL_OUTPUT) M=$(shell pwd) -j$(JOBS) modules_install
+else
+ $(MAKE) --directory=$(KERNEL_OUTPUT) M=$(shell pwd) INSTALL_MOD_PATH=$(DESTDIR) -j$(JOBS) modules_install
+endif
+ depmod
+
+.PHONY: install-userspace
+install-userspace: build-userspace
+ echo "$@"
+ cd $(BUILD_ROOT) && $(MAKE) install DESTDIR=$(DESTDIR)
+ $(shell install -d $(DESTDIR)/opt/ltp/runtest)
+ cp -f runtest/* $(DESTDIR)/opt/ltp/runtest
+
+.PHONY: clean
+clean:
+ $(MAKE) --directory=$(BUILD_ROOT) clean
+ $(MAKE) --directory=$(KERNELDIR) M=$(shell pwd) clean
+ find . -name 'modules.order' -delete
diff --git a/kernel/testcases/Makefile b/kernel/testcases/Makefile
new file mode 100644
index 0000000..72931da
--- /dev/null
+++ b/kernel/testcases/Makefile
@@ -0,0 +1,60 @@
+# Disabled test | Reason
+# -------------------|--------------------------------------------------------
+# pwrmgmt | Specific hw/sw requirements
+
+
+-include $(abspath $(TOPLEVEL)/../../ltp/.config)
+# If TOPLEVEL path doesn't exist test local path
+ifeq ($(realpath $(TOPLEVEL)/../../ltp/.config),)
+include $(LTP_TEST_CONFIG_FILE)
+endif
+
+#obj-$(CONFIG_LTP_ALSA_I2C) += alsa_i2c/
+#obj-$(CONFIG_LTP_SENSORS_AB8500) += sensors_ab8500/
+#obj-$(CONFIG_LTP_METATEST) += metatest/
+#obj-$(CONFIG_LTP_EXAMPLE) += example/
+obj-$(CONFIG_LTP_DMA) += dma/
+#obj-$(CONFIG_LTP_RTC) += rtc/
+#obj-$(CONFIG_LTP_BLUETOOTH) += ste_conn/
+#obj-$(CONFIG_LTP_GPIO) += gpio/
+#obj-$(CONFIG_LTP_MCDE) += mcde/
+#obj-$(CONFIG_LTP_B2R2) += b2r2/
+#obj-$(CONFIG_LTP_UART) += uart/
+#obj-$(CONFIG_LTP_SSP) += ssp/
+#obj-$(CONFIG_LTP_SHRM) += shrm/
+#obj-$(CONFIG_LTP_I2C) += i2c/
+#obj-$(CONFIG_LTP_DLP) += dlp/
+#obj-$(CONFIG_LTP_MMC) += mmc/
+#obj-$(CONFIG_LTP_EMMC_FILESYSTEM_MMC_VALIDATION_LTP) += emmc_filesystem_mmc_Validation_LTP/
+#obj-$(CONFIG_LTP_MSP) += msp/
+#obj-$(CONFIG_LTP_ALS) += als/
+#obj-$(CONFIG_LTP_LSM303DLH) += lsm303dlh/
+#obj-$(CONFIG_LTP_LPS001WP) += lps001wp_prs/
+#obj-$(CONFIG_LTP_L3G4200D) += l3g4200d/
+#obj-$(CONFIG_LTP_PROXIMITY) += proximity/
+#obj-$(CONFIG_LTP_PWRMGMT) += pwrmgmt/
+#obj-$(CONFIG_LTP_TEE) += tee/
+#obj-$(CONFIG_LTP_HIGHRES_TIMER) += highres_timer/
+#obj-$(CONFIG_LTP_TIMER) += timer/
+#obj-$(CONFIG_LTP_HSI) += hsi_test/
+#obj-$(CONFIG_LTP_LED) += led/
+#obj-$(CONFIG_LTP_VIBRATOR) += vibrator/
+#obj-$(CONFIG_LTP_L2CACHE) += l2cache/
+
+ifneq ($(KERNELRELEASE),)
+
+# kernel modules should be built by descending here like this:
+# obj-y := dir1/ dir2/
+
+else
+
+all:
+ @set -e; for i in $(obj-y); do $(MAKE) -C $$i ; done
+
+install:
+ @set -e; for i in $(obj-y); do $(MAKE) -C $$i install ; done
+
+clean:
+ @set -e; for i in $(obj-y) ; do $(MAKE) -C $$i clean ; done
+
+endif
diff --git a/kernel/testcases/dma/Makefile b/kernel/testcases/dma/Makefile
new file mode 100644
index 0000000..c49641a
--- /dev/null
+++ b/kernel/testcases/dma/Makefile
@@ -0,0 +1,18 @@
+ifneq ($(KERNELRELEASE),)
+
+obj-y := kernel_space/
+
+else
+
+SUBDIRS := user-space
+
+all:
+ @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done
+
+install:
+ @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i install ; done
+
+clean:
+ @set -e; for i in $(SUBDIRS) ; do $(MAKE) -C $$i clean ; done
+
+endif
diff --git a/kernel/testcases/dma/kernel_space/Makefile b/kernel/testcases/dma/kernel_space/Makefile
new file mode 100644
index 0000000..e973fee
--- /dev/null
+++ b/kernel/testcases/dma/kernel_space/Makefile
@@ -0,0 +1,4 @@
+EXTRA_CFLAGS := -I$(abspath $(M)/framework/include-kernel)
+
+obj-m := stedma40_test.o
+stedma40_test-objs := dma_test_lib.o dma_test_module.o
diff --git a/kernel/testcases/dma/kernel_space/dma_test_lib.c b/kernel/testcases/dma/kernel_space/dma_test_lib.c
new file mode 100644
index 0000000..7d77537
--- /dev/null
+++ b/kernel/testcases/dma/kernel_space/dma_test_lib.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2007-2010
+ * Author: Per Friden <per.friden@stericsson.com> for ST-Ericsson
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/scatterlist.h>
+#include <linux/mutex.h>
+#include <linux/time.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <plat/ste_dma40.h>
+
+#include "dma_test_lib.h"
+
+#ifdef CONFIG_STE_DMA40_DEBUG
+extern void sted40_history_dump(void);
+#else
+static void sted40_history_dump(void)
+{
+}
+
+#endif
+
+MODULE_DESCRIPTION("DMA test lib: Support functions for DMA testing");
+MODULE_LICENSE("GPL");
+
+/* To get various debug prints put an x after this macro */
+#define DBG_PRINT(x)
+#define DBG_FAULT_PRINT(x) x
+
+
+static void transfer_timedout(struct work_struct *work)
+{
+ int i;
+ struct buflist *buflist;
+
+ buflist = container_of(work, struct buflist, timed_out.work);
+
+ DBG_FAULT_PRINT(printk(KERN_ERR "dma_test_lib: ERROR - DMA transfer timed out!\n"));
+ DBG_FAULT_PRINT(printk(KERN_ERR "Testcase: %s failed\n",
+ buflist->name));
+
+
+ for (i = 0; buflist->list_size[i] != -1; i++) {
+ printk(KERN_INFO "%p Transfer %d bytes from phy %x to %x\n",
+ buflist,
+ buflist->list_size[i],
+ buflist->list_src_phy[i],
+ buflist->list_dst_phy[i]);
+ }
+ printk(KERN_INFO "%p %d jobs\n", buflist, i);
+
+ sted40_history_dump();
+
+}
+
+static void transmit_cb(void *data)
+{
+ struct buflist *buflist = data;
+ unsigned long flags;
+
+ DBG_PRINT(printk
+ (KERN_INFO "[%s] finished_jobs %d\n", __func__,
+ buflist->finished_jobs));
+
+ cancel_delayed_work(&buflist->timed_out);
+
+ spin_lock_irqsave(&buflist->lock, flags);
+ buflist->finished_jobs++;
+ spin_unlock_irqrestore(&buflist->lock, flags);
+
+ if (buflist->callback)
+ buflist->callback(buflist);
+}
+
+int dmatest_buflist_create(struct buflist *buflist, int length,
+ int end_padding,
+ char *name, unsigned long dma_engine_flags,
+ int timeout, bool request_phy_chan,
+ struct dma_chan *dma_chan)
+{
+ dma_cap_mask_t mask;
+
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+ buflist->is_dma_prepared = false;
+ buflist->dma_engine_flags = dma_engine_flags;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+ if (request_phy_chan)
+ dma_cap_set(DMA_SLAVE, mask);
+
+ if (dma_chan)
+ buflist->dma_chan = dma_chan;
+ else
+ buflist->dma_chan = dma_request_channel(mask, NULL, NULL);
+
+ if (buflist->dma_chan == NULL) {
+ DBG_PRINT(printk(KERN_ERR "[%s] dma_request_channel failed\n",
+ __func__));
+ return -EINVAL;
+ }
+
+ spin_lock_init(&buflist->lock);
+
+ buflist->list_len = length;
+ buflist->finished_jobs = 0;
+ strncpy(buflist->name, name, MAX_NAME_LEN-1);
+
+ buflist->sent_jobs = 0;
+
+ buflist->list_size =
+ kmalloc(sizeof(buflist->list_size) * length + 1, GFP_KERNEL);
+ buflist->list_buf_dst =
+ kmalloc(sizeof(buflist->list_buf_dst) * length, GFP_KERNEL);
+ buflist->list_buf_dst_real =
+ kmalloc(sizeof(buflist->list_buf_dst_real) * length,
+ GFP_KERNEL);
+ buflist->list_buf_src =
+ kmalloc(sizeof(buflist->list_buf_src) * length, GFP_KERNEL);
+ buflist->desc =
+ kmalloc(sizeof(struct dma_async_tx_descriptor *) * length,
+ GFP_KERNEL);
+ buflist->cookie =
+ kmalloc(sizeof(dma_cookie_t) * length,
+ GFP_KERNEL);
+ buflist->list_dst_phy = kmalloc(sizeof(dma_addr_t) * length,
+ GFP_KERNEL);
+ buflist->list_src_phy = kmalloc(sizeof(dma_addr_t) * length,
+ GFP_KERNEL);
+ buflist->sgl_src =
+ kmalloc(sizeof(struct scatterlist) * length, GFP_KERNEL);
+ buflist->sgl_dst =
+ kmalloc(sizeof(struct scatterlist) * length, GFP_KERNEL);
+
+ sg_init_table(buflist->sgl_src, length);
+ sg_init_table(buflist->sgl_dst, length);
+
+ buflist->end_padding = end_padding;
+ buflist->timeout_len = timeout;
+ buflist->callback = NULL;
+
+ INIT_DELAYED_WORK_DEFERRABLE(&buflist->timed_out, transfer_timedout);
+
+ return 0;
+}
+
+void dmatest_buflist_destroy(struct buflist *buflist)
+{
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ if (buflist->dma_chan)
+ dma_release_channel(buflist->dma_chan);
+
+ dmatest_buflist_free(buflist);
+
+ kfree(buflist->list_size);
+ kfree(buflist->list_buf_dst);
+ kfree(buflist->list_buf_dst_real);
+ kfree(buflist->list_buf_src);
+ kfree(buflist->desc);
+ kfree(buflist->cookie);
+ kfree(buflist->list_dst_phy);
+ kfree(buflist->list_src_phy);
+ kfree(buflist->sgl_src);
+ kfree(buflist->sgl_dst);
+
+ buflist->list_size = NULL;
+ buflist->list_buf_dst = NULL;
+ buflist->list_buf_dst_real = NULL;
+ buflist->list_buf_src = NULL;
+ buflist->desc = NULL;
+ buflist->cookie = NULL;
+ buflist->list_dst_phy = NULL;
+ buflist->list_src_phy = NULL;
+ buflist->sgl_src = NULL;
+ buflist->sgl_dst = NULL;
+}
+
+void dmatest_sizelist_randomize(struct buflist *buflist, u32 min, u32 max, int align)
+{
+ int i;
+ struct timespec ts = current_kernel_time();
+
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ srandom32(ts.tv_nsec);
+
+ for (i = 0; i < buflist->list_len; i++) {
+ buflist->list_size[i] =
+ ALIGN(random32() / (0xFFFFFFFF / (max - min)) + min, align);
+/* DBG_PRINT(printk(KERN_INFO "rand value %d , min %d max %d\n", */
+/* buflist->list_size[i], min, max)); */
+
+ /* TODO replace BUG_ON:s with error report, return -1 */
+ BUG_ON(buflist->list_size[i] > ALIGN(max, align));
+ }
+
+ buflist->list_size[i] = -1;
+}
+
+void dmatest_sizelist_set(struct buflist *buflist, u32 value, int align)
+{
+ int i;
+
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ for (i = 0; i < buflist->list_len; i++) {
+ buflist->list_size[i] = ALIGN(value, align);
+ }
+
+ buflist->list_size[i] = -1;
+}
+
+void dmatest_buflist_alloc(struct buflist *buflist)
+{
+ int i;
+ int buf_i;
+ int size;
+
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ for (buf_i = 0; buflist->list_size[buf_i] != -1; buf_i++) {
+ size = buflist->list_size[buf_i];
+ buflist->list_buf_dst_real[buf_i] =
+ kmalloc(size + buflist->end_padding + 2 * dma_get_cache_alignment(),
+ GFP_KERNEL);
+ buflist->list_buf_dst[buf_i] = PTR_ALIGN(buflist->list_buf_dst_real[buf_i],
+ dma_get_cache_alignment());
+ buflist->list_buf_src[buf_i] =
+ kmalloc(size + buflist->end_padding, GFP_KERNEL);
+
+ for (i = 0; i < size; i++) {
+ buflist->list_buf_src[buf_i][i] = (u8) (i + buf_i);
+ buflist->list_buf_dst[buf_i][i] = 0xAA;
+ }
+ for (i = size; i < size + buflist->end_padding; i++) {
+ buflist->list_buf_src[buf_i][i] = 0xBE;
+ buflist->list_buf_dst[buf_i][i] = 0xBE;
+ }
+ if (buflist->end_padding) {
+ dma_map_single(buflist->dma_chan->device->dev,
+ &buflist->list_buf_dst[buf_i][size],
+ buflist->end_padding,
+ DMA_BIDIRECTIONAL);
+ dma_map_single(buflist->dma_chan->device->dev,
+ &buflist->list_buf_src[buf_i][size],
+ buflist->end_padding,
+ DMA_BIDIRECTIONAL);
+ }
+ }
+
+ for (i = 0; buflist->list_size[i] != -1; i++) {
+ sg_set_buf(&buflist->sgl_src[i],
+ buflist->list_buf_src[i],
+ buflist->list_size[i]);
+ sg_set_buf(&buflist->sgl_dst[i],
+ buflist->list_buf_dst[i],
+ buflist->list_size[i]);
+ }
+
+}
+
+void dmatest_buflist_free(struct buflist *buflist)
+{
+ int i;
+
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ for (i = 0; buflist->list_size[i] != -1; i++) {
+ kfree(buflist->list_buf_dst_real[i]);
+ kfree(buflist->list_buf_src[i]);
+
+ buflist->list_buf_dst[i] = 0;
+ buflist->list_buf_src[i] = 0;
+ }
+
+}
+
+int dmatest_buflist_payload_check(struct buflist *buflist)
+{
+ int err = 0;
+ int i;
+
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ if (buflist->sgl_src_len)
+ dma_unmap_sg(buflist->dma_chan->device->dev,
+ buflist->sgl_src, buflist->sgl_src_len,
+ DMA_BIDIRECTIONAL);
+
+ if (buflist->sgl_dst_len)
+ dma_unmap_sg(buflist->dma_chan->device->dev,
+ buflist->sgl_dst, buflist->sgl_dst_len,
+ DMA_BIDIRECTIONAL);
+
+ for (i = 0; buflist->list_size[i] != -1; i++) {
+ if (!buflist->sgl_src_len)
+ dma_unmap_single(buflist->dma_chan->device->dev,
+ buflist->list_src_phy[i],
+ buflist->list_size[i], DMA_BIDIRECTIONAL);
+
+ if (!buflist->sgl_dst_len)
+ dma_unmap_single(buflist->dma_chan->device->dev,
+ buflist->list_dst_phy[i],
+ buflist->list_size[i], DMA_BIDIRECTIONAL);
+
+ if (memcmp
+ (buflist->list_buf_dst[i], buflist->list_buf_src[i],
+ buflist->list_size[i]) != 0) {
+
+ DBG_FAULT_PRINT(printk
+ (KERN_INFO "[%s] fault index %d\n",
+ __func__, i));
+
+ dmatest_buflist_payload_printdiff(buflist, i);
+ err = -1;
+ }
+ }
+
+ if (err) {
+ DBG_FAULT_PRINT(printk(KERN_INFO "Testcase: %s failed\n", buflist->name));
+ sted40_history_dump();
+ }
+
+ return err;
+}
+
+#define MAX_ERROR_PRINTS 16
+void dmatest_buflist_payload_printdiff(struct buflist *buflist,
+ u32 buf_index)
+{
+ int i, el = 0;
+ int size = buflist->list_size[buf_index];
+ u8 *buf_dst = buflist->list_buf_dst[buf_index];
+ u8 *buf_src = buflist->list_buf_src[buf_index];
+
+ DBG_FAULT_PRINT(printk
+ (KERN_INFO "[%s] fault buffer index %d dst at phy: 0x%lx\n",
+ __func__, buf_index, virt_to_phys(buf_dst)));
+
+ for (i = 0; i < size; i++) {
+ if (buf_dst[i] != buf_src[i]) {
+ DBG_FAULT_PRINT(printk
+ (KERN_INFO
+ "Buffer fault index %d: "
+ "DEST data 0x%x Virt addr %p, phy 0x%x, SRC data: 0x%x\n",
+ i, buf_dst[i],
+ buflist->list_buf_dst[buf_index] + i,
+ buflist->list_dst_phy[buf_index] + i,
+ buf_src[i]));
+ el++;
+ if (el == MAX_ERROR_PRINTS)
+ break;
+ }
+ }
+}
+
+void dmatest_buflist_start_single(struct buflist *buflist,
+ void (*callback)(struct buflist *bf))
+{
+ int i;
+
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ if ((buflist->dma_engine_flags & DMA_CTRL_ACK) ||
+ !buflist->is_dma_prepared) {
+ for (i = 0; buflist->list_size[i] != -1; i++) {
+
+ buflist->list_src_phy[i] =
+ dma_map_single(buflist->dma_chan->device->dev,
+ buflist->list_buf_src[i],
+ buflist->list_size[i],
+ DMA_BIDIRECTIONAL);
+
+ buflist->list_dst_phy[i] =
+ dma_map_single(buflist->dma_chan->device->dev,
+ buflist->list_buf_dst[i],
+ buflist->list_size[i],
+ DMA_BIDIRECTIONAL);
+
+ buflist->desc[i] = buflist->dma_chan->device->
+ device_prep_dma_memcpy(buflist->dma_chan,
+ buflist->list_dst_phy[i],
+ buflist->list_src_phy[i],
+ buflist->list_size[i],
+ buflist->dma_engine_flags);
+
+ buflist->desc[i]->callback = transmit_cb;
+ buflist->desc[i]->callback_param = buflist;
+ }
+ buflist->is_dma_prepared = true;
+ }
+ buflist->callback = callback;
+
+ buflist->sgl_src_len = 0;
+ buflist->sgl_dst_len = 0;
+
+ for (i = 0; buflist->list_size[i] != -1; i++) {
+ buflist->cookie[i] = buflist->desc[i]->tx_submit(buflist->desc[i]);
+ }
+ schedule_delayed_work(&buflist->timed_out,
+ msecs_to_jiffies(buflist->timeout_len));
+
+ dma_async_issue_pending(buflist->dma_chan);
+}
+
+void dmatest_buflist_start_sg(struct buflist *buflist,
+ void (*callback)(struct buflist *bf))
+{
+ DBG_PRINT(printk(KERN_INFO "[%s]\n", __func__));
+
+ buflist->sgl_src_len = dma_map_sg(buflist->dma_chan->device->dev,
+ buflist->sgl_src, buflist->list_len,
+ DMA_BIDIRECTIONAL);
+ buflist->sgl_dst_len = dma_map_sg(buflist->dma_chan->device->dev,
+ buflist->sgl_dst, buflist->list_len,
+ /* Both direction for verifying transfered data */
+ DMA_BIDIRECTIONAL);
+
+ if ((buflist->dma_engine_flags & DMA_CTRL_ACK) ||
+ !buflist->is_dma_prepared) {
+ buflist->desc[0] = buflist->dma_chan->device->device_prep_dma_sg(buflist->dma_chan,
+ buflist->sgl_dst,
+ buflist->sgl_dst_len,
+ buflist->sgl_src,
+ buflist->sgl_src_len,
+ buflist->dma_engine_flags);
+
+ buflist->desc[0]->callback = transmit_cb;
+ buflist->desc[0]->callback_param = buflist;
+ buflist->is_dma_prepared = true;
+ }
+
+ buflist->callback = callback;
+
+ buflist->cookie[0] = buflist->desc[0]->tx_submit(buflist->desc[0]);
+ schedule_delayed_work(&buflist->timed_out,
+ msecs_to_jiffies(buflist->timeout_len));
+
+ dma_async_issue_pending(buflist->dma_chan);
+
+}
+
+void dmatest_buflist_reset_nbr_finished(struct buflist *buflist)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&buflist->lock, flags);
+
+ buflist->finished_jobs = 0;
+ buflist->sent_jobs = 0;
+ spin_unlock_irqrestore(&buflist->lock, flags);
+}
+
+int dmatest_buflist_get_nbr_finished(struct buflist *buflist)
+{
+ unsigned long flags;
+ u32 ret;
+
+ spin_lock_irqsave(&buflist->lock, flags);
+ ret = buflist->finished_jobs;
+ spin_unlock_irqrestore(&buflist->lock, flags);
+
+ return ret;
+}
+
diff --git a/kernel/testcases/dma/kernel_space/dma_test_lib.h b/kernel/testcases/dma/kernel_space/dma_test_lib.h
new file mode 100644
index 0000000..fed1a3d
--- /dev/null
+++ b/kernel/testcases/dma/kernel_space/dma_test_lib.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2007-2010
+ * Author: Per Friden <per.friden@stericsson.com> for ST-Ericsson
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/scatterlist.h>
+#include <linux/mutex.h>
+#include <linux/dmaengine.h>
+
+#define MAX_NAME_LEN 128
+
+struct buflist {
+ spinlock_t lock;
+
+ struct dma_async_tx_descriptor **desc;
+ char name[MAX_NAME_LEN];
+ int *list_size;
+ dma_addr_t *list_dst_phy;
+ dma_addr_t *list_src_phy;
+ u8 **list_buf_dst;
+ u8 **list_buf_dst_real;
+ u8 **list_buf_src;
+ struct scatterlist *sgl_dst;
+ struct scatterlist *sgl_src;
+ unsigned int sgl_dst_len;
+ unsigned int sgl_src_len;
+
+ unsigned long dma_engine_flags;
+ bool is_dma_prepared;
+ u32 list_len;
+
+ struct dma_chan *dma_chan;
+ dma_cookie_t *cookie;
+
+ void (*callback)(struct buflist *bf);
+ struct workqueue_struct *wq;
+ u32 finished_jobs;
+ u32 sent_jobs;
+
+ struct delayed_work timed_out;
+ int timeout_len;
+ u32 end_padding;
+};
+
+/* Initiate dma test
+ *
+ * returns 0 on success otherwise none zero
+ */
+int dmatest_init(void);
+
+
+/** Creates a buffer list
+ * @length specifies length of buffer and size list
+ *
+ */
+int dmatest_buflist_create(struct buflist *buflist, int length,
+ int end_padding,
+ char *name, unsigned long dma_engine_flags,
+ int timeout, bool request_phy_chan, struct dma_chan *dma_chan);
+
+/* Destroys a buffer list, calls dmatest_buflist_free if list is != NULL */
+void dmatest_buflist_destroy(struct buflist *buflist);
+
+/* Allocates buffers according to size list and writes a pattern to the buffer,
+ * dmatest_sizelist_randomize or dmatest_sizelist_set must be
+ * called before this function
+ */
+void dmatest_buflist_alloc(struct buflist *buflist);
+
+/* Frees the buffers allocate by dmatest_buflist_alloc */
+void dmatest_buflist_free(struct buflist *buflist);
+
+/* Initialize size list with random values between min and max */
+void dmatest_sizelist_randomize(struct buflist *buflist, u32 min, u32 max, int align);
+
+/* Initialize size list with value */
+void dmatest_sizelist_set(struct buflist *buflist, u32 value, int align);
+
+/* Start sending the buflist to DMA as many single jobs, calls callback when done */
+void dmatest_buflist_start_single(struct buflist *buflist,
+ void (*callback)(struct buflist *bf));
+
+/* Start sending the buflist to DMA as a scatter-gatter list, calls callback when done */
+void dmatest_buflist_start_sg(struct buflist *buflist,
+ void (*callback)(struct buflist *bf));
+
+/* Verify the buffer according to the pattern written by dmatest_buflist_alloc.
+ * Returns 0 if ok otherwise -(index +1)
+ */
+int dmatest_buflist_payload_check(struct buflist *buflist);
+
+/* prints the difference between TX and RX for buffer number buf_index */
+void dmatest_buflist_payload_printdiff(struct buflist *buflist,
+ u32 buf_index);
+
+void dmatest_buflist_reset_nbr_finished(struct buflist *buflist);
+
+int dmatest_buflist_get_nbr_finished(struct buflist *buflist);
diff --git a/kernel/testcases/dma/kernel_space/dma_test_module.c b/kernel/testcases/dma/kernel_space/dma_test_module.c
new file mode 100644
index 0000000..6dae62b
--- /dev/null
+++ b/kernel/testcases/dma/kernel_space/dma_test_module.c
@@ -0,0 +1,2587 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2007-2010
+ * Author: Per Friden <per.friden@stericsson.com> for ST-Ericsson
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/scatterlist.h>
+#include <linux/completion.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/dma-mapping.h>
+#include <plat/ste_dma40.h>
+
+#include "dma_test_lib.h"
+
+#ifndef CONFIG_DEBUG_FS
+#error "DEBUG_FS must be set"
+#endif
+
+
+MODULE_DESCRIPTION("DMA test module: Test case for DMA");
+MODULE_LICENSE("GPL");
+
+static DEFINE_MUTEX(tc_mutex);
+
+#define DBG_TEST(x) x
+#define DBG_SPAM(x)
+
+#define TX_ALIGN 1
+
+#define DEFAULT_TIMEOUT 10000 /* ms */
+
+#if defined(CONFIG_MMC) && defined(CONFIG_STE_DMA40_DEBUG)
+extern int stedma40_debug_mmc_sgsize(u32 size, bool is_chain);
+#endif
+
+#ifdef CONFIG_STE_DMA40_DEBUG
+extern void sted40_history_reset(void);
+extern void sted40_history_disable(void);
+extern void sted40_history_dump(void);
+extern void sted40_history_text(char *text);
+#else
+#define sted40_history_reset()
+#define sted40_history_disable()
+#define sted40_history_dump()
+#define sted40_history_text(x)
+#endif
+
+enum test_case_id {
+ TEST1 = 1,
+ TEST2,
+ TEST3,
+ TEST4,
+ TEST5,
+ TEST6,
+ TEST7,
+ TEST8,
+ TEST9,
+ TEST10,
+ TEST11,
+ TEST12,
+ TEST13,
+ TEST14,
+ TEST15,
+ TEST16,
+ TEST17,
+ TEST18,
+ TEST19,
+ TEST20,
+ TEST21,
+ TEST22,
+ TEST23,
+ TEST24,
+ TEST25,
+ TEST26,
+ TEST27,
+ TEST28,
+ TEST29,
+ TEST30,
+ TEST31,
+ TEST32,
+ TEST33,
+ TEST34,
+ TEST35,
+ /* HW stress test */
+ TEST36,
+ TEST37,
+ TEST38,
+ TEST39,
+ TEST40,
+ TEST41,
+ TEST42,
+ TEST43,
+ TEST44,
+ TEST45,
+ TEST46,
+ TEST47,
+ TEST48,
+ TEST49,
+ TEST50,
+ TEST51,
+ TEST52,
+ TEST53,
+ /* HW stress test end */
+ TEST54,
+ TEST55,
+ TEST56,
+ TEST57,
+ TEST58,
+ TEST59,
+ TEST60,
+ TEST61,
+ TEST62,
+ TEST63,
+ TEST64,
+ TEST65,
+ TEST66,
+ TEST67,
+ TEST68,
+ TEST69,
+ NBR_TESTS,
+};
+
+struct tc_struct {
+ /* set by client */
+ char name[MAX_NAME_LEN];
+ int laps;
+ int end_padding;
+ int do_check_buffer;
+ int list_len;
+
+ /* err status set by test engine */
+ int err;
+
+ /* used by test engine */
+ int nbr_returns_per_transfer;
+ struct workqueue_struct *wq;
+ spinlock_t lock;
+ struct buflist buflist;
+ void (*callback)(struct buflist *bf);
+ struct work_struct work_start;
+ struct work_struct work_close;
+ struct completion done;
+ int job_counter;
+};
+
+static void tc_worker_start_single(struct work_struct *work)
+{
+ struct tc_struct *tc =
+ container_of(work, struct tc_struct, work_start);
+
+ dmatest_buflist_start_single(&tc->buflist, tc->callback);
+}
+
+static void tc_worker_start_sg(struct work_struct *work)
+{
+ struct tc_struct *tc =
+ container_of(work, struct tc_struct, work_start);
+
+ dmatest_buflist_start_sg(&tc->buflist, tc->callback);
+}
+
+static void tc_worker(struct buflist *bf)
+{
+ int finished_cbs;
+ struct tc_struct *tc = container_of(bf, struct tc_struct, buflist);
+
+ finished_cbs = dmatest_buflist_get_nbr_finished(&tc->buflist);
+
+
+ DBG_SPAM(printk
+ (KERN_INFO "[%s] job_counter %d\n", __func__,
+ tc->job_counter));
+
+ tc->job_counter++;
+
+ if (tc->job_counter == tc->nbr_returns_per_transfer) {
+ if (tc->do_check_buffer)
+ tc->err = dmatest_buflist_payload_check(&tc->buflist);
+
+ tc->laps--;
+ if (tc->laps == 0) {
+ complete(&tc->done);
+ } else {
+ dmatest_buflist_reset_nbr_finished(&tc->buflist);
+ tc->job_counter = 0;
+
+ queue_work(tc->wq, &tc->work_start);
+ }
+ }
+}
+
+/* test wrapper functions for creating/running tests */
+static int tc_test_init(struct tc_struct *tc, bool is_sg_transfer,
+ int size, bool is_const_size, unsigned long dma_flags,
+ u32 tx_align, int timeout)
+{
+ int err;
+
+ DBG_SPAM(printk(KERN_INFO "[%s] %s\n", __func__, tc->name));
+
+ tc->wq = create_singlethread_workqueue(tc->name);
+ if (tc->wq == NULL)
+ goto err;
+ err = dmatest_buflist_create(&tc->buflist, tc->list_len,
+ tc->end_padding,
+ tc->name, dma_flags, timeout, false, NULL);
+ if (err)
+ goto err_create;
+
+
+ tc->job_counter = 0;
+
+ if (is_sg_transfer) {
+ INIT_WORK(&tc->work_start, tc_worker_start_sg);
+ tc->nbr_returns_per_transfer = 1;
+ } else {
+ tc->nbr_returns_per_transfer = tc->list_len;
+ INIT_WORK(&tc->work_start, tc_worker_start_single);
+ }
+
+ init_completion(&tc->done);
+ spin_lock_init(&tc->lock);
+ tc->callback = tc_worker;
+
+ if (is_const_size)
+ dmatest_sizelist_set(&tc->buflist, size, tx_align);
+ else
+ dmatest_sizelist_randomize(&tc->buflist, 1, 60*1024, tx_align);
+ dmatest_buflist_alloc(&tc->buflist);
+
+ return 0;
+ err_create:
+ destroy_workqueue(tc->wq);
+ err:
+ return -EINVAL;
+}
+
+static void tc_test_free(struct tc_struct *tc)
+{
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ destroy_workqueue(tc->wq);
+ dmatest_buflist_destroy(&tc->buflist);
+}
+
+static void tc_test_wait(struct tc_struct *tc)
+{
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ wait_for_completion_interruptible(&tc->done);
+}
+
+#ifdef CONFIG_STE_DMA40_DEBUG
+static bool tc_test_is_done(struct tc_struct *tc)
+{
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ return completion_done(&tc->done);
+}
+#endif
+
+static void tc_test_run(struct tc_struct *tc)
+{
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ queue_work(tc->wq, &tc->work_start);
+}
+
+
+/* test case 1: Send and receive 32 byte buffer
+ *
+ */
+static int tc_1_fixed_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 1,
+ };
+ int length = 1;
+ int end_padding = 64;
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ sted40_history_reset();
+
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+ tc.callback = tc_worker;
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ tc.err = dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ DBG_TEST(if (tc.err) printk(KERN_INFO "[%s] Error creating buflist\n", __func__));
+
+ if (tc.err)
+ goto out;
+
+ dmatest_sizelist_set(&tc.buflist, 32, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ out:
+
+ return tc.err;
+}
+
+
+/* test case 2: Send and receive 1 byte buffer
+ *
+ */
+static int tc_2_fixed_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 30;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ tc.err = dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ DBG_TEST(if (tc.err) printk(KERN_INFO "[%s] Error creating buflist\n", __func__));
+
+ if (tc.err)
+ goto out;
+
+ dmatest_sizelist_set(&tc.buflist, 32, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+ out:
+
+ return tc.err;
+}
+
+/* test case 3: Send and receive 1k buffer
+ *
+ */
+static int tc_3_fixed_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 10,
+ };
+ int length = 10;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_set(&tc.buflist, 1*1024, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 4: Send and receive 8k buffer
+ *
+ */
+static int tc_4_fixed_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 10,
+ };
+ int length = 10;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker; INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_set(&tc.buflist, 8*1024, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 5: Send and receive 8k buffer
+ *
+ */
+static int tc_5_random_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 40;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_randomize(&tc.buflist, 1, 60*1024, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 6: scatter-gatter buffer
+ *
+ */
+static int tc_sg_buffer(int scatter_list_entries, int laps, int buffer_size)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ };
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_sg);
+
+ /* test case configuration */
+ tc.laps = laps;
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ tc.err = dmatest_buflist_create(&tc.buflist, scatter_list_entries,
+ end_padding, tc.name,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ 10*DEFAULT_TIMEOUT, false, NULL);
+
+ DBG_TEST(if (tc.err) printk(KERN_INFO "[%s] Error creating buflist\n", __func__));
+
+ if (tc.err)
+ goto out;
+
+ dmatest_sizelist_set(&tc.buflist, buffer_size, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+
+ tc.nbr_returns_per_transfer = 1;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+ out:
+
+ return tc.err;
+}
+
+#define SCATTER_LIST_ENTRIES_MAX 25
+#define SIZE_MAX (2 * PAGE_SIZE + 100)
+
+static int tc_9_sg_buffer(void)
+{
+ int res = 0;
+ int scatter_list_entries;
+ int size;
+ int transfers = 0;
+
+ sted40_history_disable();
+
+ for (scatter_list_entries = 1;
+ scatter_list_entries < SCATTER_LIST_ENTRIES_MAX;
+ scatter_list_entries++) {
+ for(size = 2; size < SIZE_MAX; size++) {
+ res = tc_sg_buffer(scatter_list_entries, 1, size);
+ if (res) {
+ printk(KERN_INFO "[%s] sgl with entries: %d size: %d failed\n",
+ __func__, scatter_list_entries, size);
+ goto _exit;
+ }
+ if (transfers % 2500 == 0) {
+ printk(KERN_INFO "[%s]: %d of %ld transfers done.\n",
+ __func__, transfers,
+ SCATTER_LIST_ENTRIES_MAX*SIZE_MAX);
+ }
+
+ transfers++;
+ }
+ }
+_exit:
+ return res;
+}
+
+static int tc_6_sg_buffer(void)
+{
+ return tc_sg_buffer(4, 1, 32);
+}
+
+#define SIZE_MAX_ETERNAL 1567
+
+#if defined(CONFIG_MMC) && defined(CONFIG_STE_DMA40_DEBUG)
+static int tc_14_sg_buffer_temporary_endless(void)
+{
+ int res = 0;
+ int scatter_list_entries;
+ int size;
+ int transfers = 0;
+ int errors = 0;
+
+ printk(KERN_INFO "Warning:this testcase is endless and is only there to provoke memcpy sg errors\n");
+ sted40_history_disable();
+ while (1) {
+ for (scatter_list_entries = 1;
+ scatter_list_entries < SCATTER_LIST_ENTRIES_MAX;
+ scatter_list_entries++) {
+ for (size = 2; size < SIZE_MAX_ETERNAL; size++) {
+
+ res = tc_sg_buffer(scatter_list_entries, 1, size);
+ if (res) {
+ errors++;
+ printk(KERN_INFO "[%s] sgl with entries: %d size: %d failed\n"
+ "after %d transfers there are %d error(s)\n",
+ __func__, scatter_list_entries,
+ size, transfers, errors);
+ }
+ transfers++;
+ }
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static int tc_7_sg_buffer(void)
+{
+ return tc_sg_buffer(200, 3, 160);
+}
+
+
+/* test case 8: scatter-gatter buffer
+ *
+ */
+static int tc_8_sg_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 2,
+ };
+ int length = 16;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_sg);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ tc.err = dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ DBG_TEST(if (tc.err) printk(KERN_INFO "[%s] Error creating buflist\n", __func__));
+
+ if (tc.err)
+ goto out;
+
+ dmatest_sizelist_set(&tc.buflist, 32, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+
+ /* Number of lists, not entries in each list */
+ tc.nbr_returns_per_transfer = 1;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+ out:
+
+ return tc.err;
+}
+
+#if defined(CONFIG_MMC) && defined(CONFIG_STE_DMA40_DEBUG)
+static int dd_setup(struct seq_file *s, const char *func,
+ u32 elem_size, bool is_sg_chain, const char *cmd)
+{
+ int err;
+
+ err = stedma40_debug_mmc_sgsize(elem_size, is_sg_chain);
+ if (err)
+ goto out;
+ err = seq_printf(s, "# [%s()] sg_elem_size %d, sg_chain %d, run:\n"
+ "%s; sync\n",
+ func, elem_size, is_sg_chain, cmd);
+ out:
+ return err;
+}
+
+/* test case 10: Testing dma via MMC, require sdio_ops.patch
+ *
+ */
+static int tc_10_sg_size_1024_one(struct seq_file *s)
+{
+ u32 elem_size = 1024;
+ bool is_sg_chain = 0;
+ const char *cmd = "dd if=/dev/zero of=/out_zero bs=4096 count=1";
+ DBG_SPAM(printk(KERN_INFO "# [%s]\n", __func__));
+
+ return dd_setup(s, __func__, elem_size, is_sg_chain, cmd);
+}
+
+/* test case 11: Testing dma via MMC, require sdio_ops.patch
+ *
+ */
+static int tc_11_sg_size_chain_one(struct seq_file *s)
+{
+ u32 elem_size = 1024;
+ bool is_sg_chain = 1;
+ const char *cmd = "dd if=/dev/zero of=/out_zero bs=4096 count=1";
+
+ DBG_SPAM(printk(KERN_INFO "# [%s]\n", __func__));
+
+ return dd_setup(s, __func__, elem_size, is_sg_chain, cmd);
+}
+
+/* test case 12: Testing dma via MMC, require sdio_ops.patch
+ *
+ */
+static int tc_12_sg_size_1024_many(struct seq_file *s)
+{
+ u32 elem_size = 1024;
+ bool is_sg_chain = 0;
+ const char *cmd = "dd if=/dev/zero of=/out_zero bs=4096 count=256";
+ DBG_SPAM(printk(KERN_INFO "# [%s]\n", __func__));
+
+ return dd_setup(s, __func__, elem_size, is_sg_chain, cmd);
+}
+
+/* test case 13: Testing dma via MMC, require sdio_ops.patch
+ *
+ */
+static int tc_13_sg_size_1024_chain_many(struct seq_file *s)
+{
+ u32 elem_size = 1024;
+ bool is_sg_chain = 1;
+ const char *cmd = "dd if=/dev/zero of=/out_zero bs=4096 count=256";
+ DBG_SPAM(printk(KERN_INFO "# [%s]\n", __func__));
+
+ return dd_setup(s, __func__, elem_size, is_sg_chain, cmd);
+}
+#endif
+
+/* test case 15: Send and receive 1-4 bytes buffer
+ *
+ */
+static int tc_15_static_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 40;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_set(&tc.buflist, 1, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 16: Send and receive 1-4 bytes buffer
+ *
+ */
+static int tc_16_static_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 40;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_set(&tc.buflist, 2, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 17: Send and receive 1-4 bytes buffer
+ *
+ */
+static int tc_17_static_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 40;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_set(&tc.buflist, 3, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 18: Send and receive 1-4 bytes buffer
+ *
+ */
+static int tc_18_static_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 40;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_set(&tc.buflist, 4, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 19: Send and receive 1-4 bytes buffer
+ *
+ */
+static int tc_19_static_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 40;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_set(&tc.buflist, 5, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+/* test case 20: Send and receive 1-4 bytes buffer
+ *
+ */
+static int tc_20_random_buffer(void)
+{
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 100,
+ };
+ int length = 40;
+ int end_padding = 64;
+ tc.wq = create_singlethread_workqueue(__func__);
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ init_completion(&tc.done);
+ spin_lock_init(&tc.lock);
+
+ tc.callback = tc_worker;
+ INIT_WORK(&tc.work_start, tc_worker_start_single);
+
+ snprintf(tc.name, MAX_NAME_LEN, "%s", __func__);
+ dmatest_buflist_create(&tc.buflist, length, end_padding,
+ tc.name, DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, false, NULL);
+
+ dmatest_sizelist_randomize(&tc.buflist, 1, 4, TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc.buflist);
+
+ tc.job_counter = 0;
+ tc.nbr_returns_per_transfer = length;
+ queue_work(tc.wq, &tc.work_start);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+ destroy_workqueue(tc.wq);
+
+ dmatest_buflist_destroy(&tc.buflist);
+
+ return tc.err;
+}
+
+static int tc_pause_and_unpause_parallel(int max_channels, char *str,
+ unsigned long dma_flags, int tx_align)
+{
+ struct tc_struct *tc;
+ int i;
+ int err = 0;
+ int bytes_left = 0;
+ int bytes_left_prev = 0;
+ int max = 1000;
+ int pause_id = 0;
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ tc = kzalloc(sizeof(struct tc_struct) * max_channels, GFP_KERNEL);
+ for (i = 0; i < max_channels; i++) {
+ tc[i].do_check_buffer = 1;
+ tc[i].laps = 1;
+ tc[i].end_padding = 64;
+ tc[i].list_len = 1;
+
+ snprintf(tc[i].name, 32, "%s_%d", str, i);
+
+ tc[i].err = tc_test_init(&tc[i], false, 60*1024, true,
+ dma_flags, tx_align,
+ DEFAULT_TIMEOUT);
+ if (tc[i].err)
+ break;
+ };
+ if (i == 0) {
+ err = -EINVAL;
+ goto out;
+ }
+ max_channels = i;
+
+ DBG_SPAM(printk(KERN_INFO "[%s] max available memcpy channels %d\n", str, max_channels));
+
+ for (i = 0; i < max_channels; i++)
+ tc_test_run(&tc[i]);
+
+
+ for (i = 0; i < max; i++) {
+ {
+ struct dma_tx_state state;
+
+ tc[pause_id].buflist.dma_chan->device->
+ device_control(tc[pause_id].buflist.dma_chan,
+ DMA_PAUSE, 0);
+
+ (void) tc[pause_id].buflist.dma_chan->device->
+ device_tx_status(tc[pause_id].buflist.dma_chan,
+ tc[pause_id].buflist.cookie[0],
+ &state);
+ bytes_left = state.residue;
+ }
+
+
+
+ if (bytes_left > 0)
+ break;
+ }
+ if (i == max) {
+ DBG_SPAM(printk(KERN_INFO "[%s] i == max bytes left %d\n",
+ __func__, bytes_left));
+ goto wait;
+ }
+
+ DBG_SPAM(printk(KERN_INFO "[%s] bytes left %d\n",
+ __func__, bytes_left));
+ tc[pause_id].buflist.dma_chan->device->
+ device_control(tc[pause_id].buflist.dma_chan,
+ DMA_RESUME, 0);
+
+ do {
+ mdelay(1);
+ tc[pause_id].buflist.dma_chan->device->
+ device_control(tc[pause_id].buflist.dma_chan,
+ DMA_PAUSE, 0);
+ bytes_left_prev = bytes_left;
+
+ {
+ struct dma_tx_state state;
+
+ (void) tc[pause_id].buflist.dma_chan->device->
+ device_tx_status(tc[pause_id].buflist.dma_chan,
+ tc[pause_id].buflist.cookie[0],
+ &state);
+ bytes_left = state.residue;
+
+ }
+ tc[pause_id].buflist.dma_chan->device->
+ device_control(tc[pause_id].buflist.dma_chan,
+ DMA_RESUME, 0);
+ } while (bytes_left != 0 || bytes_left_prev != bytes_left);
+
+ if (bytes_left != 0 && bytes_left_prev == bytes_left) {
+ DBG_SPAM(printk(KERN_INFO "[%s] bytes left = prev %d\n",
+ __func__, bytes_left));
+ tc[pause_id].err = -EINVAL;
+ goto out;
+ }
+
+
+ DBG_SPAM(printk(KERN_INFO "[%s] bytes left %d\n",
+ __func__, bytes_left));
+
+ wait:
+ for (i = 0; i < max_channels; i++) {
+ tc_test_wait(&tc[i]);
+ DBG_SPAM(printk(KERN_INFO "[%s] %d done\n", str, i));
+ }
+
+ out:
+ for (i = 0; i < max_channels; i++)
+ tc_test_free(&tc[i]);
+
+ for (i = 0; i < max_channels; i++)
+ err |= tc[i].err;
+
+ kfree(tc);
+ return err;
+}
+
+static int tc_21_stop_and_go(void)
+{
+ return tc_pause_and_unpause_parallel(1, "tc_21",
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK, 4);
+}
+
+static struct dma_chan *tc_22_25_chan;
+int tc_22_req(void)
+{
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+
+ tc_22_25_chan = dma_request_channel(mask, NULL, NULL);
+
+ if (tc_22_25_chan != NULL)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static struct dma_chan *tc_22_25_chan;
+int tc_23_no_irq(void)
+{
+ dma_cap_mask_t mask;
+ void *buf_src;
+ void *buf_dst;
+ dma_addr_t addr_src;
+ dma_addr_t addr_dst;
+ int size = 4096;
+ struct dma_async_tx_descriptor *desc;
+
+ if (tc_22_25_chan == NULL)
+ return -EINVAL;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+
+ buf_src = kzalloc(size, GFP_KERNEL);
+ memset(buf_src, 0xAA, size);
+ buf_dst = kzalloc(size, GFP_KERNEL);
+
+ addr_src = dma_map_single(tc_22_25_chan->device->dev,
+ buf_src, size, DMA_BIDIRECTIONAL);
+ addr_dst = dma_map_single(tc_22_25_chan->device->dev,
+ buf_dst, size, DMA_FROM_DEVICE);
+
+ desc = tc_22_25_chan->device->
+ device_prep_dma_memcpy(tc_22_25_chan,
+ addr_dst, addr_src, size,
+ DMA_CTRL_ACK);
+
+ desc->tx_submit(desc);
+ dma_async_issue_pending(tc_22_25_chan);
+
+ msleep(1000);
+
+ dma_unmap_single(tc_22_25_chan->device->dev,
+ addr_src, size, DMA_BIDIRECTIONAL);
+
+ dma_unmap_single(tc_22_25_chan->device->dev,
+ addr_dst, size, DMA_FROM_DEVICE);
+
+ if (memcmp(buf_src, buf_dst, size) == 0)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+
+static void tc_24_transmit_cb(void *data)
+{
+ struct tc_struct *tc = data;
+ complete(&tc->done);
+}
+
+int tc_24_irq(void)
+{
+ dma_cap_mask_t mask;
+ dma_addr_t addr_src;
+ dma_addr_t addr_dst;
+ int size = 4096;
+ void *buf_src;
+ void *buf_dst;
+
+ struct tc_struct tc = {
+ .do_check_buffer = 1,
+ .laps = 1,
+ };
+ struct dma_async_tx_descriptor *desc;
+ init_completion(&tc.done);
+
+ if (tc_22_25_chan == NULL)
+ return -EINVAL;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+
+ buf_src = kzalloc(size, GFP_KERNEL);
+ memset(buf_src, 0xAA, size);
+ buf_dst = kzalloc(size, GFP_KERNEL);
+
+ addr_src = dma_map_single(tc_22_25_chan->device->dev,
+ buf_src, size, DMA_BIDIRECTIONAL);
+ addr_dst = dma_map_single(tc_22_25_chan->device->dev,
+ buf_dst, size, DMA_FROM_DEVICE);
+
+ desc = tc_22_25_chan->device->
+ device_prep_dma_memcpy(tc_22_25_chan,
+ addr_dst, addr_src, size,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
+ desc->callback = tc_24_transmit_cb;
+ desc->callback_param = &tc;
+ desc->tx_submit(desc);
+
+
+ dma_async_issue_pending(tc_22_25_chan);
+
+ /* block here until test case finished */
+ wait_for_completion_interruptible(&tc.done);
+
+ dma_unmap_single(tc_22_25_chan->device->dev,
+ addr_src, size, DMA_BIDIRECTIONAL);
+
+ dma_unmap_single(tc_22_25_chan->device->dev,
+ addr_dst, size, DMA_FROM_DEVICE);
+
+ if (memcmp(buf_src, buf_dst, size) == 0) {
+ kfree(buf_src);
+ kfree(buf_dst);
+ return 0;
+ } else {
+ kfree(buf_src);
+ kfree(buf_dst);
+ return -EINVAL;
+ }
+}
+
+int tc_25_free(void)
+{
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+
+ if (tc_22_25_chan == NULL)
+ return -EINVAL;
+
+ dma_release_channel(tc_22_25_chan);
+ tc_22_25_chan = NULL;
+
+ return 0;
+}
+
+struct tc_parallel {
+ char str[32];
+ int max_channels;
+ int laps;
+ unsigned long dma_flags;
+ int chan_start_index;
+ int tx_align;
+ int const_size;
+ int list_len;
+ int timeout;
+};
+
+static int tc_run_parallel(struct tc_parallel *tcp)
+{
+ struct tc_struct *tc;
+ int i;
+ int err = 0;
+ int max_channels;
+ bool use_const_size = tcp->const_size != -1;
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ tc = kzalloc(sizeof(struct tc_struct) * tcp->max_channels, GFP_KERNEL);
+ for (i = 0; i < tcp->max_channels; i++) {
+ tc[i].do_check_buffer = 1;
+ tc[i].laps = tcp->laps;
+ tc[i].end_padding = 64;
+ tc[i].list_len = tcp->list_len;
+
+ snprintf(tc[i].name, 32, "%s_%d", tcp->str, i);
+
+ tc[i].err = tc_test_init(&tc[i], false, tcp->const_size,
+ use_const_size, tcp->dma_flags,
+ tcp->tx_align, tcp->timeout);
+ if (tc[i].err)
+ break;
+ };
+ if (i == 0) {
+ err = -EINVAL;
+ goto out;
+ }
+ max_channels = i;
+
+ DBG_SPAM(printk(KERN_INFO "[%s] max available memcpy channels %d\n", tcp->str,
+ max_channels));
+
+ for (i = tcp->chan_start_index; i < max_channels; i++) {
+ DBG_SPAM(printk(KERN_INFO "starting %d\n", i));
+ tc_test_run(&tc[i]);
+ }
+
+ for (i = tcp->chan_start_index; i < max_channels; i++) {
+ tc_test_wait(&tc[i]);
+ DBG_SPAM(printk(KERN_INFO "[%s] %d done\n", tcp->str, i));
+ }
+
+ for (i = 0; i < max_channels; i++)
+ tc_test_free(&tc[i]);
+
+ for (i = 0; i < max_channels; i++)
+ err |= tc[i].err;
+
+ out:
+ kfree(tc);
+ return err;
+}
+
+static int tc_26_run_3_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_26",
+ .max_channels = 3,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+}
+
+static int tc_27_run_4_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_27",
+ .max_channels = 4,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+}
+
+static int tc_28_run_5_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_28",
+ .max_channels = 5,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+}
+
+static int tc_29_run_6_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_29",
+ .max_channels = 6,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+
+}
+
+static int tc_30_run_7_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_30",
+ .max_channels = 7,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+
+}
+
+static int tc_31_run_128_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_31",
+ .max_channels = 128,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+}
+
+static int tc_32_run_1_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_32",
+ .max_channels = 1,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+}
+
+static int tc_33_run_2_parallel(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_33",
+ .max_channels = 2,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+
+}
+
+static int tc_34_run_pause_and_unpause_parallel(void)
+{
+ return tc_pause_and_unpause_parallel(4, "tc_34",
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK, 1);
+}
+
+static int tc_35_run_1_parallel_reuse(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_35",
+ .max_channels = 1,
+ .laps = 20,
+ .dma_flags = DMA_PREP_INTERRUPT,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = 100*DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+
+}
+
+enum read_reg_type {
+ DMA_TC_READ_PHY_CHAN_1 = 1 << 0,
+ DMA_TC_READ_PHY_CHAN_2 = 1 << 1,
+ DMA_TC_READ_PHY_CHAN_3 = 1 << 2,
+ DMA_TC_READ_PHY_CHAN_4 = 1 << 3,
+ DMA_TC_READ_PHY_CHAN_5 = 1 << 4,
+ DMA_TC_READ_PHY_CHAN_6 = 1 << 5,
+ DMA_TC_READ_PHY_CHAN_7 = 1 << 6,
+ DMA_TC_READ_PHY_CHAN_8 = 1 << 7,
+ DMA_TC_READ_GLOBAL = 1 << 8,
+};
+
+
+#ifdef CONFIG_STE_DMA40_DEBUG
+extern void stedma40_debug_read_chan(int chan, u32 *cfg);
+extern void stedma40_debug_read_global_conf(u32 *cfg);
+static void tc_read_reg(unsigned long read_type)
+{
+ u32 cfg = 0;
+
+ if (read_type | DMA_TC_READ_PHY_CHAN_1)
+ stedma40_debug_read_chan(0, &cfg);
+ if (read_type | DMA_TC_READ_PHY_CHAN_2)
+ stedma40_debug_read_chan(1, &cfg);
+ if (read_type | DMA_TC_READ_PHY_CHAN_3)
+ stedma40_debug_read_chan(2, &cfg);
+ if (read_type | DMA_TC_READ_PHY_CHAN_4)
+ stedma40_debug_read_chan(3, &cfg);
+ if (read_type | DMA_TC_READ_PHY_CHAN_5)
+ stedma40_debug_read_chan(4, &cfg);
+ if (read_type | DMA_TC_READ_PHY_CHAN_6)
+ stedma40_debug_read_chan(5, &cfg);
+ if (read_type | DMA_TC_READ_PHY_CHAN_7)
+ stedma40_debug_read_chan(6, &cfg);
+ if (read_type | DMA_TC_READ_PHY_CHAN_8)
+ stedma40_debug_read_chan(7, &cfg);
+ if (read_type | DMA_TC_READ_GLOBAL)
+ stedma40_debug_read_global_conf(&cfg);
+}
+
+
+int tc_run_while_read_reg(char *str, int max_channels, int size, int list_len,
+ int laps, bool is_sg, bool is_const_size,
+ unsigned long dma_flags, unsigned long read_type)
+{
+ struct tc_struct *tc;
+ int i;
+ int err = 0;
+
+ DBG_SPAM(printk(KERN_INFO "[%s]\n", __func__));
+
+ sted40_history_disable();
+
+ tc = kzalloc(sizeof(struct tc_struct) * max_channels, GFP_KERNEL);
+ for (i = 0; i < max_channels; i++) {
+ tc[i].do_check_buffer = 1;
+ tc[i].laps = laps;
+ tc[i].end_padding = 64;
+ tc[i].list_len = list_len;
+
+ snprintf(tc[i].name, 32, "%s_%d", str, i);
+
+ tc[i].err = tc_test_init(&tc[i], is_sg, size, is_const_size,
+ dma_flags, TX_ALIGN,
+ DEFAULT_TIMEOUT);
+ if (tc[i].err)
+ break;
+ };
+ if (i == 0) {
+ err = -EINVAL;
+ goto out;
+ }
+ max_channels = i;
+
+ DBG_SPAM(printk(KERN_INFO "[%s] max available memcpy channels %d\n", str, max_channels));
+
+ for (i = 0; i < max_channels; i++)
+ tc_test_run(&tc[i]);
+
+ for (i = 0; i < max_channels; i++) {
+ while (!tc_test_is_done(&tc[i]))
+ tc_read_reg(read_type);
+ DBG_SPAM(printk(KERN_INFO "[%s] %d done\n", str, i));
+ }
+
+ for (i = 0; i < max_channels; i++)
+ tc_test_free(&tc[i]);
+
+ for (i = 0; i < max_channels; i++)
+ err |= tc[i].err;
+
+out:
+ kfree(tc);
+ return err;
+}
+
+static int tc_36(void)
+{
+ return tc_run_while_read_reg("tc_36", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_1);
+}
+static int tc_37(void)
+{
+ return tc_run_while_read_reg("tc_37", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_2);
+}
+static int tc_38(void)
+{
+ return tc_run_while_read_reg("tc_38", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_3);
+}
+static int tc_39(void)
+{
+ return tc_run_while_read_reg("tc_39", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_4);
+}
+static int tc_40(void)
+{
+ return tc_run_while_read_reg("tc_40", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_5);
+}
+static int tc_41(void)
+{
+ return tc_run_while_read_reg("tc_41", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_6);
+}
+static int tc_42(void)
+{
+ return tc_run_while_read_reg("tc_42", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_7);
+}
+static int tc_43(void)
+{
+ return tc_run_while_read_reg("tc_43", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_GLOBAL);
+}
+static int tc_44(void)
+{
+ return tc_run_while_read_reg("tc_44", 1, 1024, 30, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_1 |
+ DMA_TC_READ_PHY_CHAN_2 |
+ DMA_TC_READ_PHY_CHAN_3 |
+ DMA_TC_READ_PHY_CHAN_4 |
+ DMA_TC_READ_PHY_CHAN_5 |
+ DMA_TC_READ_PHY_CHAN_6 |
+ DMA_TC_READ_PHY_CHAN_7 |
+ DMA_TC_READ_GLOBAL);
+}
+static int tc_45(void)
+{
+ return tc_run_while_read_reg("tc_45", 1, 1024, 30, 10, true, false,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_1 |
+ DMA_TC_READ_PHY_CHAN_2 |
+ DMA_TC_READ_PHY_CHAN_3 |
+ DMA_TC_READ_PHY_CHAN_4 |
+ DMA_TC_READ_PHY_CHAN_5 |
+ DMA_TC_READ_PHY_CHAN_6 |
+ DMA_TC_READ_PHY_CHAN_7 |
+ DMA_TC_READ_GLOBAL);
+}
+static int tc_46(void)
+{
+ return tc_run_while_read_reg("tc_46", 1, 128, 100, 10, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_1 |
+ DMA_TC_READ_PHY_CHAN_2 |
+ DMA_TC_READ_PHY_CHAN_3 |
+ DMA_TC_READ_PHY_CHAN_4 |
+ DMA_TC_READ_PHY_CHAN_5 |
+ DMA_TC_READ_PHY_CHAN_6 |
+ DMA_TC_READ_PHY_CHAN_7 |
+ DMA_TC_READ_GLOBAL);
+}
+static int tc_47(void)
+{
+ return tc_run_while_read_reg("tc_47", 1, 128, 100, 10, true, false,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_1 |
+ DMA_TC_READ_PHY_CHAN_2 |
+ DMA_TC_READ_PHY_CHAN_3 |
+ DMA_TC_READ_PHY_CHAN_4 |
+ DMA_TC_READ_PHY_CHAN_5 |
+ DMA_TC_READ_PHY_CHAN_6 |
+ DMA_TC_READ_PHY_CHAN_7 |
+ DMA_TC_READ_GLOBAL);
+}
+static int tc_48(void)
+{
+ return tc_run_while_read_reg("tc_48", 1, 128, 200, 1000, true, true,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_1 |
+ DMA_TC_READ_PHY_CHAN_2 |
+ DMA_TC_READ_PHY_CHAN_3 |
+ DMA_TC_READ_PHY_CHAN_4 |
+ DMA_TC_READ_PHY_CHAN_5 |
+ DMA_TC_READ_PHY_CHAN_6 |
+ DMA_TC_READ_PHY_CHAN_7 |
+ DMA_TC_READ_GLOBAL);
+}
+static int tc_49(void)
+{
+ return tc_run_while_read_reg("tc_49", 1, 128, 200, 1000, true, false,
+ DMA_PREP_INTERRUPT,
+ DMA_TC_READ_PHY_CHAN_1 |
+ DMA_TC_READ_PHY_CHAN_2 |
+ DMA_TC_READ_PHY_CHAN_3 |
+ DMA_TC_READ_PHY_CHAN_4 |
+ DMA_TC_READ_PHY_CHAN_5 |
+ DMA_TC_READ_PHY_CHAN_6 |
+ DMA_TC_READ_PHY_CHAN_7 |
+ DMA_TC_READ_GLOBAL);
+}
+#endif
+
+static int tc_50(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_50",
+ .max_channels = 5,
+ .laps = 200,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 3,
+ .tx_align = 4,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+}
+
+static int tc_51(void)
+{
+ return tc_pause_and_unpause_parallel(2, "tc_51",
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK, 4);
+}
+
+static int tc_52(void)
+{
+ return tc_pause_and_unpause_parallel(4, "tc_52",
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK, 4);
+}
+
+static int tc_53(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_53",
+ .max_channels = 5,
+ .laps = 200,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 3,
+ .tx_align = 1,
+ .const_size = -1,
+ .list_len = 30,
+ .timeout = DEFAULT_TIMEOUT,
+ };
+
+ return tc_run_parallel(&tcp);
+
+}
+
+static int tc_54_trigger(void)
+{
+ struct tc_parallel tcp = {
+ .str = "tc_54",
+ .max_channels = 5,
+ .laps = 1,
+ .dma_flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ .chan_start_index = 0,
+ .tx_align = 1,
+ .const_size = 1024,
+ .list_len = 4, /* Must >2 to tigger error, when we had 4 log
+ memcpy channsl */
+ .timeout = 1000, /* 1s*/
+ };
+
+ return tc_run_parallel(&tcp);
+}
+
+struct tc_link_cfg {
+ int tc;
+ int jobs;
+ int links;
+ int buffer_size;
+ bool request_phys;
+ bool start_in_sequence;
+ bool slow_start;
+ /* randomize */
+ u32 min_size;
+ u32 max_size;
+};
+
+struct tc_link {
+ struct buflist buflist;
+ struct completion done;
+ struct dma_async_tx_descriptor *desc;
+};
+
+
+static void tc_link_callback(void *data)
+{
+ struct tc_link *tc = data;
+ complete(&tc->done);
+}
+
+/* used for testing job linking */
+static int tc_link_core(struct tc_link_cfg *cfg)
+{
+
+ int i;
+ int err = 0;
+ char name[MAX_NAME_LEN];
+ struct dma_chan *dma_chan = NULL;
+
+ struct tc_link *tc;
+
+
+ tc = kmalloc(cfg->jobs * sizeof(struct tc_link), GFP_KERNEL);
+ if (!tc)
+ goto done;
+
+ for (i = 0 ; i < cfg->jobs; i++) {
+
+ snprintf(name, MAX_NAME_LEN - 1, "%s_tc_%d_%.2d",
+ __func__, cfg->tc, i);
+ err = dmatest_buflist_create(&tc[i].buflist, cfg->links, 0,
+ name,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
+ DEFAULT_TIMEOUT, cfg->request_phys,
+ dma_chan);
+ if (err)
+ /* Leaks previous allocated buflists */
+ goto done;
+ if (cfg->min_size && cfg->max_size)
+ dmatest_sizelist_randomize(&tc->buflist, cfg->min_size,
+ cfg->max_size, TX_ALIGN);
+ else
+ dmatest_sizelist_set(&tc[i].buflist, cfg->buffer_size,
+ TX_ALIGN);
+
+ dmatest_buflist_alloc(&tc[i].buflist);
+
+ dma_chan = tc[i].buflist.dma_chan;
+
+ tc[i].buflist.sgl_src_len =
+ dma_map_sg(tc[i].buflist.dma_chan->device->dev,
+ tc[i].buflist.sgl_src,
+ tc[i].buflist.list_len,
+ DMA_BIDIRECTIONAL);
+ tc[i].buflist.sgl_dst_len =
+ dma_map_sg(tc[i].buflist.dma_chan->device->dev,
+ tc[i].buflist.sgl_dst,
+ tc[i].buflist.list_len,
+ /* Both direction for verifying transfered data */
+ DMA_BIDIRECTIONAL);
+
+ tc[i].desc = dma_chan->device->device_prep_dma_sg(dma_chan,
+ tc[i].buflist.sgl_dst,
+ tc[i].buflist.sgl_dst_len,
+ tc[i].buflist.sgl_src,
+ tc[i].buflist.sgl_src_len,
+ tc[i].buflist.dma_engine_flags);
+ init_completion(&tc[i].done);
+ tc[i].desc->callback = tc_link_callback;
+ tc[i].desc->callback_param = &tc[i];
+ }
+
+ if (cfg->start_in_sequence) {
+ for (i = 0; i < cfg->jobs; i++) {
+ tc[i].desc->tx_submit(tc[i].desc);
+ dma_async_issue_pending(dma_chan);
+
+ if (cfg->slow_start)
+ udelay(500);
+ }
+ } else {
+
+ for (i = 0; i < cfg->jobs; i++)
+ tc[i].desc->tx_submit(tc[i].desc);
+
+ dma_async_issue_pending(dma_chan);
+ }
+
+ for (i = 0; i < cfg->jobs; i++) {
+ wait_for_completion_interruptible(&tc[i].done);
+ err |= dmatest_buflist_payload_check(&tc[i].buflist);
+ }
+
+ for (i = 0; i < cfg->jobs; i++) {
+ tc[i].buflist.dma_chan = dma_chan;
+ dmatest_buflist_destroy(&tc[i].buflist);
+ dma_chan = NULL;
+ }
+done:
+ kfree(tc);
+ return err;
+}
+
+static int tc_55(void)
+{
+ /* Link 2 jobs in hw before start transfer (physical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 55,
+ .jobs = 2,
+ .links = 5, /* Just > 1 is enough */
+ .buffer_size = SZ_4K, /* Just something big */
+ .request_phys = true,
+ .start_in_sequence = false,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_56(void)
+{
+ /* Link 2 jobs in hw after first job has started (physical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 56,
+ .jobs = 2,
+ .links = 5, /* Just > 1 is enough */
+ .buffer_size = SZ_4K, /* Just something big */
+ .request_phys = true,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_57(void)
+{
+ /* Link 2 jobs in hw after first job has started (physical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 57,
+ .jobs = 2,
+ .links = 1, /* No links */
+ .buffer_size = SZ_16K, /* Just something big */
+ .request_phys = true,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_58(void)
+{
+ /* Link 10 jobs in hw after first job has started (physical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 58,
+ .jobs = 10,
+ .links = 1, /* No links */
+ .buffer_size = SZ_16K, /* Just something big */
+ .request_phys = true,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_59(void)
+{
+ /* Link 10 jobs in hw after first job has started (physical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 59,
+ .jobs = 10,
+ .links = 10,
+ .buffer_size = SZ_4K, /* Just something big */
+ .request_phys = true,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+
+static int tc_60(void)
+{
+ /* Link 2 jobs in hw before start transfer (logical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 60,
+ .jobs = 2,
+ .links = 2, /* Just > 1 is enough */
+ .buffer_size = 4096, /* Just something big */
+ .request_phys = false,
+ .start_in_sequence = false,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_61(void)
+{
+ /* Link 2 jobs in hw after first job has started (logical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 61,
+ .jobs = 2,
+ .links = 2, /* Just > 1 is enough */
+ .buffer_size = 4096, /* Just something big */
+ .request_phys = false,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_62(void)
+{
+ /*
+ * Test to transfer a logical job with >64 links (Out of lcla space
+ * then.)
+ */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 62,
+ .jobs = 1,
+ .links = 90,
+ .buffer_size = 128,
+ .request_phys = false,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_63(void)
+{
+ /*
+ * Test to transfer a logical job with >124 links (Out of lcla space
+ * then.)
+ */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 63,
+ .jobs = 1,
+ .links = 140,
+ .buffer_size = 128,
+ .request_phys = false,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_64(void)
+{
+ /* Test allocate 4 80 lli long jobs before starting */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 64,
+ .jobs = 4,
+ .links = 80,
+ .buffer_size = 128,
+ .request_phys = false,
+ .start_in_sequence = false,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_65(void)
+{
+ /* Link 10 jobs in hw after first job has started (logical) */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 59,
+ .jobs = 10,
+ .links = 10,
+ .buffer_size = SZ_4K, /* Just something big */
+ .request_phys = false,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_66(void)
+{
+ /*
+ * Link 10 jobs in hw after first job has started (logical),
+ * no links
+ */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 58,
+ .jobs = 10,
+ .links = 1, /* No links */
+ .buffer_size = SZ_16K, /* Just something big */
+ .request_phys = false,
+ .start_in_sequence = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_67(void)
+{
+ /* Link 10 jobs in hw after first job has started (logical), slowly */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 59,
+ .jobs = 10,
+ .links = 10,
+ .buffer_size = SZ_4K, /* Just something big */
+ .request_phys = false,
+ .start_in_sequence = true,
+ .slow_start = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_68(void)
+{
+ /* Link 10 jobs in hw after first job has started (physical), slowly */
+ struct tc_link_cfg tc_cfg = {
+ .tc = 59,
+ .jobs = 10,
+ .links = 10,
+ .buffer_size = SZ_4K, /* Just something big */
+ .request_phys = true,
+ .start_in_sequence = true,
+ .slow_start = true,
+ };
+
+ return tc_link_core(&tc_cfg);
+}
+
+static int tc_69(void)
+{
+ int err = 0;
+ int i;
+
+ /* Test large transfer than 64k */
+ struct tc_link_cfg tc_cfg[] = {
+ {
+ .tc = 69,
+ .jobs = 1,
+ .links = 10,
+ .buffer_size = 0x10000 - 1,
+ },
+ {
+ .tc = 69,
+ .jobs = 1,
+ .links = 10,
+ .buffer_size = 0x10000,
+ },
+ {
+ .tc = 69,
+ .jobs = 1,
+ .links = 10,
+ .buffer_size = 0x10000 + 1,
+ },
+ {
+ .tc = 69,
+ .jobs = 1,
+ .links = 10,
+ .buffer_size = 2*0x10000 - 1,
+ },
+ {
+ .tc = 69,
+ .jobs = 1,
+ .links = 10,
+ .buffer_size = 2*0x10000,
+ },
+ {
+ .tc = 69,
+ .jobs = 1,
+ .links = 10,
+ .buffer_size = 2*0x10000 + 1,
+ },
+ };
+ for (i = 0; i < ARRAY_SIZE(tc_cfg); i++) {
+ printk(KERN_INFO "[%s] %d out of %d\n", __func__,
+ i, ARRAY_SIZE(tc_cfg));
+ err = tc_link_core(&tc_cfg[i]);
+ if (err)
+ goto out;
+ }
+
+ out:
+ return err;
+}
+
+static int tc_nop(struct seq_file *s, int id)
+{
+ int err;
+ err = seq_printf(s, "TEST_%d is removed\n", id);
+ return err;
+}
+
+static int d40_test_run(struct seq_file *s, void *iter)
+{
+ int test_id = (int) s->private;
+ int err = -EINVAL;
+ char *str = "";
+
+ err = mutex_lock_interruptible(&tc_mutex);
+
+ /* the out put from these tests are actually a test script
+ * echo is needed in order to display the result
+ */
+#if defined(CONFIG_MMC) && defined(CONFIG_STE_DMA40_DEBUG)
+ switch (test_id) {
+ case TEST10:
+ case TEST11:
+ case TEST12:
+ case TEST13:
+ str = "echo ";
+ break;
+ }
+#endif
+ if (err)
+ goto out;
+
+ switch (test_id) {
+ case TEST1:
+ err = tc_1_fixed_buffer();
+ break;
+ case TEST2:
+ err = tc_2_fixed_buffer();
+ break;
+ case TEST3:
+ err = tc_3_fixed_buffer();
+ break;
+ case TEST4:
+ err = tc_4_fixed_buffer();
+ break;
+ case TEST5:
+ err = tc_5_random_buffer();
+ break;
+ case TEST6:
+ err = tc_6_sg_buffer();
+ break;
+ case TEST7:
+ err = tc_7_sg_buffer();
+ break;
+ case TEST8:
+ err = tc_8_sg_buffer();
+ break;
+ case TEST9:
+ err = tc_9_sg_buffer();
+ break;
+#if defined(CONFIG_MMC) && defined(CONFIG_STE_DMA40_DEBUG)
+ case TEST10:
+ err = tc_10_sg_size_1024_one(s);
+ str = "echo ";
+ break;
+ case TEST11:
+ err = tc_11_sg_size_chain_one(s);
+ str = "echo ";
+ break;
+ case TEST12:
+ err = tc_12_sg_size_1024_many(s);
+ str = "echo ";
+ break;
+ case TEST13:
+ err = tc_13_sg_size_1024_chain_many(s);
+ str = "echo ";
+ break;
+ case TEST14:
+ err = tc_14_sg_buffer_temporary_endless();
+ break;
+#else
+ case TEST10:
+ case TEST11:
+ case TEST12:
+ case TEST13:
+ case TEST14:
+ err = tc_nop(s, test_id);
+ break;
+#endif
+ case TEST15:
+ err = tc_15_static_buffer();
+ break;
+ case TEST16:
+ err = tc_16_static_buffer();
+ break;
+ case TEST17:
+ err = tc_17_static_buffer();
+ break;
+ case TEST18:
+ err = tc_18_static_buffer();
+ break;
+ case TEST19:
+ err = tc_19_static_buffer();
+ break;
+ case TEST20:
+ err = tc_20_random_buffer();
+ break;
+ case TEST21:
+ err = tc_21_stop_and_go();
+ break;
+ case TEST22:
+ case TEST23:
+ case TEST24:
+ case TEST25:
+ err = tc_22_req();
+ if (!err)
+ err = tc_23_no_irq();
+ if (!err)
+ err = tc_24_irq();
+ if (!err)
+ err = tc_25_free();
+ break;
+ case TEST26:
+ err = tc_26_run_3_parallel();
+ break;
+ case TEST27:
+ err = tc_27_run_4_parallel();
+ break;
+ case TEST28:
+ err = tc_28_run_5_parallel();
+ break;
+ case TEST29:
+ err = tc_29_run_6_parallel();
+ break;
+ case TEST30:
+ err = tc_30_run_7_parallel();
+ break;
+ case TEST31:
+ err = tc_31_run_128_parallel();
+ break;
+ case TEST32:
+ err = tc_32_run_1_parallel();
+ break;
+ case TEST33:
+ err = tc_33_run_2_parallel();
+ break;
+ case TEST34:
+ err = tc_34_run_pause_and_unpause_parallel();
+ break;
+ case TEST35:
+ err = tc_35_run_1_parallel_reuse();
+ break;
+
+#ifdef CONFIG_STE_DMA40_DEBUG
+ case TEST36:
+ err = tc_36();
+ break;
+ case TEST37:
+ err = tc_37();
+ break;
+ case TEST38:
+ err = tc_38();
+ break;
+ case TEST39:
+ err = tc_39();
+ break;
+ case TEST40:
+ err = tc_40();
+ break;
+ case TEST41:
+ err = tc_41();
+ break;
+ case TEST42:
+ err = tc_42();
+ break;
+ case TEST43:
+ err = tc_43();
+ break;
+ case TEST44:
+ err = tc_44();
+ break;
+ case TEST45:
+ err = tc_45();
+ break;
+ case TEST46:
+ err = tc_46();
+ break;
+ case TEST47:
+ err = tc_47();
+ break;
+ case TEST48:
+ err = tc_48();
+ break;
+ case TEST49:
+ err = tc_49();
+ break;
+#else
+ case TEST36:
+ case TEST37:
+ case TEST38:
+ case TEST39:
+ case TEST40:
+ case TEST41:
+ case TEST42:
+ case TEST43:
+ case TEST44:
+ case TEST45:
+ case TEST46:
+ case TEST47:
+ case TEST48:
+ case TEST49:
+ err = tc_nop(s, test_id);
+ break;
+#endif
+ case TEST50:
+ err = tc_50();
+ break;
+ case TEST51:
+ err = tc_51();
+ break;
+ case TEST52:
+ err = tc_52();
+ break;
+ case TEST53:
+ err = tc_53();
+ break;
+ case TEST54:
+ err = tc_54_trigger();
+ break;
+ case TEST55:
+ err = tc_55();
+ break;
+ case TEST56:
+ err = tc_56();
+ break;
+ case TEST57:
+ err = tc_57();
+ break;
+ case TEST58:
+ err = tc_58();
+ break;
+ case TEST59:
+ err = tc_59();
+ break;
+ case TEST60:
+ err = tc_60();
+ break;
+ case TEST61:
+ err = tc_61();
+ break;
+ case TEST62:
+ err = tc_62();
+ break;
+ case TEST63:
+ err = tc_63();
+ break;
+ case TEST64:
+ err = tc_64();
+ break;
+ case TEST65:
+ err = tc_65();
+ break;
+ case TEST66:
+ err = tc_66();
+ break;
+ case TEST67:
+ err = tc_67();
+ break;
+ case TEST68:
+ err = tc_68();
+ break;
+ case TEST69:
+ err = tc_69();
+ break;
+
+ default:
+ err = -EINVAL;
+ printk(KERN_INFO "# [%s] Invalid test id %d\n", __func__,
+ test_id);
+ }
+
+out:
+ seq_printf(s, "%sFinished test %d: %s\n", str, test_id,
+ err == 0 ? "OK" : "***FAIL***");
+
+ mutex_unlock(&tc_mutex);
+ return 0;
+}
+
+
+static struct dentry *debugfs_dir;
+
+static int d40_debugfs_open(struct inode *inode,
+ struct file *file)
+{
+ int err;
+
+ err = single_open(file,
+ d40_test_run,
+ inode->i_private);
+
+ return err;
+}
+
+static const struct file_operations d40_debugfs_ops = {
+ .open = d40_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init stedma40_test_init(void)
+{
+ char name[32];
+ int i;
+ int err = 0;
+ void *err_ptr = NULL;
+
+ err = mutex_lock_interruptible(&tc_mutex);
+ if (err)
+ goto err;
+
+ printk(KERN_INFO "[%s] dma-test-module build: %s %s nbr tests %d\n",
+ __func__, __DATE__, __TIME__, NBR_TESTS - 1);
+
+ debugfs_dir = debugfs_create_dir("ste_dma40_test", NULL);
+ if (IS_ERR(debugfs_dir)) {
+ err = PTR_ERR(debugfs_dir);
+ goto out;
+ }
+
+ for (i = 1; i < NBR_TESTS; i++) {
+ err = snprintf(name, 32, "test_%d", i);
+ if (err < 0)
+ goto out;
+ err = 0;
+
+ err_ptr = debugfs_create_file(name,
+ S_IFREG | S_IRUGO,
+ debugfs_dir, (void *)i,
+ &d40_debugfs_ops);
+ if (IS_ERR(err_ptr)) {
+ err = PTR_ERR(err_ptr);
+ goto out;
+ }
+ }
+
+ out:
+ mutex_unlock(&tc_mutex);
+ err:
+ return err;
+}
+module_init(stedma40_test_init);
+
+static void __exit stedma40_test_exit(void)
+{
+ DBG_TEST(printk(KERN_INFO "[%s]\n", __func__));
+
+ sted40_history_reset();
+
+ debugfs_remove_recursive(debugfs_dir);
+}
+module_exit(stedma40_test_exit);
+
+
diff --git a/kernel/testcases/dma/user-space/Makefile b/kernel/testcases/dma/user-space/Makefile
new file mode 100644
index 0000000..e950b1f
--- /dev/null
+++ b/kernel/testcases/dma/user-space/Makefile
@@ -0,0 +1,26 @@
+ifeq ($(KERNELRELEASE),)
+LTP_DIR = $(abspath ../../../../)
+LTP_FRAMEWORK = $(LTP_DIR)/ltp_framework
+
+SCRIPTS=$(wildcard *.sh)
+
+CFLAGS+= -I$(LTP_FRAMEWORK)/include -I$(abspath ./include)
+LOADLIBES+= -L$(LTP_FRAMEWORK)/lib -lltp
+
+TARGETS=dma
+OBJS=dma.o
+
+all: $(TARGETS)
+
+$(TARGETS): $(TARGETS) $(OBJS)
+
+install:
+ @for i in $(TARGETS); do if [ -f $(DESTDIR)/opt/ltp/testcases/bin/$$i ]; then rm $(DESTDIR)/opt/ltp/testcases/bin/$$i; fi ; done
+ @for i in $(TARGETS); do install -D $$i $(DESTDIR)/opt/ltp/testcases/bin/$$i ; done
+ @for i in $(SCRIPTS); do if [ -f $(DESTDIR)/opt/ltp/testcases/bin/$$i ]; then rm $(DESTDIR)/opt/ltp/testcases/bin/$$i; fi ; done
+ @for i in $(SCRIPTS); do install -D $$i $(DESTDIR)/opt/ltp/testcases/bin/$$i ; done
+
+clean:
+ rm -f $(TARGETS)
+ rm -f $(OBJS)
+endif
diff --git a/kernel/testcases/dma/user-space/dma.c b/kernel/testcases/dma/user-space/dma.c
new file mode 100644
index 0000000..f3dd062
--- /dev/null
+++ b/kernel/testcases/dma/user-space/dma.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: 2010, Martin Persson <martin.persson@stericsson.com>,
+ * Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+
+#include "test.h"
+#include "usctest.h"
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <linux/input.h>
+
+
+
+/* Extern Global Variables */
+extern int Tst_count; /* counter for tst_xxx routines. */
+extern char *TESTDIR; /* temporary dir created by tst_tmpdir() */
+
+/* Global Variables */
+char *TCID = "dma";
+
+int test_cases[] = {
+ 22, 23, 24, 25, 1, 2, 3, 4, 6, 7, 8,
+ 21, 15, 16, 17, 18, 19, 20, 21, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68,
+
+ /* run long tests near the end */
+ 26, 7, 32, 33, 5, 34, 27, 28, 29,
+
+ /*
+ * The following fail:
+ *
+ * This due to hardware error V1, should be fixed in V2:
+ * 30, 31, 35, 51
+ *
+ * These fail due to unknown reason:
+ * 9
+ */
+};
+
+/* total number of tests in this file. */
+int TST_TOTAL = sizeof(test_cases);
+
+static int dma_test(int id)
+{
+ int fd = 0, size, err = 0;
+ char fname[256], buff[256], answer[256];
+
+ sprintf(fname, "/sys/kernel/debug/ste_dma40_test/test_%d", id);
+
+ fd = open(fname, O_RDONLY);
+
+ if (fd < 0) {
+ err = -1;
+ goto _exit;
+ }
+ memset(buff, 0, 256);
+ size = read(fd, buff, 255);
+ if (size <= 0) {
+ err = -2;
+ goto _exit;
+ }
+
+ sprintf(answer, "Finished test %d: OK\n", id);
+ if (size != strlen(answer)) {
+ printf("DMA testcase %d failed\n", id);
+ err = -3;
+ goto _exit;
+ }
+
+ if (strncmp(buff, answer, strlen(answer))) {
+ printf("DMA testcase %d failed\n", id);
+ err = -4;
+ }
+
+_exit:
+ if (fd > 0)
+ close(fd);
+
+ return err;
+}
+
+static int n_opt;
+static char *n_copt;
+static int testnum;
+
+static option_t options[] = {
+ { "n:", &n_opt, &n_copt },
+ { },
+};
+
+int main(int argc, char **argv)
+{
+
+ int lc; /* loop counter */
+ char *msg; /* message returned from parse_opts */
+
+ /***************************************************************
+ * parse standard options
+ ***************************************************************/
+ if ((msg = parse_opts(argc, argv, options, NULL)) != (char *) NULL) {
+ tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
+ tst_exit();
+ }
+
+ if (n_opt) {
+ testnum = atoi(n_copt);
+ TST_TOTAL = 1;
+ }
+
+ system("modprobe stedma40_test");
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ /***************************************************************
+ * only perform functional verification if flag set (-f not given)
+ ***************************************************************/
+ if (STD_FUNCTIONAL_TEST) {
+
+ for (Tst_count = 0; Tst_count < TST_TOTAL;) {
+ int num;
+
+ num = TST_TOTAL == 1 ?
+ testnum : test_cases[Tst_count];
+
+ TEST(dma_test(num));
+
+ if (TEST_RETURN == 0)
+ tst_resm(TPASS, "Functional test %d OK\n", num);
+ else
+ tst_resm(TFAIL, "Return value: %d. TCID: %s (%d) File: %s Line: %d. errno=%d : %s \n",
+ TEST_RETURN, TCID, num, __FILE__, __LINE__,
+ TEST_ERRNO, strerror(TEST_ERRNO));
+
+ }
+ }
+ }
+
+ system("modprobe -r stedma40_test");
+
+ tst_exit();
+ return 0;
+}
diff --git a/kernel/testcases/dma/user-space/dma_test_all.sh b/kernel/testcases/dma/user-space/dma_test_all.sh
new file mode 100755
index 0000000..3a3aa94
--- /dev/null
+++ b/kernel/testcases/dma/user-space/dma_test_all.sh
@@ -0,0 +1,81 @@
+#/*
+# * Copyright (C) ST-Ericsson SA 2010
+# * License Terms: GNU General Public License, version 2
+# */
+
+# Runs all test for DMA
+TEST_MODULE_NAME=stedma40_test
+TEST_DIR=/sys/kernel/debug/ste_dma40_test
+TEST_TMP_FILE=/.dma_run_test.sh
+
+echo "Loading test module $TEST_MODULE"
+modprobe $TEST_MODULE_NAME
+cd $TEST_DIR
+
+cat test_22
+cat test_23
+cat test_24
+cat test_25
+
+cat test_1
+cat test_2
+cat test_3
+cat test_4
+cat test_6
+cat test_7
+cat test_8
+
+# Testing dma using MMC
+cat test_10 > $TEST_TMP_FILE
+sh $TEST_TMP_FILE
+cat test_11 > $TEST_TMP_FILE
+sh $TEST_TMP_FILE
+cat test_12 > $TEST_TMP_FILE
+sh $TEST_TMP_FILE
+cat test_13 > $TEST_TMP_FILE
+sh $TEST_TMP_FILE
+
+# Endless test case, skip it here
+# cat test_14
+
+cat test_21
+cat test_15
+cat test_16
+cat test_17
+cat test_18
+cat test_19
+cat test_20
+cat test_21
+cat test_55
+cat test_56
+cat test_57
+cat test_58
+cat test_59
+cat test_60
+cat test_61
+cat test_62
+cat test_63
+cat test_64
+
+cat test_26
+# run long tests near the end
+cat test_7
+cat test_32
+cat test_33
+cat test_5
+cat test_34
+cat test_27
+cat test_28
+cat test_29
+
+# The following fails:
+# This due to hardware error V1, should be fixed in V2.
+# cat test_30
+# cat test_31
+# cat test_35
+# cat test_51
+# These fail due to unknown reason.
+# cat test_9
+#
+
+rmmod $TEST_MODULE_NAME
diff --git a/ltp_framework/ChangeLog b/ltp_framework/ChangeLog
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ltp_framework/ChangeLog
@@ -0,0 +1 @@
+
diff --git a/ltp_framework/IDcheck.sh b/ltp_framework/IDcheck.sh
new file mode 100755
index 0000000..d453c91
--- /dev/null
+++ b/ltp_framework/IDcheck.sh
@@ -0,0 +1,189 @@
+#!/bin/sh
+#
+# Copyright (c) International Business Machines Corp., 2001
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# FILE : IDcheck.sh
+# DESCRIPTION : checks for req'd users/groups and will create them if requested.
+# HISTORY : see the cvs log
+#
+
+# Prompt user if ids/groups should be created
+echo "Checking for required user/group ids"
+echo ""
+
+# Check ids and create if needed.
+NO_NOBODY_ID=1
+NO_BIN_ID=1
+NO_DAEMON_ID=1
+NO_NOBODY_GRP=1
+NO_BIN_GRP=1
+NO_DAEMON_GRP=1
+NO_USERS_GRP=1
+NO_SYS_GRP=1
+
+group="$DESTDIR/etc/group"
+passwd="$DESTDIR/etc/passwd"
+
+# find entry.
+fe() {
+ ID=$1
+ FILE=$2
+ [ -e "$FILE" ] || return $?
+ grep -q "^$ID:" "$FILE"
+}
+
+prompt_for_create() {
+ if [ -z "$CREATE_ENTRIES" ] ; then
+
+ if [ $NO_NOBODY_ID -ne 0 -o $NO_BIN_ID -ne 0 -o $NO_DAEMON_ID -ne 0 -o $NO_NOBODY_GRP -ne 0 -o $NO_BIN_GRP -ne 0 -o $NO_DAEMON_GRP -ne 0 -o $NO_USERS_GRP -ne 0 -o $NO_SYS_GRP -ne 0 ] ; then
+ echo -n "If any required user ids and/or groups are missing, would you like these created? [y/N]"
+ read ans
+ case "$ans" in
+ [Yy]*) CREATE_ENTRIES=1 ;;
+ *) CREATE_ENTRIES=0 ;;
+ esac
+ else
+ CREATE_ENTRIES=0
+ fi
+
+ fi
+}
+
+if [ -z ${EUID} ] ; then
+ EUID=$(id -u)
+fi
+
+for i in "$passwd" "$group"; do
+ if [ -e "$i" -a ! -r "$i" ] ; then
+ echo "$i not readable by uid $EUID"
+ exit 1
+ fi
+done
+
+fe bin "$passwd"; NO_BIN_ID=$?
+fe daemon "$passwd"; NO_DAEMON_ID=$?
+fe nobody "$passwd"; NO_NOBODY_ID=$?
+
+fe bin "$group"; NO_BIN_GRP=$?
+fe daemon "$group"; NO_DAEMON_GRP=$?
+fe nobody "$group" || fe nogroup "$group"; NO_NOBODY_GRP=$?
+fe sys "$group"; NO_SYS_GRP=$?
+fe users "$group"; NO_USERS_GRP=$?
+
+prompt_for_create
+
+debug_vals() {
+
+echo "Missing the following group / user entries:"
+echo "Group file: $group"
+echo "Password file: $passwd"
+echo "nobody: $NO_NOBODY_ID"
+echo "bin: $NO_BIN_ID"
+echo "daemon: $NO_DAEMON_ID"
+echo "nobody[/nogroup] grp: $NO_NOBODY_GRP"
+echo "bin grp: $NO_BIN_GRP"
+echo "daemon grp: $NO_DAEMON_GRP"
+echo "sys grp: $NO_SYS_GRP"
+echo "users grp: $NO_USERS_GRP"
+echo ""
+
+}
+
+#debug_vals
+
+if [ $CREATE_ENTRIES -ne 0 ] ; then
+ if ! touch "$group" "$passwd" 2>/dev/null; then
+ echo "Failed to touch $group or $passwd"
+ exit 1
+ fi
+fi
+
+make_user_group() {
+ local name=$1 id=$2 no_id=$3 no_grp=$4
+
+ if [ $no_id -eq 0 -a $no_grp -eq 0 ] ; then
+ echo "'$name' user id and group found."
+ elif [ $CREATE_ENTRIES -ne 0 ] ; then
+ echo "Creating entries for $name"
+
+ # Avoid chicken and egg issue with id(1) call
+ # made above and below.
+ if ! fe "$name" "$passwd" && [ $no_id -ne 0 ] ; then
+ echo "${name}:x:${id}:${id}:${name}::" >> "$passwd"
+ fi
+ if [ $no_grp -ne 0 ] ; then
+ echo "${name}:x:$(id -u ${name}):" >> "$group"
+ fi
+ fi
+}
+make_user_group nobody 65534 $NO_NOBODY_ID $NO_NOBODY_GRP
+make_user_group bin 1 $NO_BIN_ID $NO_BIN_GRP
+make_user_group daemon 2 $NO_DAEMON_ID $NO_DAEMON_GRP
+
+if [ $NO_USERS_GRP -eq 0 ] ; then
+ echo "Users group found."
+elif [ $CREATE_ENTRIES -ne 0 ] ; then
+ echo 'users:x:100:' >> "$group"
+fi
+
+if [ $NO_SYS_GRP -eq 0 ] ; then
+ echo "Sys group found."
+elif [ $CREATE_ENTRIES -ne 0 ] ; then
+ echo 'sys:x:3:' >> "$group"
+fi
+
+MISSING_ENTRY=0
+
+# For entries that exist in both $group and $passwd.
+for i in bin daemon; do
+ for file in "$group" "$passwd"; do
+ if ! fe "$i" "$file"; then
+ MISSING_ENTRY=1
+ break
+ fi
+ done
+ if [ $MISSING_ENTRY -ne 0 ]; then
+ break
+ fi
+done
+
+# nobody is a standard group on all distros, apart from debian based ones;
+# let's account for the fact that they use the nogroup group instead.
+if ! fe "nobody" "$passwd" || ! (fe "nogroup" "$group" || fe "nobody" "$group")
+then
+ MISSING_ENTRY=1
+fi
+
+# For entries that only exist in $group.
+for i in users sys; do
+ if ! fe "$i" "$group" ; then
+ MISSING_ENTRY=1
+ fi
+done
+
+if [ $MISSING_ENTRY -eq 0 ] ; then
+ echo "Required users/groups exist."
+ exit 0
+fi
+
+echo ""
+echo "*****************************************"
+echo "* Required users/groups do NOT exist!!! *"
+echo "* *"
+echo "* Some kernel/syscall tests will FAIL! *"
+echo "*****************************************"
+exit 1
diff --git a/ltp_framework/bin/ltp-pan b/ltp_framework/bin/ltp-pan
new file mode 100755
index 0000000..18b604e
--- /dev/null
+++ b/ltp_framework/bin/ltp-pan
Binary files differ
diff --git a/ltp_framework/include/Makefile b/ltp_framework/include/Makefile
new file mode 100644
index 0000000..243fd8a
--- /dev/null
+++ b/ltp_framework/include/Makefile
@@ -0,0 +1,45 @@
+#
+# include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+top_srcdir ?= ..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+INSTALL_DIR := $(includedir)
+
+INSTALL_MODE := 00644
+
+INSTALL_TARGETS := *.h
+
+MAKE_TARGETS :=
+
+.PHONY: ac-clean ac-distclean ac-maintainer-clean distclean maintainer-clean
+distclean:: clean ac-distclean
+maintainer-clean:: distclean ac-maintainer-clean
+ac-clean ac-distclean::
+ $(RM) -f config.h
+ac-maintainer-clean::
+ $(RM) -f config.h.in
+
+vpath %.h $(abs_srcdir)
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/ltp_framework/include/cleanup.c b/ltp_framework/include/cleanup.c
new file mode 100644
index 0000000..31393fd
--- /dev/null
+++ b/ltp_framework/include/cleanup.c
@@ -0,0 +1,45 @@
+/*
+ * Default cleanup logic because linux_syscall_numbers.h's need for cleanup
+ * and binutils bugs suck.
+ *
+ * Copyright (c) 2009 Cisco Systems, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __CLEANUP_C__
+#define __CLEANUP_C__
+
+/* Did the user define a cleanup function? */
+#ifndef CLEANUP
+# define USING_DUMMY_CLEANUP 1
+# define CLEANUP dummy_cleanup
+#endif
+
+/* A freebie for defining the function prototype. */
+static void CLEANUP(void) __attribute__((unused));
+
+#ifdef USING_DUMMY_CLEANUP
+/* The stub function. Wewt.. */
+static void dummy_cleanup(void) { }
+#endif
+
+#endif
diff --git a/ltp_framework/include/compiler.h b/ltp_framework/include/compiler.h
new file mode 100644
index 0000000..ec714fe
--- /dev/null
+++ b/ltp_framework/include/compiler.h
@@ -0,0 +1,18 @@
+/*
+ * compiler.h: take care of fun compiler details here
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#ifndef __LTP_COMPILER_H__
+#define __LTP_COMPILER_H__
+
+#define LTP_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#define LTP_ATTRIBUTE_UNUSED __attribute__((unused))
+#define LTP_ATTRIBUTE_UNUSED_RESULT __attribute__((warn_unused_result))
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
+#endif
+
+#endif /* __LTP_COMPILER_H__ */
diff --git a/ltp_framework/include/config.h b/ltp_framework/include/config.h
new file mode 100644
index 0000000..174c6ad
--- /dev/null
+++ b/ltp_framework/include/config.h
@@ -0,0 +1,293 @@
+/* include/config.h. Generated from config.h.in by configure. */
+/* include/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <asm/ldt.h> header file. */
+/* #undef HAVE_ASM_LDT_H */
+
+/* Define to 1 if you have the <asm/ptrace.h> header file. */
+#define HAVE_ASM_PTRACE_H 1
+
+/* Define to 1 if you have the `daemon' function. */
+#define HAVE_DAEMON 1
+
+/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC_COARSE', and to
+ 0 if you don't. */
+#define HAVE_DECL_CLOCK_MONOTONIC_COARSE 1
+
+/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC_RAW', and to 0
+ if you don't. */
+#define HAVE_DECL_CLOCK_MONOTONIC_RAW 1
+
+/* Define to 1 if you have the declaration of `CLOCK_REALTIME_COARSE', and to
+ 0 if you don't. */
+#define HAVE_DECL_CLOCK_REALTIME_COARSE 1
+
+/* Define to 1 if you have the declaration of `MADV_MERGEABLE', and to 0 if
+ you don't. */
+#define HAVE_DECL_MADV_MERGEABLE 1
+
+/* Define to 1 if you have the declaration of `MPOL_BIND', and to 0 if you
+ don't. */
+#define HAVE_DECL_MPOL_BIND 0
+
+/* Define to 1 if you have the declaration of `MPOL_DEFAULT', and to 0 if you
+ don't. */
+#define HAVE_DECL_MPOL_DEFAULT 0
+
+/* Define to 1 if you have the declaration of `MPOL_F_ADDR', and to 0 if you
+ don't. */
+#define HAVE_DECL_MPOL_F_ADDR 0
+
+/* Define to 1 if you have the declaration of `MPOL_F_MEMS_ALLOWED', and to 0
+ if you don't. */
+#define HAVE_DECL_MPOL_F_MEMS_ALLOWED 0
+
+/* Define to 1 if you have the declaration of `MPOL_F_NODE', and to 0 if you
+ don't. */
+#define HAVE_DECL_MPOL_F_NODE 0
+
+/* Define to 1 if you have the declaration of `MPOL_INTERLEAVE', and to 0 if
+ you don't. */
+#define HAVE_DECL_MPOL_INTERLEAVE 0
+
+/* Define to 1 if you have the declaration of `MPOL_PREFERRED', and to 0 if
+ you don't. */
+#define HAVE_DECL_MPOL_PREFERRED 0
+
+/* Define to 1 if you have the declaration of `PR_CAPBSET_DROP', and to 0 if
+ you don't. */
+#define HAVE_DECL_PR_CAPBSET_DROP 1
+
+/* Define to 1 if you have the declaration of `PR_CAPBSET_READ', and to 0 if
+ you don't. */
+#define HAVE_DECL_PR_CAPBSET_READ 1
+
+/* Define to 1 if you have the declaration of `PTRACE_GETSIGINFO', and to 0 if
+ you don't. */
+#define HAVE_DECL_PTRACE_GETSIGINFO 1
+
+/* Define to 1 if you have the declaration of `PTRACE_O_TRACEVFORKDONE', and
+ to 0 if you don't. */
+#define HAVE_DECL_PTRACE_O_TRACEVFORKDONE 1
+
+/* Define to 1 if you have the declaration of `PTRACE_SETOPTIONS', and to 0 if
+ you don't. */
+#define HAVE_DECL_PTRACE_SETOPTIONS 1
+
+/* Define to 1 if you have the <dmapi.h> header file. */
+/* #undef HAVE_DMAPI_H */
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+#define HAVE_IFADDRS_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `io_set_eventfd' function. */
+/* #undef HAVE_IO_SET_EVENTFD */
+
+/* Define to 1 if you have the libkeyutils development package and keyctl
+ syscall on your system */
+#define HAVE_KEYCTL_SYSCALL 0
+
+/* Define to 1 if you have libacl installed. */
+/* #undef HAVE_LIBACL */
+
+/* Define to 1 if you have the <libaio.h> header file. */
+/* #undef HAVE_LIBAIO_H */
+
+/* Define to 1 if you have libcap-2 installed. */
+/* #undef HAVE_LIBCAP */
+
+/* Define to 1 if you have both SELinux libraries and headers. */
+/* #undef HAVE_LIBSELINUX_DEVEL */
+
+/* Define to 1 if you have the <linux/genetlink.h> header file. */
+#define HAVE_LINUX_GENETLINK_H 1
+
+/* Define to 1 if you have the <linux/mempolicy.h> header file. */
+#define HAVE_LINUX_MEMPOLICY_H 1
+
+/* Define to 1 if you have the <linux/module.h> header file. */
+/* #undef HAVE_LINUX_MODULE_H */
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#define HAVE_LINUX_NETLINK_H 1
+
+/* Define to 1 if you have the <linux/ptrace.h> header file. */
+#define HAVE_LINUX_PTRACE_H 1
+
+/* Define to 1 if you have the <linux/securebits.h> header file. */
+#define HAVE_LINUX_SECUREBITS_H 1
+
+/* Define to 1 if you have the <linux/signalfd.h> header file. */
+#define HAVE_LINUX_SIGNALFD_H 1
+
+/* Define to 1 if you have the <linux/taskstats.h> header file. */
+#define HAVE_LINUX_TASKSTATS_H 1
+
+/* Define to 1 if you have the <linux/types.h> header file. */
+#define HAVE_LINUX_TYPES_H 1
+
+/* Define to 1 if you have MADV_MERGEABLE */
+#define HAVE_MADV_MERGEABLE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <mm.h> header file. */
+/* #undef HAVE_MM_H */
+
+/* Define to 1 if you have the `modify_ldt' function. */
+/* #undef HAVE_MODIFY_LDT */
+
+/* define to 1 if you have all constants required to use mbind tests */
+/* #undef HAVE_MPOL_CONSTANTS */
+
+/* Define to 1 if you have the <numaif.h> header file. */
+/* #undef HAVE_NUMAIF_H */
+
+/* Define to 1 if you have the `numa_alloc_onnode' function. */
+/* #undef HAVE_NUMA_ALLOC_ONNODE */
+
+/* Define to 1 if you have the <numa.h> header file. */
+/* #undef HAVE_NUMA_H */
+
+/* Define to 1 if you have the <openssl/sha.h> header file. */
+/* #undef HAVE_OPENSSL_SHA_H */
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#define HAVE_PTHREAD_H 1
+
+/* Define to 1 if you have quota v1 */
+/* #undef HAVE_QUOTAV1 */
+
+/* Define to 1 if you have quota v2 */
+#define HAVE_QUOTAV2 1
+
+/* Define to 1 if you have the <selinux/selinux.h> header file. */
+/* #undef HAVE_SELINUX_SELINUX_H */
+
+/* Define to 1 if you have the `signalfd' function. */
+#define HAVE_SIGNALFD 1
+
+/* Define to 1 if you have the <signalfd.h> header file. */
+/* #undef HAVE_SIGNALFD_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if the system has the type `struct modify_ldt_ldt_s'. */
+/* #undef HAVE_STRUCT_MODIFY_LDT_LDT_S */
+
+/* Define to 1 if the system has the type `struct pt_regs'. */
+#define HAVE_STRUCT_PT_REGS 1
+
+/* Define to 1 if `sa_sigaction' is member of `struct sigaction'. */
+#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1
+
+/* Define to 1 if `signo' is member of `struct signalfd_siginfo'. */
+/* #undef HAVE_STRUCT_SIGNALFD_SIGINFO_SIGNO */
+
+/* Define to 1 if `ssi_signo' is member of `struct signalfd_siginfo'. */
+#define HAVE_STRUCT_SIGNALFD_SIGINFO_SSI_SIGNO 1
+
+/* Define to 1 if `freepages_count' is member of `struct taskstats'. */
+#define HAVE_STRUCT_TASKSTATS_FREEPAGES_COUNT 1
+
+/* Define to 1 if `nvcsw' is member of `struct taskstats'. */
+#define HAVE_STRUCT_TASKSTATS_NVCSW 1
+
+/* Define to 1 if `read_bytes' is member of `struct taskstats'. */
+#define HAVE_STRUCT_TASKSTATS_READ_BYTES 1
+
+/* Define to 1 if the system has the type `struct user_desc'. */
+/* #undef HAVE_STRUCT_USER_DESC */
+
+/* Define to 1 if the system has the type `struct user_regs_struct'. */
+/* #undef HAVE_STRUCT_USER_REGS_STRUCT */
+
+/* Define to 1 if you have the <sys/acl.h> header file. */
+/* #undef HAVE_SYS_ACL_H */
+
+/* Define to 1 if you have the <sys/capability.h> header file. */
+/* #undef HAVE_SYS_CAPABILITY_H */
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+#define HAVE_SYS_EPOLL_H 1
+
+/* Define to 1 if you have the <sys/inotify.h> header file. */
+#define HAVE_SYS_INOTIFY_H 1
+
+/* Define to 1 if you have the <sys/jfsdmapi.h> header file. */
+/* #undef HAVE_SYS_JFSDMAPI_H */
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+#define HAVE_SYS_PRCTL_H 1
+
+/* Define to 1 if you have the <sys/ptrace.h> header file. */
+#define HAVE_SYS_PTRACE_H 1
+
+/* Define to 1 if you have the <sys/reg.h> header file. */
+/* #undef HAVE_SYS_REG_H */
+
+/* Define to 1 if you have the <sys/signalfd.h> header file. */
+#define HAVE_SYS_SIGNALFD_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `unshare' function. */
+#define HAVE_UNSHARE 1
+
+/* Define to 1 if you have the `vfork' function. */
+#define HAVE_VFORK 1
+
+/* Name of package */
+#define PACKAGE "ltp"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "ltp-list@lists.sourceforge.net"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "ltp"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "ltp LTP_VERSION"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "ltp"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "LTP_VERSION"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Target is running Linux w/out an MMU */
+/* #undef UCLINUX */
+
+/* Version number of package */
+#define VERSION "LTP_VERSION"
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+/* #undef YYTEXT_POINTER */
diff --git a/ltp_framework/include/config.h.default b/ltp_framework/include/config.h.default
new file mode 100644
index 0000000..15ff210
--- /dev/null
+++ b/ltp_framework/include/config.h.default
@@ -0,0 +1,251 @@
+/* include/config.h.default.
+ A semi-sane set of defaults for more recent Linux platforms. Please tailor
+ to meet your needs.
+ */
+
+/* Define to 1 if you have the new implementation of quotactl that only
+ requires sys/types.h and sys/quota.h */
+#define HAS_NEW_MINIMAL_QUOTACTL 1
+
+/* Define to 1 if you have the RHEL ~4.6 version of quotactl, e.g. require
+ linux/quota.h instead of sys/quota.h */
+#undef HAS_RHEL46_QUOTACTL
+
+/* Define to 1 if you have the RHEL 4.8+ version of quotactl, e.g. require
+ sys/quota.h */
+#define HAS_RHEL48_QUOTACTL
+
+/* Define to 1 if you have the <asm/ldt.h> header file. */
+#undef HAVE_ASM_LDT_H
+
+/* Define to 1 if you have the <attr/xattr.h> header file. */
+#undef HAVE_ATTR_XATTR_H
+
+/* Define to 1 if you have the declaration of `CAP_BSET_DROP', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_BSET_DROP
+
+/* Define to 1 if you have the declaration of `CAP_BSET_READ', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_BSET_READ
+
+/* Define to 1 if you have the declaration of `cap_compare', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_COMPARE
+
+/* Define to 1 if you have the declaration of `cap_free', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_FREE
+
+/* Define to 1 if you have the declaration of `cap_from_text', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_FROM_TEXT
+
+/* Define to 1 if you have the declaration of `cap_get_proc', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_GET_PROC
+
+/* Define to 1 if you have the declaration of `cap_set_file', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_SET_FILE
+
+/* Define to 1 if you have the declaration of `cap_set_flag', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_SET_FLAG
+
+/* Define to 1 if you have the declaration of `cap_set_proc', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_SET_PROC
+
+/* Define to 1 if you have the declaration of `cap_to_text', and to 0 if you
+ don't. */
+#undef HAVE_DECL_CAP_TO_TEXT
+
+/* Define to 1 if you have the declaration of `PR_CAPBSET_READ', and to 0 if
+ you don't. */
+#undef HAVE_DECL_PR_CAPBSET_READ
+
+/* Define to 1 if you have the declaration of `PTRACE_GETSIGINFO', and to 0 if
+ you don't. */
+#define HAVE_DECL_PTRACE_GETSIGINFO 1
+
+/* Define to 1 if you have the declaration of `PTRACE_O_TRACEVFORKDONE', and
+ to 0 if you don't. */
+#define HAVE_DECL_PTRACE_O_TRACEVFORKDONE 1
+
+/* Define to 1 if you have the declaration of `PTRACE_SETOPTIONS', and to 0 if
+ you don't. */
+#undef HAVE_DECL_PTRACE_SETOPTIONS
+
+/* Define to 1 if you have the <dmapi.h> header file. */
+#undef HAVE_DMAPI_H
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+#define HAVE_IFADDRS_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `io_set_eventfd' function. */
+#undef HAVE_IO_SET_EVENTFD
+
+/* Define to 1 if you have the <libaio.h> header file. */
+#undef HAVE_LIBAIO_H
+
+/* Define to 1 if you have both SELinux libraries and headers. */
+#undef HAVE_LIBSELINUX_DEVEL
+
+/* Define to 1 if you have the <linux/genetlink.h> header file. */
+#undef HAVE_LINUX_GENETLINK_H
+
+/* Define to 1 if you have the <linux/module.h> header file. */
+#undef HAVE_LINUX_MODULE_H
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#undef HAVE_LINUX_NETLINK_H
+
+/* Define to 1 if you have the <linux/ptrace.h> header file. */
+#undef HAVE_LINUX_PTRACE_H
+
+/* Define to 1 if you have the <linux/signalfd.h> header file. */
+#undef HAVE_LINUX_SIGNALFD_H
+
+/* Define to 1 if you have the <linux/taskstats.h> header file. */
+#undef HAVE_LINUX_TASKSTATS_H
+
+/* Define to 1 if you have the <linux/types.h> header file. */
+#undef HAVE_LINUX_TYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <mm.h> header file. */
+#undef HAVE_MM_H
+
+/* Define to 1 if you have the `modify_ldt' function. */
+#undef HAVE_MODIFY_LDT
+
+/* 2.6 version of swapon/swapoff */
+#define HAVE_NEW_SWAPONOFF 1
+
+/* Define to 1 if you have the `numa_alloc_onnode' function. */
+#undef HAVE_NUMA_ALLOC_ONNODE
+
+/* Define to 1 if you have the <numa.h> header file. */
+#undef HAVE_NUMA_H
+
+/* 2.4 version of swapon/swapoff */
+#undef HAVE_OLD_SWAPONOFF
+
+/* Define to 1 if you have the <openssl/sha.h> header file. */
+#undef HAVE_OPENSSL_SHA_H
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the <selinux/selinux.h> header file. */
+#undef HAVE_SELINUX_SELINUX_H
+
+/* Define to 1 if you have the `signalfd' function. */
+#define HAVE_SIGNALFD 1
+
+/* Define to 1 if you have the <signalfd.h> header file. */
+#define HAVE_SIGNALFD_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if the system has the type `struct modify_ldt_ldt_s'. */
+#undef HAVE_STRUCT_MODIFY_LDT_LDT_S
+
+/* Define to 1 if `signo' is member of `struct signalfd_siginfo'. */
+#undef HAVE_STRUCT_SIGNALFD_SIGINFO_SIGNO
+
+/* Define to 1 if `ssi_signo' is member of `struct signalfd_siginfo'. */
+#undef HAVE_STRUCT_SIGNALFD_SIGINFO_SSI_SIGNO
+
+/* Define to 1 if `freepages_count' is member of `struct taskstats'. */
+#undef HAVE_STRUCT_TASKSTATS_FREEPAGES_COUNT
+
+/* Define to 1 if `nvcsw' is member of `struct taskstats'. */
+#undef HAVE_STRUCT_TASKSTATS_NVCSW
+
+/* Define to 1 if `read_bytes' is member of `struct taskstats'. */
+#undef HAVE_STRUCT_TASKSTATS_READ_BYTES
+
+/* Define to 1 if the system has the type `struct user_desc'. */
+#undef HAVE_STRUCT_USER_DESC
+
+/* Define to 1 if you have the <sys/acl.h> header file. */
+#define HAVE_SYS_ACL_H 1
+
+/* Define to 1 if you have the <sys/capability.h> header file. */
+#define HAVE_SYS_CAPABILITY_H 1
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+#define HAVE_SYS_EPOLL_H 1
+
+/* Define to 1 if you have the <sys/inotify.h> header file. */
+#define HAVE_SYS_INOTIFY_H 1
+
+/* Define to 1 if you have the <sys/jfsdmapi.h> header file. */
+#undef HAVE_SYS_JFSDMAPI_H
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+#undef HAVE_SYS_PRCTL_H
+
+/* Define to 1 if you have the <sys/signalfd.h> header file. */
+#undef HAVE_SYS_SIGNALFD_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `unshare' function. */
+#undef HAVE_UNSHARE
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/*
+ * vim: syntax=c
+ */
diff --git a/ltp_framework/include/config.h.in b/ltp_framework/include/config.h.in
new file mode 100644
index 0000000..690f43b
--- /dev/null
+++ b/ltp_framework/include/config.h.in
@@ -0,0 +1,292 @@
+/* include/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <asm/ldt.h> header file. */
+#undef HAVE_ASM_LDT_H
+
+/* Define to 1 if you have the <asm/ptrace.h> header file. */
+#undef HAVE_ASM_PTRACE_H
+
+/* Define to 1 if you have the `daemon' function. */
+#undef HAVE_DAEMON
+
+/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC_COARSE', and to
+ 0 if you don't. */
+#undef HAVE_DECL_CLOCK_MONOTONIC_COARSE
+
+/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC_RAW', and to 0
+ if you don't. */
+#undef HAVE_DECL_CLOCK_MONOTONIC_RAW
+
+/* Define to 1 if you have the declaration of `CLOCK_REALTIME_COARSE', and to
+ 0 if you don't. */
+#undef HAVE_DECL_CLOCK_REALTIME_COARSE
+
+/* Define to 1 if you have the declaration of `MADV_MERGEABLE', and to 0 if
+ you don't. */
+#undef HAVE_DECL_MADV_MERGEABLE
+
+/* Define to 1 if you have the declaration of `MPOL_BIND', and to 0 if you
+ don't. */
+#undef HAVE_DECL_MPOL_BIND
+
+/* Define to 1 if you have the declaration of `MPOL_DEFAULT', and to 0 if you
+ don't. */
+#undef HAVE_DECL_MPOL_DEFAULT
+
+/* Define to 1 if you have the declaration of `MPOL_F_ADDR', and to 0 if you
+ don't. */
+#undef HAVE_DECL_MPOL_F_ADDR
+
+/* Define to 1 if you have the declaration of `MPOL_F_MEMS_ALLOWED', and to 0
+ if you don't. */
+#undef HAVE_DECL_MPOL_F_MEMS_ALLOWED
+
+/* Define to 1 if you have the declaration of `MPOL_F_NODE', and to 0 if you
+ don't. */
+#undef HAVE_DECL_MPOL_F_NODE
+
+/* Define to 1 if you have the declaration of `MPOL_INTERLEAVE', and to 0 if
+ you don't. */
+#undef HAVE_DECL_MPOL_INTERLEAVE
+
+/* Define to 1 if you have the declaration of `MPOL_PREFERRED', and to 0 if
+ you don't. */
+#undef HAVE_DECL_MPOL_PREFERRED
+
+/* Define to 1 if you have the declaration of `PR_CAPBSET_DROP', and to 0 if
+ you don't. */
+#undef HAVE_DECL_PR_CAPBSET_DROP
+
+/* Define to 1 if you have the declaration of `PR_CAPBSET_READ', and to 0 if
+ you don't. */
+#undef HAVE_DECL_PR_CAPBSET_READ
+
+/* Define to 1 if you have the declaration of `PTRACE_GETSIGINFO', and to 0 if
+ you don't. */
+#undef HAVE_DECL_PTRACE_GETSIGINFO
+
+/* Define to 1 if you have the declaration of `PTRACE_O_TRACEVFORKDONE', and
+ to 0 if you don't. */
+#undef HAVE_DECL_PTRACE_O_TRACEVFORKDONE
+
+/* Define to 1 if you have the declaration of `PTRACE_SETOPTIONS', and to 0 if
+ you don't. */
+#undef HAVE_DECL_PTRACE_SETOPTIONS
+
+/* Define to 1 if you have the <dmapi.h> header file. */
+#undef HAVE_DMAPI_H
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+#undef HAVE_IFADDRS_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `io_set_eventfd' function. */
+#undef HAVE_IO_SET_EVENTFD
+
+/* Define to 1 if you have the libkeyutils development package and keyctl
+ syscall on your system */
+#undef HAVE_KEYCTL_SYSCALL
+
+/* Define to 1 if you have libacl installed. */
+#undef HAVE_LIBACL
+
+/* Define to 1 if you have the <libaio.h> header file. */
+#undef HAVE_LIBAIO_H
+
+/* Define to 1 if you have libcap-2 installed. */
+#undef HAVE_LIBCAP
+
+/* Define to 1 if you have both SELinux libraries and headers. */
+#undef HAVE_LIBSELINUX_DEVEL
+
+/* Define to 1 if you have the <linux/genetlink.h> header file. */
+#undef HAVE_LINUX_GENETLINK_H
+
+/* Define to 1 if you have the <linux/mempolicy.h> header file. */
+#undef HAVE_LINUX_MEMPOLICY_H
+
+/* Define to 1 if you have the <linux/module.h> header file. */
+#undef HAVE_LINUX_MODULE_H
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#undef HAVE_LINUX_NETLINK_H
+
+/* Define to 1 if you have the <linux/ptrace.h> header file. */
+#undef HAVE_LINUX_PTRACE_H
+
+/* Define to 1 if you have the <linux/securebits.h> header file. */
+#undef HAVE_LINUX_SECUREBITS_H
+
+/* Define to 1 if you have the <linux/signalfd.h> header file. */
+#undef HAVE_LINUX_SIGNALFD_H
+
+/* Define to 1 if you have the <linux/taskstats.h> header file. */
+#undef HAVE_LINUX_TASKSTATS_H
+
+/* Define to 1 if you have the <linux/types.h> header file. */
+#undef HAVE_LINUX_TYPES_H
+
+/* Define to 1 if you have MADV_MERGEABLE */
+#undef HAVE_MADV_MERGEABLE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <mm.h> header file. */
+#undef HAVE_MM_H
+
+/* Define to 1 if you have the `modify_ldt' function. */
+#undef HAVE_MODIFY_LDT
+
+/* define to 1 if you have all constants required to use mbind tests */
+#undef HAVE_MPOL_CONSTANTS
+
+/* Define to 1 if you have the <numaif.h> header file. */
+#undef HAVE_NUMAIF_H
+
+/* Define to 1 if you have the `numa_alloc_onnode' function. */
+#undef HAVE_NUMA_ALLOC_ONNODE
+
+/* Define to 1 if you have the <numa.h> header file. */
+#undef HAVE_NUMA_H
+
+/* Define to 1 if you have the <openssl/sha.h> header file. */
+#undef HAVE_OPENSSL_SHA_H
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have quota v1 */
+#undef HAVE_QUOTAV1
+
+/* Define to 1 if you have quota v2 */
+#undef HAVE_QUOTAV2
+
+/* Define to 1 if you have the <selinux/selinux.h> header file. */
+#undef HAVE_SELINUX_SELINUX_H
+
+/* Define to 1 if you have the `signalfd' function. */
+#undef HAVE_SIGNALFD
+
+/* Define to 1 if you have the <signalfd.h> header file. */
+#undef HAVE_SIGNALFD_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if the system has the type `struct modify_ldt_ldt_s'. */
+#undef HAVE_STRUCT_MODIFY_LDT_LDT_S
+
+/* Define to 1 if the system has the type `struct pt_regs'. */
+#undef HAVE_STRUCT_PT_REGS
+
+/* Define to 1 if `sa_sigaction' is member of `struct sigaction'. */
+#undef HAVE_STRUCT_SIGACTION_SA_SIGACTION
+
+/* Define to 1 if `signo' is member of `struct signalfd_siginfo'. */
+#undef HAVE_STRUCT_SIGNALFD_SIGINFO_SIGNO
+
+/* Define to 1 if `ssi_signo' is member of `struct signalfd_siginfo'. */
+#undef HAVE_STRUCT_SIGNALFD_SIGINFO_SSI_SIGNO
+
+/* Define to 1 if `freepages_count' is member of `struct taskstats'. */
+#undef HAVE_STRUCT_TASKSTATS_FREEPAGES_COUNT
+
+/* Define to 1 if `nvcsw' is member of `struct taskstats'. */
+#undef HAVE_STRUCT_TASKSTATS_NVCSW
+
+/* Define to 1 if `read_bytes' is member of `struct taskstats'. */
+#undef HAVE_STRUCT_TASKSTATS_READ_BYTES
+
+/* Define to 1 if the system has the type `struct user_desc'. */
+#undef HAVE_STRUCT_USER_DESC
+
+/* Define to 1 if the system has the type `struct user_regs_struct'. */
+#undef HAVE_STRUCT_USER_REGS_STRUCT
+
+/* Define to 1 if you have the <sys/acl.h> header file. */
+#undef HAVE_SYS_ACL_H
+
+/* Define to 1 if you have the <sys/capability.h> header file. */
+#undef HAVE_SYS_CAPABILITY_H
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+#undef HAVE_SYS_EPOLL_H
+
+/* Define to 1 if you have the <sys/inotify.h> header file. */
+#undef HAVE_SYS_INOTIFY_H
+
+/* Define to 1 if you have the <sys/jfsdmapi.h> header file. */
+#undef HAVE_SYS_JFSDMAPI_H
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+#undef HAVE_SYS_PRCTL_H
+
+/* Define to 1 if you have the <sys/ptrace.h> header file. */
+#undef HAVE_SYS_PTRACE_H
+
+/* Define to 1 if you have the <sys/reg.h> header file. */
+#undef HAVE_SYS_REG_H
+
+/* Define to 1 if you have the <sys/signalfd.h> header file. */
+#undef HAVE_SYS_SIGNALFD_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `unshare' function. */
+#undef HAVE_UNSHARE
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Target is running Linux w/out an MMU */
+#undef UCLINUX
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
diff --git a/ltp_framework/include/dataascii.h b/ltp_framework/include/dataascii.h
new file mode 100644
index 0000000..d08fe86
--- /dev/null
+++ b/ltp_framework/include/dataascii.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _DATAASCII_H_
+#define _DATAASCII_H_
+
+/***********************************************************************
+ * int dataasciigen(listofchars, buffer, size, offset)
+ *
+ * This function fills buffer with ascii characters.
+ * The ascii characters are obtained from listofchars or the CHARS array
+ * if listofchars is NULL.
+ * Each char is selected by an index. The index is the remainder
+ * of count divided by the array size.
+ * This method allows more than one process to write to a location
+ * in a file without corrupting it for another process' point of view.
+ *
+ * The return value will be the number of character written in buffer
+ * (size).
+ *
+ ***********************************************************************/
+int dataasciigen(char *, char *, int, int);
+
+/***********************************************************************
+ * int dataasciichk(listofchars, buffer, size, count, errmsg)
+ *
+ * This function checks the contents of a buffer produced by
+ * dataasciigen.
+ *
+ * return values:
+ * >= 0 : error at character count
+ * < 0 : no error
+ ***********************************************************************/
+
+int dataasciichk(char *, char *, int, int, char**);
+
+#endif
diff --git a/ltp_framework/include/databin.h b/ltp_framework/include/databin.h
new file mode 100644
index 0000000..93c3863
--- /dev/null
+++ b/ltp_framework/include/databin.h
@@ -0,0 +1,44 @@
+#ifndef _DATABIN_H_
+#define _DATABIN_H_
+
+/*******************************************************************************
+* NAME
+* databingen - fill a buffer with a data pattern
+*
+* SYNOPSIS
+* (void) databingen(mode, buffer, bsize, offset)
+* int mode;
+* char *buffer;
+* int bsize;
+* int offset;
+*
+* DESCRIPTION
+* datagen fills the buffer pointed to by 'buffer' with 'bsize' bytes
+* of data of the form indicated by 'mode'.
+* All modes (expect r -random) are file offset based.
+* This allows more than process to do writing to the file without
+* corrupting it if the same modes were used.
+* They data modes to choose from, these are:
+*
+* 'a' - writes an alternating bit pattern (i.e. 0x5555555...)
+*
+* 'c' - writes a checkerboard pattern (i.e. 0xff00ff00ff00...)
+*
+* 'C' - writes counting pattern (i.e. 0 - 07, 0 - 07, ...);
+*
+* 'o' - writes all bits set (i.e. 0xffffffffffffff...)
+*
+* 'z' - writes all bits cleared (i.e. 0x000000000...);
+*
+* 'r' - writes random integers
+*
+* RETURN VALUE
+* None
+*
+*******************************************************************************/
+
+void databingen( int mode, char *buffer, int bsize, int offset );
+
+int databinchk( int mode, char *buffer, int bsize, int offset, char **errmsg);
+
+#endif
diff --git a/ltp_framework/include/file_lock.h b/ltp_framework/include/file_lock.h
new file mode 100644
index 0000000..7586260
--- /dev/null
+++ b/ltp_framework/include/file_lock.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _FILE_LOCK_H_
+#define _FILE_LOCK_H_
+
+extern char Fl_syscall_str[128];
+
+int file_lock( int , int, char ** );
+int record_lock( int , int , int , int , char ** );
+
+#if defined(__sun) || defined(__hpux)
+#define LOCK_NB 0x0001
+#define LOCK_UN 0x0002
+#define LOCK_EX 0x0004
+#define LOCK_SH 0x0008
+#endif
+#endif /* _FILE_LOCK_H_ */
diff --git a/ltp_framework/include/forker.h b/ltp_framework/include/forker.h
new file mode 100644
index 0000000..dfad625
--- /dev/null
+++ b/ltp_framework/include/forker.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _FORKER_H_
+#define _FORKER_H_
+
+#define FORKER_MAX_PIDS 4098
+
+extern int Forker_pids[FORKER_MAX_PIDS]; /* holds pids of forked processes */
+extern int Forker_npids; /* number of entries in Forker_pids */
+
+/*
+ * This function will fork and the parent will exit zero and
+ * the child will return. This will orphan the returning process
+ * putting it in the background.
+ */
+int background( char * );
+
+/*
+ * Forker will fork ncopies-1 copies of self.
+ *
+ * arg 1: Number of copies of the process to be running after return.
+ * This value minus one is the number of forks performed.
+ * arg 2: mode: 0 - all children are first generation descendents.
+ * 1 - each subsequent child is a descendent of another
+ * descendent, resulting in only one direct descendent of the
+ * parent and each other child is a child of another child in
+ * relation to the parent.
+ * arg 3: prefix: string to preceed any error messages. A value of NULL
+ * results in no error messages on failure.
+ * returns: returns to parent the number of children forked.
+ */
+int forker( int , int , char * );
+
+#endif /* _FORKER_H_ */
diff --git a/ltp_framework/include/libtestsuite.h b/ltp_framework/include/libtestsuite.h
new file mode 100644
index 0000000..0668961
--- /dev/null
+++ b/ltp_framework/include/libtestsuite.h
@@ -0,0 +1,20 @@
+/* The following functions are used to synchronize father and sons processes.
+ *
+ * create_sync_pipes: create pipes used for the synchronization. Must be done
+ * by father process before a fork.
+ *
+ * wait_son_startup: wait a son process to reach the "notify_startup" function.
+ *
+ * notify_startup: notify the father process a son has started its execution.
+ */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* fifo_name is used to create named pipe. NULL means anonymous pipe. */
+#define PIPE_NAME NULL
+int sync_pipe_create( int fd[], const char *pipe_name);
+int sync_pipe_close(int fd[], const char *pipe_name);
+int sync_pipe_wait( int fd[]);
+int sync_pipe_notify( int fd[]);
+
diff --git a/ltp_framework/include/ltp_signal.h b/ltp_framework/include/ltp_signal.h
new file mode 100644
index 0000000..1ac6f70
--- /dev/null
+++ b/ltp_framework/include/ltp_signal.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2009 Cisco Systems, Inc. All Rights Reserved.
+ * Copyright (c) 2009 FUJITSU LIMITED. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Author: Liu Bo <liubo2009@cn.fujitsu.com>
+ * Author: Garrett Cooper <yanegomi@gmail.com>
+ *
+ */
+
+#ifndef __LTP_SIGNAL_H
+#define __LTP_SIGNAL_H
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include "config.h"
+
+#define SIGSETSIZE (_NSIG / 8)
+
+#ifdef LTP_RT_SIG_TEST
+
+#ifdef __x86_64__
+
+/*
+ * From asm/signal.h -- this value isn't exported anywhere outside of glibc and
+ * asm/signal.h and is only required for the rt_sig* function family because
+ * sigaction(2), et all, appends this if necessary to
+ * (struct sigaction).sa_flags. HEH.
+ *
+ * I do #undef though, just in case...
+ *
+ * Also, from .../arch/x86/kernel/signal.c:448 for v2.6.30 (something or
+ * other):
+ *
+ * x86-64 should always use SA_RESTORER.
+ *
+ * -- thus SA_RESTORER must always be defined along with
+ * (struct sigaction).sa_restorer for this architecture.
+ */
+#undef SA_RESTORER
+#define HAVE_SA_RESTORER
+#define SA_RESTORER 0x04000000
+
+struct kernel_sigaction {
+ __sighandler_t k_sa_handler;
+ unsigned long sa_flags;
+ void (*sa_restorer) (void);
+ sigset_t sa_mask;
+};
+
+void (*restore_rt) (void);
+
+inline void
+handler_h (int signal)
+{
+ return;
+}
+
+/* Setup an initial signal handler for signal number = sig for x86_64. */
+inline int
+sig_initial(int sig)
+{
+ int ret_code = -1;
+ struct sigaction act, oact;
+
+ act.sa_handler = handler_h;
+ /* Clear out the signal set. */
+ if (sigemptyset(&act.sa_mask) < 0) {
+ /* Add the signal to the mask set. */
+ } else if (sigaddset(&act.sa_mask, sig) < 0) {
+ /* Set act.sa_restorer via syscall(2) */
+ } else if (sigaction(sig, &act, &oact) < 0) {
+ /* Copy oact.sa_restorer via syscall(2) */
+ } else if (sigaction(sig, &act, &oact) < 0) {
+ /* And voila -- we just tricked the kernel into giving us our
+ * restorer function! */
+ } else {
+ restore_rt = oact.sa_restorer;
+ ret_code = 0;
+ }
+
+ return ret_code;
+
+}
+
+#endif /* __x86_64__ */
+
+#endif /* LTP_RT_SIG_TEST */
+
+#endif
diff --git a/ltp_framework/include/mk/automake.mk b/ltp_framework/include/mk/automake.mk
new file mode 100644
index 0000000..e5a4fe0
--- /dev/null
+++ b/ltp_framework/include/mk/automake.mk
@@ -0,0 +1,117 @@
+#
+# Autotools include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+# Override these variables to use non-system available tools.
+ACLOCAL ?= aclocal
+AUTOCONF ?= autoconf
+AUTOHEADER ?= autoheader
+AUTOMAKE ?= automake
+
+AUTOCONFED_SUBDIRS = \
+ testcases/realtime
+
+# We want to run this every single time to ensure that all of the prereq files
+# are there.
+.PHONY: testcases/realtime/configure
+testcases/realtime/configure:
+ $(MAKE) -C $(@D) autotools
+
+.PHONY: autotools
+autotools: aclocal autoconf autoheader automake $(addsuffix /configure,$(AUTOCONFED_SUBDIRS))
+
+.PHONY: aclocal
+aclocal: aclocal.m4
+
+aclocal.m4: $(wildcard m4/*.m4) m4/ltp-version.m4
+ $(ACLOCAL) -I m4
+
+.PHONY: autoconf
+autoconf: configure
+
+configure: configure.ac aclocal.m4
+ $(AUTOCONF)
+
+.PHONY: autoheader
+autoheader: configure.ac $(wildcard m4/*.m4) m4/ltp-version.m4 aclocal.m4
+ $(AUTOHEADER)
+
+include:
+ mkdir -p "$@"
+
+m4/ltp-version.m4: ChangeLog
+ sed -n '1{s:LTP-:m4_define([LTP_VERSION],[:;s:$$:]):;p;q}' $< > $@
+
+.PHONY: automake
+AUTOMAKE_FILES := config.guess config.sub install-sh missing stamp-h1
+automake: aclocal $(AUTOMAKE_FILES)
+$(AUTOMAKE_FILES): m4/Makefile.in
+m4/Makefile.in: m4/Makefile.am aclocal.m4
+ $(AUTOMAKE) -c -a
+
+.PHONY: ac-clean ac-distclean ac-maintainer-clean
+ac-clean::
+ $(RM) -rf autom4te.cache
+ $(RM) -f config.log config.status
+ $(RM) -f include/config.h include/stamp-h1
+ $(RM) -f m4/Makefile m4/ltp-version.m4
+ for d in $(AUTOCONFED_SUBDIRS); do \
+ $(MAKE) -C "$(top_srcdir)/$$d" $@; \
+ done
+
+ac-distclean:: ac-clean
+ac-maintainer-clean:: ac-distclean
+ for d in $(AUTOCONFED_SUBDIRS); do \
+ $(MAKE) -C "$(top_srcdir)/$$d" $@; \
+ done
+ $(RM) -f aclocal.m4 configure $(AUTOMAKE_FILES) m4/Makefile.in
+ $(RM) -f include/*config.h.in
+
+# Don't include config.h, or make will (rightfully) whine about overriding
+# rules.
+#
+# This list should match the files in configure.ac.
+#
+AUTOGENERATED_FILES = \
+ include/mk/config.mk \
+ include/mk/features.mk \
+ lib/ltp.pc \
+ m4/Makefile \
+ ltp-devel.spec \
+ execltp \
+ README.ltp-devel
+
+distclean:: %: clean ac-distclean
+ for d in $(AUTOCONFED_SUBDIRS); do \
+ $(MAKE) -C "$(top_srcdir)/$$d" $@; \
+ done
+ $(RM) -f $(AUTOGENERATED_FILES)
+
+maintainer-clean:: distclean ac-maintainer-clean
+
+$(AUTOGENERATED_FILES): $(top_builddir)/config.status
+ $(SHELL) $^
+
+# This variable is automatically changed from help to all once someone has
+# run configure, or the equivalent steps manually, as described in INSTALL.
+$(abs_top_builddir)/include/mk/config.mk \
+$(abs_top_builddir)/include/mk/features.mk:
+ $(MAKE) -C $(top_srcdir) help; false
diff --git a/ltp_framework/include/mk/config.mk b/ltp_framework/include/mk/config.mk
new file mode 100644
index 0000000..de7a353
--- /dev/null
+++ b/ltp_framework/include/mk/config.mk
@@ -0,0 +1,82 @@
+#
+# config.mk.in.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+# See this page for more info about LEX*:
+# http://www.gnu.org/software/hello/manual/autoconf/Particular-Programs.html
+
+# Application specifying variables. You should never have to change these.
+AR := arm-linux-gnueabi-ar
+CC := arm-linux-gnueabi-gcc
+LEX := :
+RANLIB := arm-linux-gnueabi-ranlib
+STRIP := arm-linux-gnueabi-strip
+YACC := yacc
+
+# XXX: I'm lazy... but if someone has a working javac, they should have a
+# working jar on their systems.
+JAR := jar
+JAVAC := @JAVAC@
+
+AIO_LIBS :=
+CAP_LIBS :=
+ACL_LIBS :=
+CRYPTO_LIBS :=
+LEXLIB :=
+NUMA_CPPFLAGS :=
+NUMA_LIBS :=
+SELINUX_LIBS :=
+
+prefix := /opt/ltp
+
+datarootdir := ${prefix}/share
+includedir := ${prefix}/include
+exec_prefix := ${prefix}
+bindir := ${exec_prefix}/bin
+libdir := ${exec_prefix}/lib
+mandir := ${datarootdir}/man
+
+RPMBUILD ?= rpmbuild
+
+CPPFLAGS :=
+CFLAGS := -g -O2
+LDLIBS :=
+LDFLAGS :=
+
+DEBUG_CFLAGS ?= -g
+DEBUG_CXXFLAGS ?= $(DEBUG_CFLAGS)
+
+# Please see README.mk-devel about -fstrict-aliasing.
+OPT_CFLAGS ?= -O2 -fno-strict-aliasing -pipe
+OPT_CXXFLAGS ?= $(OPT_CFLAGS)
+
+WCFLAGS ?= -Wall
+WCXXFLAGS ?= $(WCFLAGS)
+
+LDFLAGS += $(WLDFLAGS)
+CFLAGS += $(DEBUG_CFLAGS) $(OPT_CFLAGS) $(WCFLAGS)
+CXXFLAGS += $(DEBUG_CXXFLAGS) $(OPT_CXXFLAGS) $(WCXXFLAGS)
+
+ifeq ($(strip $(prefix)),)
+$(error you are using $$(prefix) incorrectly -- set it to $(abs_top_srcdir) if you want to build in the source tree)
+endif
+
+export datarootdir includedir libdir mandir prefix
diff --git a/ltp_framework/include/mk/config.mk.default b/ltp_framework/include/mk/config.mk.default
new file mode 100644
index 0000000..8248071
--- /dev/null
+++ b/ltp_framework/include/mk/config.mk.default
@@ -0,0 +1,76 @@
+#
+# config.mk.in.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+# See this page for more info about LEX*:
+# http://www.gnu.org/software/hello/manual/autoconf/Particular-Programs.html
+
+# Application specifying variables. You should never have to change these.
+AR := ar
+CC := gcc
+LEX := flex
+RANLIB := ranlib
+STRIP := strip
+YACC := bison -y
+
+#JAR := jar
+#JAVAC := javac
+
+#AIO_LIBS := -laio
+#CAP_LIBS := -lcap
+#ACL_LIBS := -lacl
+#CRYPTO_LIBS := -lcrypto
+#LEXLIB := -lfl
+#NUMA_CPPFLAGS := -DNUMA_VERSION1_COMPATIBILITY
+#NUMA_LIBS := -lnuma
+#SELINUX_LIBS := -lselinux
+
+prefix := /opt/ltp
+
+datarootdir := ${prefix}/share
+includedir := ${prefix}/include
+exec_prefix := ${prefix}
+bindir := ${exec_prefix}/bin
+libdir := ${exec_prefix}/lib
+mandir := ${datarootdir}/man
+
+RPMBUILD ?= rpmbuild
+
+CPPFLAGS :=
+CFLAGS := -g -O2
+LDLIBS :=
+LDFLAGS :=
+
+DEBUG_CFLAGS ?= -g
+DEBUG_CXXFLAGS ?= $(DEBUG_CFLAGS)
+
+# Please see README.mk-devel about -fstrict-aliasing.
+OPT_CFLAGS ?= -O2 -fno-strict-aliasing -pipe
+OPT_CXXFLAGS ?= $(OPT_CFLAGS)
+
+WCFLAGS ?= -Wall
+WCXXFLAGS ?= $(WCFLAGS)
+
+LDFLAGS += $(WLDFLAGS)
+CFLAGS += $(DEBUG_CFLAGS) $(OPT_CFLAGS) $(WCFLAGS)
+CXXFLAGS += $(DEBUG_CXXFLAGS) $(OPT_CXXFLAGS) $(WCXXFLAGS)
+
+export datarootdir includedir libdir mandir prefix
diff --git a/ltp_framework/include/mk/config.mk.in b/ltp_framework/include/mk/config.mk.in
new file mode 100644
index 0000000..b835c86
--- /dev/null
+++ b/ltp_framework/include/mk/config.mk.in
@@ -0,0 +1,82 @@
+#
+# config.mk.in.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+# See this page for more info about LEX*:
+# http://www.gnu.org/software/hello/manual/autoconf/Particular-Programs.html
+
+# Application specifying variables. You should never have to change these.
+AR := @AR@
+CC := @CC@
+LEX := @LEX@
+RANLIB := @RANLIB@
+STRIP := @STRIP@
+YACC := @YACC@
+
+# XXX: I'm lazy... but if someone has a working javac, they should have a
+# working jar on their systems.
+JAR := jar
+JAVAC := @JAVAC@
+
+AIO_LIBS := @AIO_LIBS@
+CAP_LIBS := @CAP_LIBS@
+ACL_LIBS := @ACL_LIBS@
+CRYPTO_LIBS := @CRYPTO_LIBS@
+LEXLIB := @LEXLIB@
+NUMA_CPPFLAGS := @NUMA_CPPFLAGS@
+NUMA_LIBS := @NUMA_LIBS@
+SELINUX_LIBS := @SELINUX_LIBS@
+
+prefix := @prefix@
+
+datarootdir := @datarootdir@
+includedir := @includedir@
+exec_prefix := @exec_prefix@
+bindir := @bindir@
+libdir := @libdir@
+mandir := @mandir@
+
+RPMBUILD ?= rpmbuild
+
+CPPFLAGS := @CPPFLAGS@
+CFLAGS := @CFLAGS@
+LDLIBS := @LIBS@
+LDFLAGS := @LDFLAGS@
+
+DEBUG_CFLAGS ?= -g
+DEBUG_CXXFLAGS ?= $(DEBUG_CFLAGS)
+
+# Please see README.mk-devel about -fstrict-aliasing.
+OPT_CFLAGS ?= -O2 -fno-strict-aliasing -pipe
+OPT_CXXFLAGS ?= $(OPT_CFLAGS)
+
+WCFLAGS ?= -Wall
+WCXXFLAGS ?= $(WCFLAGS)
+
+LDFLAGS += $(WLDFLAGS)
+CFLAGS += $(DEBUG_CFLAGS) $(OPT_CFLAGS) $(WCFLAGS)
+CXXFLAGS += $(DEBUG_CXXFLAGS) $(OPT_CXXFLAGS) $(WCXXFLAGS)
+
+ifeq ($(strip $(prefix)),)
+$(error you are using $$(prefix) incorrectly -- set it to $(abs_top_srcdir) if you want to build in the source tree)
+endif
+
+export datarootdir includedir libdir mandir prefix
diff --git a/ltp_framework/include/mk/env_post.mk b/ltp_framework/include/mk/env_post.mk
new file mode 100644
index 0000000..ebaee1f
--- /dev/null
+++ b/ltp_framework/include/mk/env_post.mk
@@ -0,0 +1,104 @@
+#
+# Environment post-setup Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+ENV_PRE_LOADED ?= $(error You must load env_pre.mk before including this file)
+
+include $(top_srcdir)/include/mk/functions.mk
+
+ifndef ENV_POST_LOADED
+ENV_PRE_LOADED = 1
+
+# Default source search path. Modify as necessary, but I would call that
+# poor software design if you need more than one search directory, and
+# would suggest creating a general purpose static library to that end.
+vpath %.c $(abs_srcdir)
+
+# For config.h, et all.
+CPPFLAGS += -I$(top_srcdir)/include -I$(top_builddir)/include
+
+LDFLAGS += -L$(top_builddir)/lib
+
+ifeq ($(UCLINUX),1)
+CPPFLAGS += -D__UCLIBC__ -DUCLINUX
+endif
+
+MAKE_TARGETS ?= $(notdir $(patsubst %.c,%,$(wildcard $(abs_srcdir)/*.c)))
+
+MAKE_TARGETS := $(filter-out $(FILTER_OUT_MAKE_TARGETS),$(MAKE_TARGETS))
+
+CLEAN_TARGETS += $(MAKE_TARGETS) *.o *.pyc
+
+# Majority of the files end up in testcases/bin...
+INSTALL_DIR ?= testcases/bin
+
+ifneq ($(filter-out install,$(MAKECMDGOALS)),$(MAKECMDGOALS))
+
+ifeq ($(strip $(INSTALL_DIR)),)
+INSTALL_DIR := $(error You must define INSTALL_DIR before including this file)
+endif
+
+ifneq ($(strip $(prefix)),)
+# Value specified by INSTALL_DIR isn't an absolute path, so let's tack on $(prefix).
+ifneq ($(patsubst /%,,$(INSTALL_DIR)),)
+INSTALL_DIR := $(prefix)/$(INSTALL_DIR)
+endif
+
+# Glob any possible expressions, but make sure to zap the $(abs_srcdir)
+# reference at the start of the filename instead of using $(notdir), so that
+# way we don't accidentally nuke the relative path from $(abs_srcdir) that
+# may have been set in the Makefile.
+INSTALL_TARGETS := $(wildcard $(addprefix $(abs_srcdir)/,$(INSTALL_TARGETS)))
+INSTALL_TARGETS := $(patsubst $(abs_srcdir)/%,%,$(INSTALL_TARGETS))
+
+# The large majority of the files that we install are going to be apps and
+# scripts, so let's chmod them like that.
+INSTALL_MODE ?= 00775
+
+ifdef MAKE_3_80_COMPAT
+
+INSTALL_PATH := $(call MAKE_3_80_abspath,$(DESTDIR)/$(INSTALL_DIR))
+
+INSTALL_TARGETS_ABS := $(call MAKE_3_80_abspath,$(addprefix $(INSTALL_PATH)/,$(INSTALL_TARGETS)))
+MAKE_TARGETS_ABS := $(call MAKE_3_80_abspath,$(addprefix $(INSTALL_PATH)/,$(MAKE_TARGETS)))
+
+INSTALL_FILES := $(INSTALL_TARGETS_ABS) $(MAKE_TARGETS_ABS)
+
+$(INSTALL_TARGETS_ABS):
+ test -d "$(@D)" || mkdir -p "$(@D)"
+ install -m $(INSTALL_MODE) "$(abs_srcdir)/$(subst $(INSTALL_PATH)/,,$@)" "$@"
+
+$(MAKE_TARGETS_ABS):
+ test -d "$(@D)" || mkdir -p "$(@D)"
+ install -m $(INSTALL_MODE) "$(abs_builddir)/$(subst $(INSTALL_PATH)/,,$@)" "$@"
+else
+$(abspath $(addprefix $(DESTDIR)/$(INSTALL_DIR)/,$(sort $(dir $(INSTALL_TARGETS) $(MAKE_TARGETS))))):
+ mkdir -p "$@"
+$(foreach install_target,$(INSTALL_TARGETS),$(eval $(call generate_install_rule,$(install_target),$(abs_srcdir),$(INSTALL_DIR))))
+$(foreach make_target,$(MAKE_TARGETS),$(eval $(call generate_install_rule,$(make_target),$(abs_builddir),$(INSTALL_DIR))))
+endif
+
+else # else ! $(filter-out install,$(MAKECMDGOALS)),$(MAKECMDGOALS)
+$(error You must define $$(prefix) before executing install)
+endif # END $(filter-out install,$(MAKECMDGOALS)),$(MAKECMDGOALS)
+endif
+
+endif
diff --git a/ltp_framework/include/mk/env_pre.mk b/ltp_framework/include/mk/env_pre.mk
new file mode 100644
index 0000000..f1584a8
--- /dev/null
+++ b/ltp_framework/include/mk/env_pre.mk
@@ -0,0 +1,144 @@
+#
+# Make pre-include environment Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, September 2009
+#
+# This Makefile must be included first. NO IF'S, AND'S, OR BUT'S.
+#
+# This sets the stage for all operations required within Makefiles.
+#
+
+ifndef ENV_PRE_LOADED
+ENV_PRE_LOADED = 1
+
+# "out-of-build-tree" build.
+BUILD_TREE_BUILDDIR_INSTALL := 1
+# "in-srcdir" build / install.
+BUILD_TREE_SRCDIR_INSTALL := 2
+# "in-srcdir" build, non-srcdir install.
+BUILD_TREE_NONSRCDIR_INSTALL := 3
+# configure not run.
+BUILD_TREE_UNCONFIGURED := 4
+
+ifndef MAKE_VERSION_CHECK
+export MAKE_VERSION_CHECK = 1
+ifneq ($(firstword $(sort 3.80 $(MAKE_VERSION))),3.80)
+$(error Your version of make $(MAKE_VERSION) is too old. Upgrade to at least 3.80; 3.81+ is preferred)
+else
+ifneq ($(filter 3.80%,$(MAKE_VERSION)),)
+export MAKE_3_80_COMPAT := 1
+endif # make 3.80?
+endif # At least make 3.80?
+endif # MAKE_VERSION_CHECK
+
+# Get the absolute path for the source directory.
+top_srcdir ?= $(error You must define top_srcdir before including this file)
+
+include $(top_srcdir)/include/mk/functions.mk
+
+# Where's the root source directory?
+ifdef MAKE_3_80_COMPAT
+abs_top_srcdir := $(call MAKE_3_80_abspath,$(top_srcdir))
+else
+abs_top_srcdir := $(abspath $(top_srcdir))
+endif
+
+#
+# Where's the root object directory?
+#
+# Just in case it's not specified, set it to the top srcdir (because the user
+# must not have wanted out of build tree support)...
+#
+top_builddir ?= $(top_srcdir)
+
+# We need the absolute path...
+ifdef MAKE_3_80_COMPAT
+abs_top_builddir := $(call MAKE_3_80_abspath,$(top_builddir))
+else
+abs_top_builddir := $(abspath $(top_builddir))
+endif
+
+# Where's the root object directory?
+builddir := .
+
+abs_builddir := $(CURDIR)
+
+cwd_rel_from_top := $(subst $(abs_top_builddir),,$(abs_builddir))
+
+# Where's the source located at? Squish all of the / away by using abspath...
+ifdef MAKE_3_80_COMPAT
+abs_srcdir := $(call MAKE_3_80_abspath,$(abs_top_srcdir)/$(cwd_rel_from_top))
+else
+abs_srcdir := $(abspath $(abs_top_srcdir)/$(cwd_rel_from_top))
+endif
+
+srcdir := $(strip $(subst $(abs_top_srcdir)/,,$(abs_srcdir)))
+
+ifeq ($(srcdir),)
+srcdir := .
+endif
+
+# autotools, *clean, and help don't require config.mk, features.mk, etc...
+ifeq ($(filter autotools %clean .gitignore gitignore.% help,$(MAKECMDGOALS)),)
+
+include $(abs_top_builddir)/include/mk/config.mk
+include $(abs_top_builddir)/include/mk/features.mk
+
+# START out-of-build-tree check.
+ifneq ($(abs_builddir),$(abs_srcdir))
+BUILD_TREE_STATE := $(BUILD_TREE_BUILDDIR_INSTALL)
+else
+# Else, not out of build tree..
+
+# START srcdir build-tree install checks
+ifeq ($(strip $(DESTDIR)$(prefix)),)
+BUILD_TREE_STATE := $(BUILD_TREE_SRCDIR_INSTALL)
+else # Empty $(DESTDIR)$(prefix)
+ifeq ($(abs_top_srcdir),$(prefix))
+BUILD_TREE_STATE := $(BUILD_TREE_SRCDIR_INSTALL)
+endif
+# END srcdir build-tree install checks
+endif
+# END out-of-build-tree check.
+endif
+
+# Is the build-tree configured yet?
+ifeq ($(BUILD_TREE_STATE),)
+ifneq ($(wildcard $(abs_top_builddir)/include/mk/config.mk),)
+BUILD_TREE_STATE := $(BUILD_TREE_NONSRCDIR_INSTALL)
+endif
+endif
+
+ifeq ($(MAKE_3_80_COMPAT),1)
+# Trick make 3.80 into thinking that the default goal is all.
+.PHONY: default
+default: all
+else
+.DEFAULT_GOAL := all
+endif
+
+endif # END autotools, *clean...
+
+BUILD_TREE_STATE ?= $(BUILD_TREE_UNCONFIGURED)
+
+# We can piece together where we're located in the source and object trees with
+# just these two vars and $(CURDIR).
+export abs_top_srcdir abs_top_builddir BUILD_TREE_STATE
+
+endif
diff --git a/ltp_framework/include/mk/features.mk b/ltp_framework/include/mk/features.mk
new file mode 100644
index 0000000..d06a80a
--- /dev/null
+++ b/ltp_framework/include/mk/features.mk
@@ -0,0 +1,55 @@
+#
+# features.mk.in - feature tuning include Makefile.
+#
+# Copyright (C) 2010, Linux Test Project.
+#
+# 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.
+#
+# Garrett Cooper, October 2010
+#
+
+# Path to capset program
+CAPSET :=
+
+# Tools enable knobs
+WITH_EXPECT := no
+
+WITH_PERL := no
+
+WITH_PYTHON := no
+
+# Features knobs
+
+# Is securebits[.h], et all support available?
+HAVE_SECUREBITS := yes
+
+# Test suite knobs
+
+# Enable testcases/kernel/power_management's compile and install?
+ifeq ($(UCLINUX),1)
+WITH_POWER_MANAGEMENT_TESTSUITE := no
+else
+WITH_POWER_MANAGEMENT_TESTSUITE := no
+endif
+
+# Enable testcases/open_posix_testsuite's compile and install?
+WITH_OPEN_POSIX_TESTSUITE := no
+
+# Enable testcases/realtime's compile and install?
+ifeq ($(UCLINUX),1)
+WITH_REALTIME_TESTSUITE := no
+else
+WITH_REALTIME_TESTSUITE := no
+endif
diff --git a/ltp_framework/include/mk/features.mk.default b/ltp_framework/include/mk/features.mk.default
new file mode 100644
index 0000000..53ea30c
--- /dev/null
+++ b/ltp_framework/include/mk/features.mk.default
@@ -0,0 +1,55 @@
+#
+# features.mk.default - feature tuning include Makefile.
+#
+# Copyright (C) 2010, Linux Test Project.
+#
+# 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.
+#
+# Garrett Cooper, October 2010
+#
+
+# Path to capset program
+CAPSET :=
+
+# Tools enable knobs
+WITH_EXPECT := no
+
+WITH_PERL := no
+
+WITH_PYTHON := no
+
+# Features knobs
+
+# Is securebits[.h], et all support available?
+HAVE_SECUREBITS := no
+
+# Test suite knobs
+
+# Enable testcases/kernel/power_management's compile and install?
+ifeq ($(UCLINUX),1)
+WITH_POWER_MANAGEMENT_TESTSUITE := no
+else
+WITH_POWER_MANAGEMENT_TESTSUITE :=
+endif
+
+# Enable testcases/open_posix_testsuite's compile and install?
+WITH_OPEN_POSIX_TESTSUITE := no
+
+# Enable testcases/realtime's compile and install?
+ifeq ($(UCLINUX),1)
+WITH_REALTIME_TESTSUITE := no
+else
+WITH_REALTIME_TESTSUITE := no
+endif
diff --git a/ltp_framework/include/mk/features.mk.in b/ltp_framework/include/mk/features.mk.in
new file mode 100644
index 0000000..3472159
--- /dev/null
+++ b/ltp_framework/include/mk/features.mk.in
@@ -0,0 +1,55 @@
+#
+# features.mk.in - feature tuning include Makefile.
+#
+# Copyright (C) 2010, Linux Test Project.
+#
+# 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.
+#
+# Garrett Cooper, October 2010
+#
+
+# Path to capset program
+CAPSET := @CAPSET@
+
+# Tools enable knobs
+WITH_EXPECT := @WITH_EXPECT@
+
+WITH_PERL := @WITH_PERL@
+
+WITH_PYTHON := @WITH_PYTHON@
+
+# Features knobs
+
+# Is securebits[.h], et all support available?
+HAVE_SECUREBITS := @HAVE_SECUREBITS@
+
+# Test suite knobs
+
+# Enable testcases/kernel/power_management's compile and install?
+ifeq ($(UCLINUX),1)
+WITH_POWER_MANAGEMENT_TESTSUITE := no
+else
+WITH_POWER_MANAGEMENT_TESTSUITE := @WITH_POWER_MANAGEMENT_TESTSUITE@
+endif
+
+# Enable testcases/open_posix_testsuite's compile and install?
+WITH_OPEN_POSIX_TESTSUITE := @WITH_OPEN_POSIX_TESTSUITE@
+
+# Enable testcases/realtime's compile and install?
+ifeq ($(UCLINUX),1)
+WITH_REALTIME_TESTSUITE := no
+else
+WITH_REALTIME_TESTSUITE := @WITH_REALTIME_TESTSUITE@
+endif
diff --git a/ltp_framework/include/mk/functions.mk b/ltp_framework/include/mk/functions.mk
new file mode 100644
index 0000000..fc58737
--- /dev/null
+++ b/ltp_framework/include/mk/functions.mk
@@ -0,0 +1,76 @@
+#
+# A Makefile with a collection of reusable functions.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+SQUOTE := '
+
+# ' # to keep colorized editors from going nuts
+
+MAKE_3_80_realpath = $(shell $(top_srcdir)/scripts/realpath.sh '$(subst $(SQUOTE),\\$(SQUOTE),$(1))')
+
+MAKE_3_80_abspath = $(shell $(top_srcdir)/scripts/abspath.sh '$(subst $(SQUOTE),\\$(SQUOTE),$(1))')
+
+#
+# NOTE (garrcoop):
+#
+# The following functions are (sometimes) split into 3.80 and 3.81+
+# counterparts, and not conditionalized inside of the define(s) to work around
+# an issue with how make 3.80 evaluates defines.
+#
+# SO DO NOT INTERNALIZE CONDITIONALS IN DEFINES OR YOU WILL BREAK MAKE 3.80!
+#
+
+#
+# Generate an install rule which also creates the install directory if needed
+# to avoid unnecessary bourne shell based for-loops and install errors, as well
+# as adhoc install rules.
+#
+# 1 -> Target basename.
+# 2 -> Source directory.
+# 3 -> Destination directory.
+#
+ifdef MAKE_3_80_COMPAT
+define generate_install_rule
+
+INSTALL_FILES += $$(call MAKE_3_80_abspath,$$(DESTDIR)/$(3)/$(1))
+
+$$(call MAKE_3_80_abspath,$$(DESTDIR)/$(3)/$(1)): \
+ $$(call MAKE_3_80_abspath,$$(dir $$(DESTDIR)/$(3)/$(1)))
+ install -m $$(INSTALL_MODE) "$(2)/$(1)" "$$@"
+endef
+else # not MAKE_3_80_COMPAT
+define generate_install_rule
+
+INSTALL_FILES += $$(abspath $$(DESTDIR)/$(3)/$(1))
+
+$$(abspath $$(DESTDIR)/$(3)/$(1)): \
+ $$(abspath $$(dir $$(DESTDIR)/$(3)/$(1)))
+ install -m $$(INSTALL_MODE) "$(2)/$(1)" "$$@"
+endef
+endif # END MAKE_3_80_COMPAT
+
+#
+# Set SUBDIRS to the subdirectories where Makefiles were found.
+#
+define get_make_dirs
+SUBDIRS ?= $$(subst $$(abs_srcdir)/,,$$(patsubst %/Makefile,%,$$(wildcard $$(abs_srcdir)/*/Makefile)))
+SUBDIRS := $$(filter-out $$(FILTER_OUT_DIRS),$$(SUBDIRS))
+endef
diff --git a/ltp_framework/include/mk/generic_leaf_target.inc b/ltp_framework/include/mk/generic_leaf_target.inc
new file mode 100644
index 0000000..a88586f
--- /dev/null
+++ b/ltp_framework/include/mk/generic_leaf_target.inc
@@ -0,0 +1,106 @@
+#
+# Generic leaf rules include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+#
+# generic_leaf_target
+#
+# Generate a set of basic targets (all, clean, install) for a leaf directory
+# (no subdirectories).
+#
+# $(MAKE_DEPS) : What should we execute beforehand as a
+# dependency of $(MAKE_TARGETS)?
+#
+# $(INSTALL_FILES) -> install
+#
+# Helpful variables are:
+#
+# $(MAKE_TARGETS) : What to execute as direct dependencies of
+# all.
+# 1. Defaults to the basename of the targets
+# produced by the %.c -> % implicit pattern
+# rules, e.g. the MAKE_TARGET in a directory
+# like the following:
+#
+# $$ ls /bar
+# foo.c
+#
+# Would be `foo'. Similarly, the following
+# dir structure:
+#
+# $$ ls /bar
+# foo.c zanzibar.c
+#
+# Would be `foo zanzibar'.
+#
+# 2. If you define MAKE_TARGETS as an empty
+# string, this will override the defaults.
+# I did this to avoid providing too much
+# rope to hang one's self in the event of
+# unwanted behavior.
+#
+# $(CLEAN_TARGETS) : What targets should be cleaned (must be
+# real files). This will automatically append
+# adds the .o suffix to all files referenced
+# by $(MAKE_TARGETS)) to CLEAN_TARGETS, if
+# MAKE_TARGETS wasn't defined (see
+# $(MAKE_TARGETS)).
+# $(INSTALL_MODE) : What mode should we using when calling
+# install(1)?
+#
+# Also, if you wish to change the installation directory, from the set default
+# (testcases/bin) you must do something like either one of the following items:
+#
+# Method A:
+#
+# INSTALL_DIR := /path/to/installdir/from/$(DESTDIR)/$(prefix)
+#
+# e.g. if I wanted to install my binaries in testcases/bin, I would do:
+#
+# INSTALL_DIR := testcases/bin
+#
+# in my calling Makefile.
+#
+# Or Method B:
+#
+# INSTALL_DIR := /path/to/installdir/from/$(DESTDIR)
+#
+# e.g. if I wanted to install my binaries in $(libdir) (which may not exist
+# outside of $(prefix) right now, but could in the future), I could do the
+# following:
+#
+# INSTALL_DIR := $(libdir)
+#
+
+.PHONY: all clean install
+
+$(MAKE_TARGETS): | $(MAKE_DEPS)
+
+all: $(MAKE_TARGETS)
+
+clean:: $(CLEAN_DEPS)
+ -$(RM) -f $(CLEAN_TARGETS)
+
+$(INSTALL_FILES): | $(INSTALL_DEPS)
+
+install: $(INSTALL_FILES)
+
+# vim: syntax=make
diff --git a/ltp_framework/include/mk/generic_leaf_target.mk b/ltp_framework/include/mk/generic_leaf_target.mk
new file mode 100644
index 0000000..cb6db5e
--- /dev/null
+++ b/ltp_framework/include/mk/generic_leaf_target.mk
@@ -0,0 +1,24 @@
+#
+# Generic leaf include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+include $(top_srcdir)/include/mk/env_post.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.inc
diff --git a/ltp_framework/include/mk/generic_trunk_target.inc b/ltp_framework/include/mk/generic_trunk_target.inc
new file mode 100644
index 0000000..86d654c
--- /dev/null
+++ b/ltp_framework/include/mk/generic_trunk_target.inc
@@ -0,0 +1,97 @@
+#
+# Generic trunk rules include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+#
+# generic_trunk_target
+#
+# Generate a set of recursive targets to apply over a trunk directory (has
+# directories) -- optionally with a set of trunk-based files.
+#
+# All variables in this canned define are essentially the same as
+# generic_leaf_target, with the exception that the install flow for local
+# targets is:
+#
+# $(INSTALL_FILES) -> trunk-install -> install (recursive)
+#
+# All recursive targets are traverse SUBDIRS as defined by the user, or if
+# undefined, defaults to any subdirectories where Makefile's are contained
+# within.
+#
+# generic_trunk_target specific variables are:
+#
+# RECURSIVE_TARGETS : a list of targets to apply over an entire
+# directory tree. This defaults to
+# `all install'.
+#
+# See generic_leaf_target, generic_target_env_setup, and get_make_dirs for
+# more details and design notes.
+#
+
+include $(top_srcdir)/include/mk/functions.mk
+
+RECURSIVE_TARGETS ?= all install
+
+$(eval $(get_make_dirs))
+
+.PHONY: $(RECURSIVE_TARGETS) $(addprefix trunk-,$(RECURSIVE_TARGETS))
+
+$(SUBDIRS): %:
+ mkdir -m 00755 -p "$@"
+
+$(MAKE_TARGETS): | $(MAKE_DEPS)
+
+trunk-all: $(MAKE_TARGETS)
+
+trunk-clean:: | $(SUBDIRS)
+ $(if $(strip $(CLEAN_TARGETS)),$(RM) -f $(CLEAN_TARGETS))
+
+$(INSTALL_FILES): | $(INSTALL_DEPS)
+
+trunk-install: $(INSTALL_FILES)
+
+# Avoid creating duplicate .PHONY references to all, clean, and install. IIRC,
+# I've seen some indeterministic behavior when one does this in the past with
+# GNU Make...
+.PHONY: $(filter-out $(RECURSIVE_TARGETS),all clean install)
+all: trunk-all
+
+clean:: trunk-clean
+ @set -e; for dir in $(SUBDIRS); do \
+ $(MAKE) -C "$$dir" -f "$(abs_srcdir)/$$dir/Makefile" $@; \
+ done
+ifneq ($(abs_builddir),$(abs_srcdir))
+ $(RM) -Rf $(SUBDIRS)
+endif
+
+install: trunk-install
+
+# Print out CURDIR to check for a recursion issue.
+ifeq ($(strip $(SUBDIRS)),)
+ $(warning CURDIR is: $(CURDIR))
+else
+$(RECURSIVE_TARGETS): %: | $(SUBDIRS)
+ @set -e; for dir in $(SUBDIRS); do \
+ $(MAKE) -C $$dir -f "$(abs_srcdir)/$$dir/Makefile" $@; \
+ done
+endif
+
+# vim: syntax=make
diff --git a/ltp_framework/include/mk/generic_trunk_target.mk b/ltp_framework/include/mk/generic_trunk_target.mk
new file mode 100644
index 0000000..f480ef6
--- /dev/null
+++ b/ltp_framework/include/mk/generic_trunk_target.mk
@@ -0,0 +1,24 @@
+#
+# Generic trunk include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+include $(top_srcdir)/include/mk/env_post.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.inc
diff --git a/ltp_framework/include/mk/gitignore.mk b/ltp_framework/include/mk/gitignore.mk
new file mode 100644
index 0000000..b9932fb
--- /dev/null
+++ b/ltp_framework/include/mk/gitignore.mk
@@ -0,0 +1,51 @@
+#
+# gitignore generation include Makefile.
+#
+# Copyright (C) 2011, Linux Test Project.
+#
+# 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.
+#
+# Garrett Cooper, January 2011
+#
+
+CLEAN_TARGETS+= gitignore_clean
+
+BEFORE:= .gitignore-before
+
+AFTER:= .gitignore-after
+
+IGNORE_DIR_EXPR:= egrep -v "^$$(echo "$(AUTOCONFED_SUBDIRS)" | tr " " "|")"
+
+# NOTE: The underscore is used in place of a dash to avoid implicit rule
+# evaluation in top-level Makefile.
+.PHONY: gitignore_clean
+gitignore_clean:
+ $(RM) -f $(BEFORE) $(AFTER)
+
+$(BEFORE):
+ $(MAKE) distclean
+ $(MAKE) ac-maintainer-clean
+ find . | $(IGNORE_DIR_EXPR) > $@
+
+$(AFTER):
+ $(MAKE) autotools
+ ./configure --prefix=/dev/null
+ $(MAKE) all
+ find . | $(IGNORE_DIR_EXPR) > $@
+ # Set everything in autoconf land back to a sane state.
+ $(MAKE) distclean
+
+.gitignore: | $(BEFORE) $(AFTER)
+ diff -u $(BEFORE) $(AFTER) | grep '^+' | sed -e 's,^\+,,g' > $@
diff --git a/ltp_framework/include/mk/lib.mk b/ltp_framework/include/mk/lib.mk
new file mode 100644
index 0000000..bc0c45d
--- /dev/null
+++ b/ltp_framework/include/mk/lib.mk
@@ -0,0 +1,64 @@
+#
+# library include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+# Makefile to include for libraries.
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+INSTALL_DIR := $(libdir)
+
+# An extension of generic_leaf_target, strictly for libraries.
+.PHONY: install_headers
+
+ifndef LIB
+$(error You must define LIB when including this Makefile)
+endif
+
+install_headers: $(addprefix $(DESTDIR)/$(includedir)/,$(notdir $(HEADER_FILES)))
+
+INSTALL_MODE ?= 00664
+
+MAKE_TARGETS := $(LIB)
+
+LIBSRCS ?= $(wildcard $(abs_srcdir)/*.c)
+
+ifdef MAKE_3_80_COMPAT
+LIBSRCS := $(call MAKE_3_80_abspath,$(LIBSRCS))
+else
+LIBSRCS := $(abspath $(LIBSRCS))
+endif
+
+LIBSRCS := $(subst $(abs_srcdir)/,,$(wildcard $(LIBSRCS)))
+
+LIBSRCS := $(filter-out $(FILTER_OUT_LIBSRCS),$(LIBSRCS))
+
+LIBOBJS := $(LIBSRCS:.c=.o)
+
+$(LIB): $(notdir $(LIBOBJS))
+ if [ -z "$(strip $^)" ] ; then \
+ echo "Cowardly refusing to create empty archive"; \
+ exit 1; \
+ fi
+ $(if $(AR),$(AR),ar) -rc "$@" $^
+ $(if $(RANLIB),$(RANLIB),ranlib) "$@"
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/ltp_framework/include/mk/man.mk b/ltp_framework/include/mk/man.mk
new file mode 100644
index 0000000..f0b4525
--- /dev/null
+++ b/ltp_framework/include/mk/man.mk
@@ -0,0 +1,37 @@
+#
+# Manpage include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+ifeq ($(strip $(MANPREFIX)),)
+$(error $$(MANPREFIX) not defined)
+endif
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+INSTALL_DIR := $(mandir)/man$(MANPREFIX)
+
+INSTALL_MODE := 00644
+
+INSTALL_TARGETS ?= *.$(MANPREFIX)
+
+MAKE_TARGETS :=
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/ltp_framework/include/mk/testcases.mk b/ltp_framework/include/mk/testcases.mk
new file mode 100644
index 0000000..ea26d4f
--- /dev/null
+++ b/ltp_framework/include/mk/testcases.mk
@@ -0,0 +1,55 @@
+#
+# testcases include Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/functions.mk
+
+APICMDS_DIR := $(abs_top_builddir)/tools/apicmds
+
+TKI_DIR := testcases/kernel/include
+
+LSN_H := $(abs_top_builddir)/$(TKI_DIR)/linux_syscall_numbers.h
+
+LIBLTP_DIR := $(abs_top_builddir)/lib
+
+LIBLTP := $(LIBLTP_DIR)/libltp.a
+
+$(APICMDS_DIR)/tst_kvercmp: $(APICMDS_DIR)
+ $(MAKE) -C "$^" -f "$(abs_top_srcdir)/tools/apicmds/Makefile" all
+
+$(LIBLTP): $(LIBLTP_DIR)
+ $(MAKE) -C "$^" -f "$(abs_top_srcdir)/lib/Makefile" all
+
+$(LSN_H): $(abs_top_builddir)/$(TKI_DIR)
+ $(MAKE) -C "$^" -f "$(abs_top_srcdir)/$(TKI_DIR)/Makefile" all
+
+MAKE_DEPS := $(LIBLTP) $(LSN_H)
+
+# For linux_syscall_numbers.h
+CPPFLAGS += -I$(abs_top_builddir)/$(TKI_DIR)
+
+INSTALL_DIR := testcases/bin
+
+LDLIBS += -lltp
+
+$(APICMDS_DIR) $(LIBLTP_DIR) $(abs_top_builddir)/$(TKI_DIR): %:
+ mkdir -p "$@"
diff --git a/ltp_framework/include/open_flags.h b/ltp_framework/include/open_flags.h
new file mode 100644
index 0000000..966d684
--- /dev/null
+++ b/ltp_framework/include/open_flags.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _OPEN_FLAGS_H_
+#define _OPEN_FLAGS_H_
+
+/***********************************************************************
+ * This function attempts to convert open flag bits into human readable
+ * symbols (i.e. O_TRUNC). If there are more than one symbol,
+ * the <sep> string will be placed as a separator between symbols.
+ * Commonly used separators would be a comma "," or pipe "|".
+ * If <mode> is one and not all <openflags> bits can be converted to
+ * symbols, the "UNKNOWN" symbol will be added to return string.
+ *
+ * Return Value
+ * openflags2symbols will return the indentified symbols.
+ * If no symbols are recognized the return value will be a empty
+ * string or the "UNKNOWN" symbol.
+ *
+ * Limitations
+ * Currently (05/96) all known symbols are coded into openflags2symbols.
+ * If new open flags are added this code will have to updated
+ * to know about them or they will not be recognized.
+ *
+ * The Open_symbols must be large enough to hold all possible symbols
+ * for a given system.
+ *
+ ***********************************************************************/
+char *openflags2symbols( int, char *, int );
+
+/***********************************************************************
+ * This function will take a string of comma separated open flags symbols
+ * and translate them into an open flag bitmask.
+ * If any symbol is not valid, -1 is returned. On this error condition
+ * the badname pointer is updated if not NULL. badname will point
+ * to the beginning location of where the invalid symbol was found.
+ * string will be returned unchanged.
+ *
+ * A signal received while parsing string could cause the string to
+ * contain a NULL character in the middle of it.
+ *
+ ***********************************************************************/
+int parse_open_flags( char *, char ** );
+
+#endif
diff --git a/ltp_framework/include/pattern.h b/ltp_framework/include/pattern.h
new file mode 100644
index 0000000..29c75d3
--- /dev/null
+++ b/ltp_framework/include/pattern.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _PATTERN_H_
+#define _PATTERN_H_
+
+/*
+ * pattern_check(buf, buflen, pat, patlen, patshift)
+ *
+ * Check a buffer of length buflen against repeated occurrances of
+ * a pattern whose length is patlen. Patshift can be used to rotate
+ * the pattern by patshift bytes to the left.
+ *
+ * Patshift may be greater than patlen, the pattern will be rotated by
+ * (patshift % patshift) bytes.
+ *
+ * pattern_check returns -1 if the buffer does not contain repeated
+ * occurrances of the indicated pattern (shifted by patshift).
+ *
+ * The algorithm used to check the buffer relies on the fact that buf is
+ * supposed to be repeated copies of pattern. The basic algorithm is
+ * to validate the first patlen bytes of buf against the pat argument
+ * passed in - then validate the next patlen bytes against the 1st patlen
+ * bytes - the next (2*patlen) bytes against the 1st (2*pathen) bytes, and
+ * so on. This algorithm only works when the assumption of a buffer full
+ * of repeated copies of a pattern holds, and gives MUCH better results
+ * then walking the buffer byte by byte.
+ *
+ * Performance wise, It appears to be about 5% slower than doing a straight
+ * memcmp of 2 buffers, but the big win is that it does not require a
+ * 2nd comparison buffer, only the pattern.
+ */
+int pattern_check( char * , int , char * , int , int );
+
+/*
+ * pattern_fill(buf, buflen, pat, patlen, patshift)
+ *
+ * Fill a buffer of length buflen with repeated occurrances of
+ * a pattern whose length is patlen. Patshift can be used to rotate
+ * the pattern by patshift bytes to the left.
+ *
+ * Patshift may be greater than patlen, the pattern will be rotated by
+ * (patshift % patlen) bytes.
+ *
+ * If buflen is not a multiple of patlen, a partial pattern will be written
+ * in the last part of the buffer. This implies that a buffer which is
+ * shorter than the pattern length will receive only a partial pattern ...
+ *
+ * pattern_fill always returns 0 - no validation of arguments is done.
+ *
+ * The algorithm used to fill the buffer relies on the fact that buf is
+ * supposed to be repeated copies of pattern. The basic algorithm is
+ * to fill the first patlen bytes of buf with the pat argument
+ * passed in - then copy the next patlen bytes with the 1st patlen
+ * bytes - the next (2*patlen) bytes with the 1st (2*pathen) bytes, and
+ * so on. This algorithm only works when the assumption of a buffer full
+ * of repeated copies of a pattern holds, and gives MUCH better results
+ * then filling the buffer 1 byte at a time.
+ */
+int pattern_fill( char * , int , char * , int , int );
+
+#endif
diff --git a/ltp_framework/include/random_range.h b/ltp_framework/include/random_range.h
new file mode 100644
index 0000000..c8c4858
--- /dev/null
+++ b/ltp_framework/include/random_range.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _RANDOM_RANGE_H_
+#define _RANDOM_RANGE_H_
+
+int parse_ranges ( char *, int, int, int, int (*)(), char **, char ** );
+int range_min ( char *, int );
+int range_max ( char *, int );
+int range_mult ( char *, int );
+long random_range ( int, int, int, char ** );
+long random_rangel ( long, long, long, char ** );
+long long random_rangell ( long long, long long, long long, char ** );
+void random_range_seed( long );
+long random_bit ( long );
+
+#endif
diff --git a/ltp_framework/include/rmobj.h b/ltp_framework/include/rmobj.h
new file mode 100644
index 0000000..4808ca2
--- /dev/null
+++ b/ltp_framework/include/rmobj.h
@@ -0,0 +1,12 @@
+#ifndef _RMOBJ_H_
+#define _RMOBJ_H_
+
+/*
+ * rmobj() - Remove the specified object. If the specified object is a
+ * directory, recursively remove everything inside of it. If
+ * there are any problems, set errmsg (if it is not NULL) and
+ * return -1. Otherwise return 0.
+ */
+int rmobj( char *object , char **errmesg );
+
+#endif
diff --git a/ltp_framework/include/safe_macros.h b/ltp_framework/include/safe_macros.h
new file mode 100644
index 0000000..3753b7f
--- /dev/null
+++ b/ltp_framework/include/safe_macros.h
@@ -0,0 +1,139 @@
+/*
+ * Safe macros for commonly used syscalls to reduce code duplication in LTP
+ * testcases, and to ensure all errors are caught in said testcases as
+ * gracefully as possible.
+ *
+ * Also satiates some versions of gcc/glibc when the warn_unused_result
+ * attribute is applied to the function call.
+ *
+ * Licensed under the GPLv2.
+ */
+
+#ifndef __TEST_H__
+#error "you must include test.h before this file"
+#else
+
+#ifndef __SAFE_MACROS_H__
+#define __SAFE_MACROS_H__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+char* safe_basename(const char *file, const int lineno,
+ void (*cleanup_fn)(void), char *path);
+#define SAFE_BASENAME(cleanup_fn, path) \
+ safe_basename(__FILE__, __LINE__, (cleanup_fn), (path))
+
+int safe_chdir(const char *file, const int lineno,
+ void (*cleanup_fn)(void), const char *path);
+#define SAFE_CHDIR(cleanup_fn, path) \
+ safe_chdir(__FILE__, __LINE__, (cleanup_fn), (path))
+
+int safe_close(const char *file, const int lineno,
+ void (*cleanup_fn)(void), int fildes);
+#define SAFE_CLOSE(cleanup_fn, fildes) \
+ safe_close(__FILE__, __LINE__, (cleanup_fn), (fildes))
+
+int safe_creat(const char *file, const int lineno,
+ void (*cleanup_fn)(void), char *pathname, mode_t mode);
+#define SAFE_CREAT(cleanup_fn, pathname, mode) \
+ safe_creat(__FILE__, __LINE__, cleanup_fn, (pathname), (mode))
+
+char* safe_dirname(const char *file, const int lineno,
+ void (*cleanup_fn)(void), char *path);
+#define SAFE_DIRNAME(cleanup_fn, path) \
+ safe_dirname(__FILE__, __LINE__, (cleanup_fn), (path))
+
+char* safe_getcwd(const char *file, const int lineno,
+ void (*cleanup_fn)(void), char *buf, size_t size);
+#define SAFE_GETCWD(cleanup_fn, buf, size) \
+ safe_getcwd(__FILE__, __LINE__, (cleanup_fn), (buf), (size))
+
+struct passwd* safe_getpwnam(const char *file, const int lineno,
+ void (*cleanup_fn)(void), const char *name);
+#define SAFE_GETPWNAM(cleanup_fn, name) \
+ safe_getpwnam(__FILE__, __LINE__, cleanup_fn, (name))
+
+int safe_getrusage(const char *file, const int lineno,
+ void (*cleanup_fn)(void), int who, struct rusage *usage);
+#define SAFE_GETRUSAGE(cleanup_fn, who, usage) \
+ safe_getrusage(__FILE__, __LINE__, (cleanup_fn), (who), (usage))
+
+void* safe_malloc(const char *file, const int lineno,
+ void (*cleanup_fn)(void), size_t size);
+#define SAFE_MALLOC(cleanup_fn, size) \
+ safe_malloc(__FILE__, __LINE__, (cleanup_fn), (size))
+
+int safe_mkdir(const char *file, const int lineno,
+ void (*cleanup_fn)(void), const char *pathname, mode_t mode);
+#define SAFE_MKDIR(cleanup_fn, pathname, mode) \
+ safe_mkdir(__FILE__, __LINE__, (cleanup_fn), (pathname), (mode))
+
+void* safe_mmap(const char *file, const int lineno,
+ void (*cleanup_fn)(void), void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset);
+#define SAFE_MMAP(cleanup_fn, addr, length, prot, flags, fd, offset) \
+ safe_mmap(__FILE__, __LINE__, (cleanup_fn), (addr), (length), (prot), \
+ (flags), (fd), (offset))
+
+int safe_munmap(const char *file, const int lineno,
+ void (*cleanup_fn)(void), void *addr, size_t length);
+#define SAFE_MUNMAP(cleanup_fn, addr, length) \
+ safe_munmap(__FILE__, __LINE__, (cleanup_fn), (addr), (length))
+
+int safe_open(const char *file, const int lineno,
+ void (*cleanup_fn)(void), const char *pathname, int oflags, ...);
+#define SAFE_OPEN(cleanup_fn, pathname, oflags, ...) \
+ safe_open(__FILE__, __LINE__, (cleanup_fn), (pathname), (oflags), \
+ ##__VA_ARGS__)
+
+int safe_pipe(const char *file, const int lineno,
+ void (*cleanup_fn)(void), int fildes[2]);
+#define SAFE_PIPE(cleanup_fn, fildes) \
+ safe_pipe(__FILE__, __LINE__, cleanup_fn, (fildes))
+
+ssize_t safe_read(const char *file, const int lineno,
+ void (*cleanup_fn)(void), char len_strict, int fildes, void *buf,
+ size_t nbyte);
+#define SAFE_READ(cleanup_fn, len_strict, fildes, buf, nbyte) \
+ safe_read(__FILE__, __LINE__, cleanup_fn, (len_strict), (fildes), \
+ (buf), (nbyte))
+
+int safe_setegid(const char *file, const int lineno,
+ void (*cleanup_fn)(void), gid_t egid);
+#define SAFE_SETEGID(cleanup_fn, egid) \
+ safe_setegid(__FILE__, __LINE__, cleanup_fn, (egid))
+
+int safe_seteuid(const char *file, const int lineno,
+ void (*cleanup_fn)(void), uid_t euid);
+#define SAFE_SETEUID(cleanup_fn, euid) \
+ safe_seteuid(__FILE__, __LINE__, cleanup_fn, (euid))
+
+int safe_setgid(const char *file, const int lineno,
+ void (*cleanup_fn)(void), gid_t gid);
+#define SAFE_SETGID(cleanup_fn, gid) \
+ safe_setgid(__FILE__, __LINE__, cleanup_fn, (gid))
+
+int safe_setuid(const char *file, const int lineno,
+ void (*cleanup_fn)(void), uid_t uid);
+#define SAFE_SETUID(cleanup_fn, uid) \
+ safe_setuid(__FILE__, __LINE__, cleanup_fn, (uid))
+
+int safe_unlink(const char *file, const int lineno,
+ void (*cleanup_fn)(void), const char *pathname);
+#define SAFE_UNLINK(cleanup_fn, pathname) \
+ safe_unlink(__FILE__, __LINE__, cleanup_fn, (pathname))
+
+ssize_t safe_write(const char *file, const int lineno,
+ void (cleanup_fn)(void), char len_strict, int fildes,
+ const void *buf, size_t nbyte);
+#define SAFE_WRITE(cleanup_fn, len_strict, fildes, buf, nbyte) \
+ safe_write(__FILE__, __LINE__, cleanup_fn, (len_strict), (fildes), \
+ (buf), (nbyte))
+
+#endif
+#endif
diff --git a/ltp_framework/include/search_path.h b/ltp_framework/include/search_path.h
new file mode 100644
index 0000000..c81d42c
--- /dev/null
+++ b/ltp_framework/include/search_path.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+/* $Id: search_path.h,v 1.2 2009/07/20 10:59:32 vapier Exp $ */
+
+
+int search_path(char *cmd, char *res_path, int access_mode, int fullpath);
diff --git a/ltp_framework/include/stamp-h1 b/ltp_framework/include/stamp-h1
new file mode 100644
index 0000000..b330768
--- /dev/null
+++ b/ltp_framework/include/stamp-h1
@@ -0,0 +1 @@
+timestamp for include/config.h
diff --git a/ltp_framework/include/str_to_bytes.h b/ltp_framework/include/str_to_bytes.h
new file mode 100644
index 0000000..977a6b1
--- /dev/null
+++ b/ltp_framework/include/str_to_bytes.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _STR_TO_BYTES_
+#define _STR_TO_BYTES_
+
+int str_to_bytes ( char * );
+long str_to_lbytes ( char * );
+long long str_to_llbytes( char * );
+
+#endif
diff --git a/ltp_framework/include/string_to_tokens.h b/ltp_framework/include/string_to_tokens.h
new file mode 100644
index 0000000..75c7d24
--- /dev/null
+++ b/ltp_framework/include/string_to_tokens.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _STRING_TO_TOKENS_H_
+#define _STRING_TO_TOKENS_H_
+
+/*
+ * string_to_tokens()
+ *
+ * This function parses the string 'arg_string', placing pointers to
+ * the 'separator' separated tokens into the elements of 'arg_array'.
+ * The array is terminated with a null pointer.
+ *
+ * NOTE: This function uses strtok() to parse 'arg_string', and thus
+ * physically alters 'arg_string' by placing null characters where the
+ * separators originally were.
+ */
+int string_to_tokens(char *, char **, int, char *);
+
+#endif
diff --git a/ltp_framework/include/swaponoff.h b/ltp_framework/include/swaponoff.h
new file mode 100644
index 0000000..e3eae3f
--- /dev/null
+++ b/ltp_framework/include/swaponoff.h
@@ -0,0 +1,18 @@
+
+#ifndef __SWAP_ON_OFF_H_
+#define __SWAP_ON_OFF_H_
+
+/*
+ * Read swapon(2) / swapoff(2) for a full history lesson behind the value of
+ * MAX_SWAPFILES.
+ */
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+#define MAX_SWAPFILES 30
+#elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 10)
+#define MAX_SWAPFILES 32
+#else
+#define MAX_SWAPFILES 8
+#endif
+
+#endif
diff --git a/ltp_framework/include/system_specific_hugepages_info.h b/ltp_framework/include/system_specific_hugepages_info.h
new file mode 100644
index 0000000..f5e3c46
--- /dev/null
+++ b/ltp_framework/include/system_specific_hugepages_info.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2009
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _SYS_SPECIFIC_HUGEPAGES_INFO_H_
+#define _SYS_SPECIFIC_HUGEPAGES_INFO_H_
+
+/*Returns Total No. of available Hugepages in the system from /proc/meminfo*/
+int get_no_of_hugepages(void);
+/*Returns No. of Hugepages_Free from /proc/meminfo*/
+int get_no_of_free_hugepages(void);
+/*Returns Hugepages Size from /proc/meminfo*/
+int hugepages_size(void);
+
+#endif
diff --git a/ltp_framework/include/system_specific_process_info.h b/ltp_framework/include/system_specific_process_info.h
new file mode 100644
index 0000000..956d90f
--- /dev/null
+++ b/ltp_framework/include/system_specific_process_info.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2009
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _SYS_SPECIFIC_PROCESS_INFO_H_
+#define _SYS_SPECIFIC_PROCESS_INFO_H_
+
+/* Returns max pid count obtained from reading /proc/sys/kernel/pid_max */
+int get_max_pids(void);
+
+/* Returns number of free pids */
+int get_free_pids(void);
+
+#endif
diff --git a/ltp_framework/include/test.h b/ltp_framework/include/test.h
new file mode 100644
index 0000000..033fdbc
--- /dev/null
+++ b/ltp_framework/include/test.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2009 Cyril Hrubis chrubis@suse.cz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+/* $Id: test.h,v 1.26 2010/01/10 22:27:15 yaberauneya Exp $ */
+
+#ifndef __TEST_H__
+#define __TEST_H__
+
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "compiler.h"
+
+/* Use low 6 bits to encode test type */
+#define TTYPE_MASK 0x3f
+#define TPASS 0 /* Test passed flag */
+#define TFAIL 1 /* Test failed flag */
+#define TBROK 2 /* Test broken flag */
+#define TWARN 4 /* Test warning flag */
+#define TRETR 8 /* Test retire flag */
+#define TINFO 16 /* Test information flag */
+#define TCONF 32 /* Test not appropriate for configuration flag */
+#define TTYPE_RESULT(ttype) ((ttype) & TTYPE_MASK)
+
+#define TERRNO 0x100 /* Append errno information to output */
+#define TTERRNO 0x200 /* Append TEST_ERRNO information to output */
+#define TRERRNO 0x300 /* Capture errno information from TEST_RETURN to
+ output; useful for pthread-like APIs :). */
+
+/*
+ * To determine if you are on a Umk or Unicos system,
+ * use sysconf(_SC_CRAY_SYSTEM). But since _SC_CRAY_SYSTEM
+ * is not defined until 90, it will be define here if not already
+ * defined.
+ * if (sysconf(_SC_CRAY_SYSTEM) == 1)
+ * on UMK
+ * else # returned 0 or -1
+ * on Unicos
+ * This is only being done on CRAY systems.
+ */
+#ifdef CRAY
+#ifndef _SC_CRAY_SYSTEM
+#define _SC_CRAY_SYSTEM 140
+#endif /* ! _SC_CRAY_SYSTEM */
+#endif /* CRAY */
+
+/*
+ * Ensure that NUMSIGS is defined.
+ * It should be defined in signal.h or sys/signal.h on
+ * UNICOS/mk and IRIX systems. On UNICOS systems,
+ * it is not defined, thus it is being set to UNICOS's NSIG.
+ * Note: IRIX's NSIG (signals are 1-(NSIG-1))
+ * is not same meaning as UNICOS/UMK's NSIG (signals 1-NSIG)
+ */
+#ifndef NUMSIGS
+#define NUMSIGS NSIG
+#endif
+
+
+/* defines for unexpected signal setup routine (set_usig.c) */
+#define FORK 1 /* SIGCLD is to be ignored */
+#define NOFORK 0 /* SIGCLD is to be caught */
+#define DEF_HANDLER SIG_ERR /* tells set_usig() to use default signal handler */
+
+/*
+ * The following defines are used to control tst_res and t_result reporting.
+ */
+
+#define TOUTPUT "TOUTPUT" /* The name of the environment variable */
+ /* that can be set to one of the following */
+ /* strings to control tst_res output */
+ /* If not set, TOUT_VERBOSE_S is assumed */
+
+#define TOUT_VERBOSE_S "VERBOSE" /* All test cases reported */
+#define TOUT_NOPASS_S "NOPASS" /* No pass test cases are reported */
+#define TOUT_DISCARD_S "DISCARD" /* No output is reported */
+
+/*
+ * The following defines are used to control tst_tmpdir, tst_wildcard and t_mkchdir
+ */
+
+#define TDIRECTORY "TDIRECTORY" /* The name of the environment variable */
+ /* that if is set, the value (directory) */
+ /* is used by all tests as their working */
+ /* directory. tst_rmdir and t_rmdir will */
+ /* not attempt to clean up. */
+ /* This environment variable should only */
+ /* be set when doing system testing since */
+ /* tests will collide and break and fail */
+ /* because of setting it. */
+
+#define TEMPDIR "/tmp" /* This is the default temporary directory. */
+ /* The environment variable TMPDIR is */
+ /* used prior to this valid by tempnam(3). */
+ /* To control the base location of the */
+ /* temporary directory, set the TMPDIR */
+ /* environment variable to desired path */
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify the number of iterations.
+ * It is supported in parse_opts.c and USC_setup.c.
+ */
+#define USC_ITERATION_ENV "USC_ITERATIONS"
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify to iteration until desired time
+ * in floating point seconds has gone by.
+ * Supported in USC_setup.c.
+ */
+#define USC_LOOP_WALLTIME "USC_LOOP_WALLTIME"
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify that no functional checks are wanted.
+ * It is supported in parse_opts.c and USC_setup.c.
+ */
+#define USC_NO_FUNC_CHECK "USC_NO_FUNC_CHECK"
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify the delay between each loop iteration.
+ * The value is in seconds (fractional numbers are allowed).
+ * It is supported in parse_opts.c.
+ */
+#define USC_LOOP_DELAY "USC_LOOP_DELAY"
+
+/*
+ * fork() can't be used on uClinux systems, so use FORK_OR_VFORK instead,
+ * which will run vfork() on uClinux.
+ * mmap() doesn't support MAP_PRIVATE on uClinux systems, so use
+ * MAP_PRIVATE_EXCEPT_UCLINUX instead, which will skip the option on uClinux.
+ * If MAP_PRIVATE really is required, the test can not be run on uClinux.
+ */
+#ifdef UCLINUX
+#define FORK_OR_VFORK vfork
+#define MAP_PRIVATE_EXCEPT_UCLINUX 0
+#else
+#define FORK_OR_VFORK fork
+#define MAP_PRIVATE_EXCEPT_UCLINUX MAP_PRIVATE
+#endif
+
+/*
+ * lib/forker.c
+ */
+extern int Forker_pids[];
+extern int Forker_npids;
+
+/* lib/tst_res.c */
+const char *strttype(int ttype);
+void tst_res(int ttype, char *fname, char *arg_fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
+void tst_resm(int ttype, char *arg_fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+void tst_brk(int ttype, char *fname, void (*func)(void), char *arg_fmt, ...)
+ __attribute__ ((format (printf, 4, 5)));
+void tst_brkm(int ttype, void (*func)(void), char *arg_fmt, ...)
+ __attribute__ ((format (printf, 3, 4))) LTP_ATTRIBUTE_NORETURN;
+void tst_require_root(void (*func)(void));
+int tst_environ(void);
+void tst_exit(void) LTP_ATTRIBUTE_NORETURN;
+void tst_flush(void);
+
+extern int Tst_count;
+
+/* lib/tst_sig.c */
+void tst_sig(int fork_flag, void (*handler)(), void (*cleanup)());
+
+/* lib/tst_tmpdir.c */
+void tst_tmpdir(void);
+void tst_rmdir(void);
+char *get_tst_tmpdir(void);
+
+/* lib/get_high_address.c */
+char *get_high_address(void);
+
+/* lib/tst_kvercmp.c */
+void tst_getkver(int *k1, int *k2, int *k3);
+int tst_kvercmp(int r1, int r2, int r3);
+
+/* lib/tst_is_cwd.c */
+int tst_is_cwd_nfs(void);
+int tst_is_cwd_v9fs(void);
+int tst_is_cwd_tmpfs(void);
+int tst_is_cwd_ramfs(void);
+
+/* lib/tst_cwd_has_free.c */
+int tst_cwd_has_free(int required_kib);
+
+/* lib/self_exec.c */
+void maybe_run_child(void (*child)(), char *fmt, ...);
+int self_exec(char *argv0, char *fmt, ...);
+
+/* Functions from lib/cloner.c */
+int ltp_clone(unsigned long clone_flags, int (*fn)(void *arg), void *arg,
+ size_t stack_size, void *stack);
+int ltp_clone_malloc(unsigned long clone_flags, int (*fn)(void *arg),
+ void *arg, size_t stacksize);
+int ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg),
+ void *arg);
+#define clone(...) use_the_ltp_clone_functions,do_not_use_clone
+
+/* Functions from lib/mount_utils.c */
+char *get_block_device(const char *path);
+char *get_mountpoint(const char *path);
+
+/* Function from lib/get_path.c */
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
+
+#ifdef TST_USE_COMPAT16_SYSCALL
+#define TCID_BIT_SUFFIX "_16"
+#elif TST_USE_NEWER64_SYSCALL
+#define TCID_BIT_SUFFIX "_64"
+#else
+#define TCID_BIT_SUFFIX ""
+#endif
+#define TCID_DEFINE(ID) char *TCID = (#ID TCID_BIT_SUFFIX)
+
+#endif /* __TEST_H__ */
diff --git a/ltp_framework/include/tlibio.h b/ltp_framework/include/tlibio.h
new file mode 100644
index 0000000..0ac52e4
--- /dev/null
+++ b/ltp_framework/include/tlibio.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+#define LIO_IO_SYNC 00001 /* read/write */
+#define LIO_IO_ASYNC 00002 /* reada/writea/aio_write/aio_read */
+#define LIO_IO_SLISTIO 00004 /* single stride sync listio */
+#define LIO_IO_ALISTIO 00010 /* single stride async listio */
+#define LIO_IO_SYNCV 00020 /* single-buffer readv/writev */
+#define LIO_IO_SYNCP 00040 /* pread/pwrite */
+
+#ifdef sgi
+#define LIO_IO_ATYPES 00077 /* all io types */
+#define LIO_IO_TYPES 00061 /* all io types, non-async */
+#endif /* sgi */
+#if defined(__linux__) && !defined(__UCLIBC__)
+#define LIO_IO_TYPES 00061 /* all io types */
+#define LIO_IO_ATYPES 00077 /* all io types */
+#endif
+#if defined(__sun) || defined(__hpux) || defined(_AIX) || defined(__UCLIBC__)
+#define LIO_IO_TYPES 00021 /* all io types except pread/pwrite */
+#endif /* linux */
+#ifdef CRAY
+#define LIO_IO_TYPES 00017 /* all io types */
+#endif /* CRAY */
+
+#ifndef LIO_IO_ATYPES
+#define LIO_IO_ATYPES LIO_IO_TYPES
+#endif
+
+#define LIO_WAIT_NONE 00010000 /* return asap -- use with care */
+#define LIO_WAIT_ACTIVE 00020000 /* spin looking at iosw fields, or EINPROGRESS */
+#define LIO_WAIT_RECALL 00040000 /* call recall(2)/aio_suspend(3) */
+#define LIO_WAIT_SIGPAUSE 00100000 /* call pause */
+#define LIO_WAIT_SIGACTIVE 00200000 /* spin waiting for signal */
+#if defined(sgi) || defined(__linux__)
+#define LIO_WAIT_CBSUSPEND 00400000 /* aio_suspend waiting for callback */
+#define LIO_WAIT_SIGSUSPEND 01000000 /* aio_suspend waiting for signal */
+#define LIO_WAIT_ATYPES 01760000 /* all async wait types, except nowait */
+#define LIO_WAIT_TYPES 00020000 /* all sync wait types (sorta) */
+#endif /* sgi */
+#if defined(__sun) || defined(__hpux) || defined(_AIX)
+#define LIO_WAIT_TYPES 00300000 /* all wait types, except nowait */
+#endif /* linux */
+#ifdef CRAY
+#define LIO_WAIT_TYPES 00360000 /* all wait types, except nowait */
+#endif /* CRAY */
+
+/* meta wait io */
+/* 00 000 0000 */
+
+#if defined(sgi) || defined(__linux__)
+/* all callback wait types */
+#define LIO_WAIT_CBTYPES (LIO_WAIT_CBSUSPEND)
+/* all signal wait types */
+#define LIO_WAIT_SIGTYPES (LIO_WAIT_SIGPAUSE|LIO_WAIT_SIGACTIVE|LIO_WAIT_SIGSUSPEND)
+/* all aio_{read,write} or lio_listio */
+#define LIO_IO_ASYNC_TYPES (LIO_IO_ASYNC|LIO_IO_SLISTIO|LIO_IO_ALISTIO)
+#endif /* sgi */
+#if defined(__sun) || defined(__hpux) || defined(_AIX)
+/* all signal wait types */
+#define LIO_WAIT_SIGTYPES (LIO_WAIT_SIGPAUSE)
+#endif /* linux */
+#ifdef CRAY
+/* all signal wait types */
+#define LIO_WAIT_SIGTYPES (LIO_WAIT_SIGPAUSE|LIO_WAIT_SIGACTIVE)
+#endif /* CRAY */
+
+/*
+ * This bit provides a way to randomly pick an io type and wait method.
+ * lio_read_buffer() and lio_write_buffer() functions will call
+ * lio_random_methods() with the given method.
+ */
+#define LIO_RANDOM 010000000
+
+/*
+ * This bit provides a way for the programmer to use async i/o with
+ * signals and to use their own signal handler. By default,
+ * the signal will only be given to the system call if the wait
+ * method is LIO_WAIT_SIGPAUSE or LIO_WAIT_SIGACTIVE.
+ * Whenever these wait methods are used, libio signal handler
+ * will be used.
+ */
+#define LIO_USE_SIGNAL 020000000
+
+/*
+ * prototypes/structures for functions in the libio.c module. See comments
+ * in that module, or man page entries for information on the individual
+ * functions.
+ */
+
+int stride_bounds(int offset, int stride, int nstrides,
+ int bytes_per_stride, int *min_byte, int *max_byte);
+
+int lio_set_debug(int level);
+int lio_parse_io_arg1(char *string);
+void lio_help1(char *prefex);
+int lio_parse_io_arg2(char *string, char **badtoken);
+void lio_help2(char *prefex);
+int lio_write_buffer(int fd, int method, char *buffer, int size,
+ int sig, char **errmsg, long wrd);
+
+int lio_read_buffer(int fd, int method, char *buffer, int size,
+ int sig, char **errmsg, long wrd);
+int lio_random_methods(long mask);
+
+#if CRAY
+#include <sys/iosw.h>
+int lio_wait4asyncio(int method, int fd, struct iosw **statptr);
+int lio_check_asyncio(char *io_type, int size, struct iosw *status);
+#endif /* CRAY */
+#if defined (sgi)
+#include <aio.h>
+int lio_wait4asyncio(int method, int fd, aiocb_t *aiocbp);
+int lio_check_asyncio(char *io_type, int size, aiocb_t *aiocbp, int method);
+#endif /* sgi */
+#if defined(__linux__) && !defined(__UCLIBC__)
+#include <aio.h>
+int lio_wait4asyncio(int method, int fd, struct aiocb *aiocbp);
+int lio_check_asyncio(char *io_type, int size, struct aiocb *aiocbp, int method);
+#endif
+
+/*
+ * Define the structure that contains the infomation that is used
+ * by the parsing and help functions.
+ */
+struct lio_info_type {
+ char *token;
+ int bits;
+ char *desc;
+};
+
+
diff --git a/ltp_framework/include/usctest.h b/ltp_framework/include/usctest.h
new file mode 100644
index 0000000..04f0e9c
--- /dev/null
+++ b/ltp_framework/include/usctest.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+/* $Id: usctest.h,v 1.14 2009/08/28 10:03:01 vapier Exp $ */
+
+/**********************************************************
+ *
+ * IRIX/Linux Feature Test and Evaluation - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME : usctest.h
+ *
+ * FUNCTION TITLE : System Call Test Macros
+ *
+ * SYNOPSIS:
+ * See DESCRIPTION below.
+ *
+ * AUTHOR : William Roske
+ *
+ * INITIAL RELEASE : UNICOS 7.0
+ *
+ * DESCRIPTION
+ * TEST(SCALL) - calls a system call
+ * TEST_VOID(SCALL) - same as TEST() but for syscalls with no return value.
+ * TEST_CLEANUP - print the log of errno return counts if STD_ERRNO_LOG
+ * is set.
+ * TEST_PAUSEF(HAND) - Pause for SIGUSR1 if the pause flag is set.
+ * Use "hand" as the interrupt handling function
+ * TEST_PAUSE - Pause for SIGUSR1 if the pause flag is set.
+ * Use internal function to do nothing on signal and go on.
+ * TEST_LOOPING(COUNTER) - Conditional to check if test should
+ * loop. Evaluates to TRUE (1) or FALSE (0).
+ * TEST_ERROR_LOG(eno) - log that this errno was received,
+ * if STD_ERRNO_LOG is set.
+ * TEST_EXP_ENOS(array) - set the bits in TEST_VALID_ENO array at
+ * positions specified in integer "array"
+ *
+ * RETURN VALUE
+ * TEST(SCALL) - Global Variables set:
+ * long TEST_RETURN=return code from SCALL
+ * int TEST_ERRNO=value of errno at return from SCALL
+ * TEST_VOID(SCALL) - Global Variables set:
+ * int TEST_ERRNO=value of errno at return from SCALL
+ * TEST_CLEANUP - None.
+ * TEST_PAUSEF(HAND) - None.
+ * TEST_PAUSE - None.
+ * TEST_LOOPING(COUNTER) - True if COUNTER < STD_LOOP_COUNT or
+ * STD_INFINITE is set.
+ * TEST_ERROR_LOG(eno) - None
+ * TEST_EXP_ENOS(array) - None
+ *
+ * KNOWN BUGS
+ * If you use the TEST_PAUSE or TEST_LOOPING macros, you must
+ * link in parse_opts.o, which contains the code for those functions.
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+
+#ifndef __USCTEST_H__
+#define __USCTEST_H__ 1
+
+#ifndef _SC_CLK_TCK
+#include <unistd.h>
+#endif
+
+#include <sys/param.h>
+
+/*
+ * Ensure that PATH_MAX is defined
+ */
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+#ifndef CRAY
+#ifndef BSIZE
+#define BSIZE BBSIZE
+#endif
+#endif
+
+/***********************************************************************
+ * Define option_t structure type.
+ * Entries in this struct are used by the parse_opts routine
+ * to indicate valid options and return option arguments
+ ***********************************************************************/
+typedef struct {
+ char *option; /* Valid option string (one option only) like "a:" */
+ int *flag; /* pointer to location to set true if option given */
+ char **arg; /* pointer to location to place argument, if needed */
+} option_t;
+
+/***********************************************************************
+ * The following globals are defined in parse_opts.c but must be
+ * externed here because they are used in the macros defined below.
+ ***********************************************************************/
+extern int STD_FUNCTIONAL_TEST, /* turned off by -f to not do functional test */
+ STD_TIMING_ON, /* turned on by -t to print timing stats */
+ STD_PAUSE, /* turned on by -p to pause before loop */
+ STD_INFINITE, /* turned on by -i0 to loop forever */
+ STD_LOOP_COUNT, /* changed by -in to set loop count to n */
+ STD_ERRNO_LOG, /* turned on by -e to log errnos returned */
+ STD_ERRNO_LIST[], /* counts of errnos returned. indexed by errno */
+ STD_COPIES,
+ STD_argind;
+
+extern float STD_LOOP_DURATION, /* wall clock time to iterate */
+ STD_LOOP_DELAY; /* delay time after each iteration */
+
+#define USC_MAX_ERRNO 2000
+
+/**********************************************************************
+ * Prototype for parse_opts routine
+ **********************************************************************/
+extern char *parse_opts(int ac, char **av, const option_t *user_optarr, void (*uhf)());
+
+
+/*
+ * define a structure
+ */
+struct usc_errno_t {
+ int flag;
+};
+
+/***********************************************************************
+ ****
+ ****
+ ****
+ **********************************************************************/
+#ifdef _USC_LIB_
+
+extern long TEST_RETURN;
+extern int TEST_ERRNO;
+extern struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
+
+#else
+/***********************************************************************
+ * Global array of bit masks to indicate errnos that are expected.
+ * Bits set by TEST_EXP_ENOS() macro and used by TEST_CLEANUP() macro.
+ ***********************************************************************/
+struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
+
+/***********************************************************************
+ * Globals for returning the return code and errno from the system call
+ * test macros.
+ ***********************************************************************/
+long TEST_RETURN;
+int TEST_ERRNO;
+
+#endif /* _USC_LIB_ */
+
+/***********************************************************************
+ * structure for timing accumulator and counters
+ ***********************************************************************/
+struct tblock {
+ long tb_max;
+ long tb_min;
+ long tb_total;
+ long tb_count;
+};
+
+/***********************************************************************
+ * The following globals are externed here so that they are accessable
+ * in the macros that follow.
+ ***********************************************************************/
+extern struct tblock tblock;
+extern void STD_go();
+extern int (*_TMP_FUNC)(void);
+extern void STD_opts_help();
+
+
+/***********************************************************************
+ * TEST: calls a system call
+ *
+ * parameters:
+ * SCALL = system call and parameters to execute
+ *
+ ***********************************************************************/
+#define TEST(SCALL) \
+ do { \
+ errno = 0; \
+ TEST_RETURN = SCALL; \
+ TEST_ERRNO = errno; \
+ } while (0)
+
+/***********************************************************************
+ * TEST_VOID: calls a system call
+ *
+ * parameters:
+ * SCALL = system call and parameters to execute
+ *
+ * Note: This is IDENTICAL to the TEST() macro except that it is intended
+ * for use with syscalls returning no values (void syscall()). The
+ * Typecasting nothing (void) into an unsigned integer causes compilation
+ * errors.
+ *
+ ***********************************************************************/
+#define TEST_VOID(SCALL) do { errno = 0; SCALL; TEST_ERRNO = errno; } while (0)
+
+/***********************************************************************
+ * TEST_CLEANUP: print system call timing stats and errno log entries
+ * to stdout if STD_TIMING_ON and STD_ERRNO_LOG are set, respectively.
+ * Do NOT print ANY information if no system calls logged.
+ *
+ * parameters:
+ * none
+ *
+ ***********************************************************************/
+#define TEST_CLEANUP \
+do { \
+ int i; \
+ if (!STD_ERRNO_LOG) \
+ break; \
+ for (i = 0; i < USC_MAX_ERRNO; ++i) { \
+ if (!STD_ERRNO_LIST[i]) \
+ continue; \
+ tst_resm(TINFO, "ERRNO %d:\tReceived %d Times%s", \
+ i, STD_ERRNO_LIST[i], \
+ TEST_VALID_ENO[i].flag ? "" : " ** UNEXPECTED **"); \
+ } \
+} while (0)
+
+/***********************************************************************
+ * TEST_PAUSEF: Pause for SIGUSR1 if the pause flag is set.
+ * Set the user specified function as the interrupt
+ * handler instead of "STD_go"
+ *
+ * parameters:
+ * none
+ *
+ ***********************************************************************/
+#define TEST_PAUSEF(HANDLER) \
+do { \
+ if (STD_PAUSE) { \
+ _TMP_FUNC = (int (*)())signal(SIGUSR1, HANDLER); \
+ pause(); \
+ signal(SIGUSR1, (void (*)())_TMP_FUNC); \
+ } \
+} while (0)
+
+/***********************************************************************
+ * TEST_PAUSE: Pause for SIGUSR1 if the pause flag is set.
+ * Just continue when signal comes in.
+ *
+ * parameters:
+ * none
+ *
+ ***********************************************************************/
+#define TEST_PAUSE usc_global_setup_hook();
+int usc_global_setup_hook();
+
+/***********************************************************************
+ * TEST_LOOPING now call the usc_test_looping function.
+ * The function will return 1 if the test should continue
+ * iterating.
+ *
+ ***********************************************************************/
+#define TEST_LOOPING usc_test_looping
+int usc_test_looping(int counter);
+
+/***********************************************************************
+ * TEST_ERROR_LOG(eno): log this errno if STD_ERRNO_LOG flag set
+ *
+ * parameters:
+ * int eno: the errno location in STD_ERRNO_LIST to log.
+ *
+ ***********************************************************************/
+#define TEST_ERROR_LOG(eno) \
+do { \
+ int _eno = (eno); \
+ if ((STD_ERRNO_LOG) && (_eno < USC_MAX_ERRNO)) \
+ STD_ERRNO_LIST[_eno]++; \
+} while (0)
+
+/***********************************************************************
+ * TEST_EXP_ENOS(array): set the bits associated with the nput errnos
+ * in the TEST_VALID_ENO array.
+ *
+ * parameters:
+ * int array[]: a zero terminated array of errnos expected.
+ *
+ ***********************************************************************/
+#define TEST_EXP_ENOS(array) \
+do { \
+ int i = 0; \
+ while (array[i] != 0) { \
+ if (array[i] < USC_MAX_ERRNO) \
+ TEST_VALID_ENO[array[i]].flag = 1; \
+ ++i; \
+ } \
+} while (0)
+
+#endif /* end of __USCTEST_H__ */
diff --git a/ltp_framework/include/write_log.h b/ltp_framework/include/write_log.h
new file mode 100644
index 0000000..84d6313
--- /dev/null
+++ b/ltp_framework/include/write_log.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#ifndef _WRITE_LOG_H_
+#define _WRITE_LOG_H_
+
+/*
+ * Constants defining the max size of various wlog_rec fields. ANY SIZE
+ * CHANGES HERE MUST BE REFLECTED IN THE WLOG_REC_DISK STRUCTURE DEFINED
+ * BELOW.
+ */
+
+#define WLOG_MAX_PATH 128
+#define WLOG_MAX_PATTERN 64
+#define WLOG_MAX_HOST 8
+#define WLOG_REC_MAX_SIZE (sizeof(struct wlog_rec)+WLOG_MAX_PATH+WLOG_MAX_PATTERN+WLOG_MAX_HOST+2)
+
+/*
+ * User view of a write log record. Note that this is not necessiliary
+ * how the data is formatted on disk (signifigant compression occurrs), so
+ * don't expect to od the write log file and see things formatted this way.
+ */
+
+struct wlog_rec {
+ int w_pid; /* pid doing the write */
+ int w_offset; /* file offset */
+ int w_nbytes; /* # bytes written */
+ int w_oflags; /* low-order open() flags */
+ int w_done; /* 1 if io confirmed done */
+ int w_async; /* 1 if async write (writea) */
+
+ char w_host[WLOG_MAX_HOST+1]; /* host doing write - */
+ /* null terminated */
+ int w_hostlen; /* host name length */
+ char w_path[WLOG_MAX_PATH+1]; /* file written to - */
+ /* null terminated */
+ int w_pathlen; /* file name length */
+ char w_pattern[WLOG_MAX_PATTERN+1]; /* pattern written - */
+ /* null terminated */
+ int w_patternlen; /* pattern length */
+};
+
+#ifndef uint
+#define uint unsigned int
+#endif
+
+/*
+ * On-disk structure of a wlog_rec. Actually, the record consists of
+ * 3 parts: [wlog_rec_disk structure][variable length data][length]
+ * where length is a 2 byte field containing the total record length
+ * (including the 2 bytes). It is used for scanning the logfile in reverse
+ * order.
+ *
+ * The variable length data includes the path, host, and pattern (in that
+ * order). The lengths of these pieces of data are held in the
+ * wlog_rec_disk structure. Thus, the actual on-disk record looks like
+ * this (top is lower byte offset):
+ *
+ * struct wlog_rec_disk
+ * path (w_pathlen bytes - not null terminated)
+ * host (w_hostlen bytes - not null terminated)
+ * pattern (w_patternlen bytes - not null terminated)
+ * 2-byte record length
+ *
+ * Another way of looking at it is:
+ *
+ * <struct wlog_rec_disk><path (wpathlen bytes)>-->
+ * --><host (w_hostlen bytes)><pattern (w_patternlen bytes)><length (2 bytes)>
+ *
+ * The maximum length of this record is defined by the WLOG_REC_MAX_SIZE
+ * record. Note that the 2-byte record length forces this to be
+ * <= 64k bytes.
+ *
+ * Note that there is lots of bit-masking done here. The w_pathlen,
+ * w_hostlen, and w_patternlen fields MUST have enough bits to hold
+ * WLOG_MAX_PATH, WLOG_MAX_HOST, and WLOG_MAX_PATTERN bytes respectivly.
+ */
+
+struct wlog_rec_disk {
+#ifdef CRAY
+ uint w_offset : 44; /* file offset */
+ uint w_extra0 : 20; /* EXTRA BITS IN WORD 0 */
+#else
+ /* NB: sgi is pissy about fields > 32 bit, even cc -mips3 */
+ uint w_offset : 32; /* file offset */
+ uint w_extra0 : 32; /* EXTRA BITS IN WORD 0 */
+#endif
+
+ uint w_nbytes : 32; /* # bytes written */
+ uint w_oflags : 32; /* low-order open() flags */
+
+ uint w_pid : 17; /* pid doing the write */
+ uint w_pathlen : 7; /* length of file path */
+ uint w_patternlen: 6; /* length of pattern */
+ uint w_hostlen : 4; /* length of host */
+ uint w_done : 1; /* 1 if io confirmed done */
+ uint w_async : 1; /* 1 if async write (writea) */
+ uint w_extra2 : 28; /* EXTRA BITS IN WORD 2 */
+};
+
+/*
+ * write log file datatype. wlog_open() initializes this structure
+ * which is then passed around to the various wlog_xxx routines.
+ */
+
+struct wlog_file {
+ int w_afd; /* append fd */
+ int w_rfd; /* random-access fd */
+ char w_file[1024]; /* name of the write_log */
+};
+
+/*
+ * return value defines for the user-supplied function to
+ * wlog_scan_backward().
+ */
+
+#define WLOG_STOP_SCAN 0
+#define WLOG_CONTINUE_SCAN 1
+
+/*
+ * wlog prototypes
+ */
+
+#if __STDC__
+extern int wlog_open(struct wlog_file *wfile, int trunc, int mode);
+extern int wlog_close(struct wlog_file *wfile);
+extern int wlog_record_write(struct wlog_file *wfile,
+ struct wlog_rec *wrec, long offset);
+extern int wlog_scan_backward(struct wlog_file *wfile, int nrecs,
+ int (*func)(struct wlog_rec *rec),
+ long data);
+#else
+int wlog_open();
+int wlog_close();
+int wlog_record_write();
+int wlog_scan_backward();
+#endif
+
+extern char Wlog_Error_String[];
+
+#endif /* _WRITE_LOG_H_ */
+
diff --git a/ltp_framework/lib/Makefile b/ltp_framework/lib/Makefile
new file mode 100644
index 0000000..661c0a1
--- /dev/null
+++ b/ltp_framework/lib/Makefile
@@ -0,0 +1,45 @@
+#
+# lib Makefile.
+#
+# Copyright (C) 2009, Cisco Systems 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.
+#
+# Garrett Cooper, July 2009
+#
+
+top_srcdir ?= ..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+
+ifeq ($(UCLINUX),1)
+CFLAGS += -D_USC_LIB_
+endif
+
+#CPPFLAGS += -DGARRETT_IS_A_PEDANTIC_BASTARD
+
+FILTER_OUT_LIBSRCS := mount_utils.c
+
+LIB := libltp.a
+
+pc_file := $(DESTDIR)/$(datarootdir)/pkgconfig/ltp.pc
+
+INSTALL_TARGETS := $(pc_file)
+
+$(pc_file):
+ test -d "$(@D)" || mkdir -p "$(@D)"
+ install -m $(INSTALL_MODE) "$(builddir)/$(@F)" "$@"
+
+include $(top_srcdir)/include/mk/lib.mk
diff --git a/ltp_framework/lib/cloner.c b/ltp_framework/lib/cloner.c
new file mode 100644
index 0000000..bf9eed1
--- /dev/null
+++ b/ltp_framework/lib/cloner.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2009
+ * Some wrappers for clone functionality. Thrown together by Serge Hallyn
+ * <serue@us.ibm.com> based on existing clone usage in ltp.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h> /* fork, getpid, sleep */
+#include <string.h>
+#include <stdlib.h> /* exit */
+#include <sched.h> /* clone */
+#include "test.h"
+
+#undef clone /* we want to use clone() */
+
+/* copied from several other files under ltp */
+#if defined (__s390__) || (__s390x__)
+#define clone __clone
+extern int __clone(int(void*),void*,int,void*);
+#elif defined(__ia64__)
+#define clone2 __clone2
+/* Prototype provided by David Mosberger */
+extern int __clone2(int (*fn) (void *arg), void *child_stack_base,
+ size_t child_stack_size, int flags, void *arg,
+ pid_t *parent_tid, void *tls, pid_t *child_tid);
+#endif
+
+/***********************************************************************
+ * ltp_clone: wrapper for clone to hide the architecture dependencies.
+ * 1. hppa takes bottom of stack and no stacksize (stack grows up)
+ * 2. __ia64__ takes bottom of stack and uses clone2
+ * 3. all others take top of stack (stack grows down)
+ ***********************************************************************/
+int
+ltp_clone(unsigned long clone_flags, int (*fn)(void *arg), void *arg,
+ size_t stack_size, void *stack)
+{
+ int ret;
+
+#if defined(__hppa__)
+ ret = clone(fn, stack, clone_flags, arg);
+#elif defined(__ia64__)
+ ret = clone2(fn, stack, stack_size, clone_flags, arg, NULL, NULL, NULL);
+#else
+ /*
+ * For archs where stack grows downwards, stack points to the topmost
+ * address of the memory space set up for the child stack.
+ */
+ ret = clone(fn, (stack ? stack + stack_size : NULL),
+ clone_flags, arg);
+#endif
+
+ return ret;
+}
+
+/***********************************************************************
+ * ltp_clone_malloc: also does the memory allocation for clone with a
+ * caller-specified size.
+ ***********************************************************************/
+int
+ltp_clone_malloc(unsigned long clone_flags, int (*fn)(void *arg), void *arg,
+ size_t stack_size)
+{
+ void *stack;
+ int ret;
+ int saved_errno;
+
+ if ((stack = malloc(stack_size)) == NULL)
+ return -1;
+
+ ret = ltp_clone(clone_flags, fn, arg, stack_size, stack);
+
+ if (ret == -1) {
+ saved_errno = errno;
+ free(stack);
+ errno = saved_errno;
+ }
+
+ return ret;
+}
+
+/***********************************************************************
+ * ltp_clone_quick: calls ltp_clone_malloc with predetermined stack size.
+ * Experience thus far suggests that one page is often insufficient,
+ * while 4*getpagesize() seems adequate.
+ ***********************************************************************/
+int
+ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg), void *arg)
+{
+ size_t stack_size = getpagesize() * 4;
+
+ return ltp_clone_malloc(clone_flags, fn, arg, stack_size);
+} \ No newline at end of file
diff --git a/ltp_framework/lib/dataascii.c b/ltp_framework/lib/dataascii.c
new file mode 100644
index 0000000..0188eca
--- /dev/null
+++ b/ltp_framework/lib/dataascii.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#include <stdio.h>
+#include <string.h>
+#include "dataascii.h"
+
+#define CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjiklmnopqrstuvwxyz\n"
+#define CHARS_SIZE sizeof(CHARS)
+
+#ifdef UNIT_TEST
+#include <stdlib.h> /* malloc */
+#endif
+
+static char Errmsg[80];
+
+int
+dataasciigen(listofchars, buffer, bsize, offset)
+char *listofchars; /* a null terminated list of characters */
+char *buffer;
+int bsize;
+int offset;
+{
+ int cnt;
+ int total;
+ int ind; /* index into CHARS array */
+ char *chr;
+ int chars_size;
+ char *charlist;
+
+ chr=buffer;
+ total=offset+bsize;
+
+ if (listofchars == NULL) {
+ charlist=CHARS;
+ chars_size=CHARS_SIZE;
+ }
+ else {
+ charlist=listofchars;
+ chars_size=strlen(listofchars);
+ }
+
+ for (cnt=offset; cnt<total; cnt++) {
+ ind=cnt%chars_size;
+ *chr++=charlist[ind];
+ }
+
+ return bsize;
+
+} /* end of dataasciigen */
+
+int
+dataasciichk(listofchars, buffer, bsize, offset, errmsg)
+char *listofchars; /* a null terminated list of characters */
+char *buffer;
+int bsize;
+int offset;
+char **errmsg;
+{
+ int cnt;
+ int total;
+ int ind; /* index into CHARS array */
+ char *chr;
+ int chars_size;
+ char *charlist;
+
+ chr=buffer;
+ total=offset+bsize;
+
+ if (listofchars == NULL) {
+ charlist=CHARS;
+ chars_size=CHARS_SIZE;
+ }
+ else {
+ charlist=listofchars;
+ chars_size=strlen(listofchars);
+ }
+
+ if (errmsg != NULL) {
+ *errmsg = Errmsg;
+ }
+
+ for (cnt=offset; cnt<total; chr++, cnt++) {
+ ind=cnt%chars_size;
+ if (*chr != charlist[ind]) {
+ sprintf(Errmsg,
+ "data mismatch at offset %d, exp:%#o, act:%#o", cnt,
+ charlist[ind], *chr);
+ return cnt;
+ }
+ }
+
+ sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
+ return -1; /* buffer is ok */
+
+} /* end of dataasciichk */
+
+
+#if UNIT_TEST
+
+/***********************************************************************
+ * main for doing unit testing
+ ***********************************************************************/
+int
+main(ac, ag)
+int ac;
+char **ag;
+{
+
+int size=1023;
+char *buffer;
+int ret;
+char *errmsg;
+
+ if ((buffer=(char *)malloc(size)) == NULL) {
+ perror("malloc");
+ exit(2);
+ }
+
+ dataasciigen(NULL, buffer, size, 0);
+ printf("dataasciigen(NULL, buffer, %d, 0)\n", size);
+
+ ret=dataasciichk(NULL, buffer, size, 0, &errmsg);
+ printf("dataasciichk(NULL, buffer, %d, 0, &errmsg) returned %d %s\n",
+ size, ret, errmsg);
+
+ if (ret == -1)
+ printf("\tPASS return value is -1 as expected\n");
+ else
+ printf("\tFAIL return value is %d, expected -1\n", ret);
+
+ ret=dataasciichk(NULL, &buffer[1], size-1, 1, &errmsg);
+ printf("dataasciichk(NULL, &buffer[1], %d, 1, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+ if (ret == -1)
+ printf("\tPASS return value is -1 as expected\n");
+ else
+ printf("\tFAIL return value is %d, expected -1\n", ret);
+
+ buffer[25]= 0x0;
+ printf("changing char 25\n");
+
+ ret=dataasciichk(NULL, &buffer[1], size-1, 1, &errmsg);
+ printf("dataasciichk(NULL, &buffer[1], %d, 1, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+ if (ret == 25)
+ printf("\tPASS return value is 25 as expected\n");
+ else
+ printf("\tFAIL return value is %d, expected 25\n", ret);
+
+ dataasciigen("this is a test of the my string" , buffer, size, 0);
+ printf("dataasciigen(\"this is a test of the my string\", buffer, %d, 0)\n", size);
+
+ ret=dataasciichk("this is a test of the my string", buffer, size, 0, &errmsg);
+ printf("dataasciichk(\"this is a test of the my string\", buffer, %d, 0, &errmsg) returned %d %s\n",
+ size, ret, errmsg);
+
+ if (ret == -1)
+ printf("\tPASS return value is -1 as expected\n");
+ else
+ printf("\tFAIL return value is %d, expected -1\n", ret);
+
+ ret=dataasciichk("this is a test of the my string", &buffer[1], size-1, 1, &errmsg);
+ printf("dataasciichk(\"this is a test of the my string\", &buffer[1], %d, 1, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+ if (ret == -1)
+ printf("\tPASS return value is -1 as expected\n");
+ else
+ printf("\tFAIL return value is %d, expected -1\n", ret);
+
+ buffer[25]= 0x0;
+ printf("changing char 25\n");
+
+ ret=dataasciichk("this is a test of the my string", &buffer[1], size-1, 1, &errmsg);
+ printf("dataasciichk(\"this is a test of the my string\", &buffer[1], %d, 1, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+ if (ret == 25)
+ printf("\tPASS return value is 25 as expected\n");
+ else
+ printf("\tFAIL return value is %d, expected 25\n", ret);
+
+ exit(0);
+}
+
+#endif
diff --git a/ltp_framework/lib/databin.c b/ltp_framework/lib/databin.c
new file mode 100644
index 0000000..c0f4307
--- /dev/null
+++ b/ltp_framework/lib/databin.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#include <stdio.h>
+#include <sys/param.h>
+#include <string.h> /* memset */
+#include <stdlib.h> /* rand */
+#include "databin.h"
+
+#if UNIT_TEST
+#include <malloc.h>
+#endif
+
+static char Errmsg[80];
+
+void
+databingen (mode, buffer, bsize, offset)
+int mode; /* either a, c, r, o, z or C */
+char *buffer; /* buffer pointer */
+int bsize; /* size of buffer */
+int offset; /* offset into the file where buffer starts */
+{
+int ind;
+
+ switch (mode)
+ {
+ default:
+ case 'a': /* alternating bit pattern */
+ memset(buffer,0x55,bsize);
+ break;
+
+ case 'c': /* checkerboard pattern */
+ memset(buffer,0xf0,bsize);
+ break;
+
+ case 'C': /* */
+ for (ind=0;ind< bsize;ind++) {
+ buffer[ind] = ((offset+ind)%8 & 0177);
+ }
+ break;
+
+ case 'o':
+ memset(buffer,0xff,bsize);
+ break;
+
+ case 'z':
+ memset(buffer,0x0,bsize);
+ break;
+
+ case 'r': /* random */
+ for (ind=0;ind< bsize;ind++) {
+ buffer[ind] = (rand () & 0177) | 0100;
+ }
+ }
+}
+
+/***********************************************************************
+ *
+ * return values:
+ * >= 0 : error at byte offset into the file, offset+buffer[0-(bsize-1)]
+ * < 0 : no error
+ ***********************************************************************/
+int
+databinchk(mode, buffer, bsize, offset, errmsg)
+int mode; /* either a, c, r, z, o, or C */
+char *buffer; /* buffer pointer */
+int bsize; /* size of buffer */
+int offset; /* offset into the file where buffer starts */
+char **errmsg;
+{
+ int cnt;
+ unsigned char *chr;
+ int total;
+ long expbits;
+ long actbits;
+
+ chr = (unsigned char *) buffer;
+ total=bsize;
+
+ if (errmsg != NULL) {
+ *errmsg = Errmsg;
+ }
+
+ switch (mode)
+ {
+ default:
+ case 'a': /* alternating bit pattern */
+ expbits=0x55;
+ break;
+
+ case 'c': /* checkerboard pattern */
+ expbits=0xf0;
+ break;
+
+ case 'C': /* counting pattern */
+ for (cnt=0;cnt< bsize;cnt++) {
+ expbits = ((offset+cnt)%8 & 0177);
+
+ if (buffer[cnt] != expbits) {
+ sprintf(Errmsg,
+ "data mismatch at offset %d, exp:%#lo, act:%#o",
+ offset+cnt, expbits, buffer[cnt]);
+ return offset+cnt;
+ }
+ }
+ sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
+ return -1;
+
+ case 'o':
+ expbits=0xff;
+ break;
+
+ case 'z':
+ expbits=0;
+ break;
+
+ case 'r':
+ return -1; /* no check can be done for random */
+ }
+
+ for (cnt=0; cnt<bsize; chr++, cnt++) {
+ actbits = (long)*chr;
+
+ if (actbits != expbits) {
+ sprintf(Errmsg, "data mismatch at offset %d, exp:%#lo, act:%#lo",
+ offset+cnt, expbits, actbits);
+ return offset+cnt;
+ }
+ }
+
+ sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
+ return -1; /* all ok */
+}
+
+#if UNIT_TEST
+
+/***********************************************************************
+ * main for doing unit testing
+ ***********************************************************************/
+int
+main(ac, ag)
+int ac;
+char **ag;
+{
+
+ int size=1023;
+ int offset;
+ int number;
+ unsigned char *buffer;
+ int ret;
+ char *errmsg;
+
+ if ((buffer=(unsigned char *)malloc(size)) == NULL) {
+ perror("malloc");
+ exit(2);
+ }
+
+
+printf("***** for a ****************************\n");
+ databingen('a', buffer, size, 0);
+ printf("databingen('a', buffer, %d, 0)\n", size);
+
+ ret=databinchk('a', buffer, size, 0, &errmsg);
+ printf("databinchk('a', buffer, %d, 0, &errmsg) returned %d: %s\n",
+ size, ret, errmsg);
+ if (ret == -1)
+ printf("\tPASS return value of -1 as expected\n");
+ else
+ printf("\tFAIL return value %d, expected -1\n", ret);
+
+ offset=232400;
+ ret=databinchk('a', &buffer[1], size-1, offset, &errmsg);
+ printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
+ size, offset, ret, errmsg);
+ if (ret == -1)
+ printf("\tPASS return value of -1 as expected\n");
+ else
+ printf("\tFAIL return value %d, expected -1\n", ret);
+
+ buffer[15]= 0x0;
+ printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
+ number=offset+15;
+
+ ret=databinchk('a', &buffer[1], size-1, offset+1, &errmsg);
+ printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
+ size-1, offset+1, ret, errmsg);
+ if (ret == number)
+ printf("\tPASS return value of %d as expected\n", number);
+ else
+ printf("\tFAIL return value %d, expected %d\n", ret, number);
+
+
+
+printf("***** for c ****************************\n");
+ databingen('c', buffer, size, 0);
+ printf("databingen('c', buffer, %d, 0)\n", size);
+
+ ret=databinchk('c', buffer, size, 0, &errmsg);
+ printf("databinchk('c', buffer, %d, 0, &errmsg) returned %d: %s\n",
+ size, ret, errmsg);
+ if (ret == -1)
+ printf("\tPASS return value of -1 as expected\n");
+ else
+ printf("\tFAIL return value %d, expected -1\n", ret);
+
+ offset=232400;
+ ret=databinchk('c', &buffer[1], size-1, offset, &errmsg);
+ printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
+ size, offset, ret, errmsg);
+ if (ret == -1)
+ printf("\tPASS return value of -1 as expected\n");
+ else
+ printf("\tFAIL return value %d, expected -1\n", ret);
+
+ buffer[15]= 0x0;
+ printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
+ number=offset+15;
+
+ ret=databinchk('c', &buffer[1], size-1, offset+1, &errmsg);
+ printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
+ size-1, offset+1, ret, errmsg);
+ if (ret == number)
+ printf("\tPASS return value of %d as expected\n", number);
+ else
+ printf("\tFAIL return value %d, expected %d\n", ret, number);
+
+printf("***** for C ****************************\n");
+
+ databingen('C', buffer, size, 0);
+ printf("databingen('C', buffer, %d, 0)\n", size);
+
+ ret=databinchk('C', buffer, size, 0, &errmsg);
+ printf("databinchk('C', buffer, %d, 0, &errmsg) returned %d: %s\n",
+ size, ret, errmsg);
+ if (ret == -1)
+ printf("\tPASS return value of -1 as expected\n");
+ else
+ printf("\tFAIL return value %d, expected -1\n", ret);
+
+ offset=18;
+ ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
+ printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
+ size-18, ret, errmsg);
+ if (ret == -1)
+ printf("\tPASS return value of -1 as expected\n");
+ else
+ printf("\tFAIL return value %d, expected -1\n", ret);
+
+ buffer[20]= 0x0;
+ buffer[21]= 0x0;
+ printf("changing char 20 and 21 to 0x0 (offset %d and %d)\n", 20,
+ 21);
+
+ ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
+ printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
+ size-18, ret, errmsg);
+
+ if (ret == 20 || ret == 21)
+ printf("\tPASS return value of %d or %d as expected\n",
+ 20, 21);
+ else
+ printf("\tFAIL return value %d, expected %d or %d\n", ret,
+ 20, 21 );
+
+ exit(0);
+
+}
+
+#endif
diff --git a/ltp_framework/lib/datapid.c b/ltp_framework/lib/datapid.c
new file mode 100644
index 0000000..eb84b1d
--- /dev/null
+++ b/ltp_framework/lib/datapid.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+/************
+
+64 bits in a Cray word
+
+ 12345678901234567890123456789012
+1234567890123456789012345678901234567890123456789012345678901234
+________________________________________________________________
+< pid >< word-offset in file (same #) >< pid >
+
+1234567890123456789012345678901234567890123456789012345678901234
+________________________________________________________________
+< pid >< offset in file of this word >< pid >
+
+
+8 bits to a bytes == character
+ NBPW 8
+************/
+
+#include <stdio.h>
+#include <sys/param.h>
+#ifdef UNIT_TEST
+#include <unistd.h>
+#include <stdlib.h>
+#endif
+
+static char Errmsg[80];
+
+#define LOWER16BITS(X) (X & 0177777)
+#define LOWER32BITS(X) (X & 0xffffffff)
+
+/***
+#define HIGHBITS(WRD, bits) ( (-1 << (64-bits)) & WRD)
+#define LOWBITS(WRD, bits) ( (-1 >> (64-bits)) & WRD)
+****/
+
+#define NBPBYTE 8 /* number bits per byte */
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+/***********************************************************************
+ *
+ *
+ * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 15 bytes
+ * 1234567890123456789012345678901234567890123456789012345678901234 bits
+ * ________________________________________________________________ 1 word
+ * < pid >< offset in file of this word >< pid >
+ *
+ * the words are put together where offset zero is the start.
+ * thus, offset 16 is the start of the second full word
+ * Thus, offset 8 is in middle of word 1
+ ***********************************************************************/
+int
+datapidgen(pid, buffer, bsize, offset)
+int pid;
+char *buffer;
+int bsize;
+int offset;
+{
+#if CRAY
+
+ int cnt;
+ int tmp;
+ char *chr;
+ long *wptr;
+ long word;
+ int woff; /* file offset for the word */
+ int boff; /* buffer offset or index */
+ int num_full_words;
+
+ num_full_words = bsize/NBPW;
+ boff = 0;
+
+ if (cnt=(offset % NBPW)) { /* partial word */
+
+ woff = offset - cnt;
+#if DEBUG
+printf("partial at beginning, cnt = %d, woff = %d\n", cnt, woff);
+#endif
+
+ word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
+
+ chr = (char *)&word;
+
+ for (tmp=0; tmp<cnt; tmp++) { /* skip unused bytes */
+ chr++;
+ }
+
+ for (; boff<(NBPW-cnt) && boff<bsize; boff++, chr++) {
+ buffer[boff] = *chr;
+ }
+ }
+
+ /*
+ * full words
+ */
+
+ num_full_words = (bsize-boff)/NBPW;
+
+ woff = offset+boff;
+
+ for (cnt=0; cnt<num_full_words; woff += NBPW, cnt++) {
+
+ word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
+
+ chr = (char *)&word;
+ for (tmp=0; tmp<NBPW; tmp++, chr++) {
+ buffer[boff++] = *chr;
+ }
+/****** Only if wptr is a word ellined
+ wptr = (long *)&buffer[boff];
+ *wptr = word;
+ boff += NBPW;
+*****/
+
+ }
+
+ /*
+ * partial word at end of buffer
+ */
+
+ if (cnt=((bsize-boff) % NBPW)) {
+#if DEBUG
+printf("partial at end\n");
+#endif
+ word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
+
+ chr = (char *)&word;
+
+ for (tmp=0; tmp<cnt && boff<bsize; tmp++, chr++) {
+ buffer[boff++] = *chr;
+ }
+ }
+
+ return bsize;
+
+#else
+ return -1; /* not support on non-64 bits word machines */
+
+#endif
+
+}
+
+/***********************************************************************
+ *
+ *
+ ***********************************************************************/
+int
+datapidchk(pid, buffer, bsize, offset, errmsg)
+int pid;
+char *buffer;
+int bsize;
+int offset;
+char **errmsg;
+{
+#if CRAY
+
+ int cnt;
+ int tmp;
+ char *chr;
+ long *wptr;
+ long word;
+ int woff; /* file offset for the word */
+ int boff; /* buffer offset or index */
+ int num_full_words;
+
+
+ if (errmsg != NULL) {
+ *errmsg = Errmsg;
+ }
+
+
+ num_full_words = bsize/NBPW;
+ boff = 0;
+
+ if (cnt=(offset % NBPW)) { /* partial word */
+ woff = offset - cnt;
+ word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
+
+ chr = (char *)&word;
+
+ for (tmp=0; tmp<cnt; tmp++) { /* skip unused bytes */
+ chr++;
+ }
+
+ for (; boff<(NBPW-cnt) && boff<bsize; boff++, chr++) {
+ if (buffer[boff] != *chr) {
+ sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
+ offset+boff, *chr, buffer[boff]);
+ return offset+boff;
+ }
+ }
+ }
+
+ /*
+ * full words
+ */
+
+ num_full_words = (bsize-boff)/NBPW;
+
+ woff = offset+boff;
+
+ for (cnt=0; cnt<num_full_words; woff += NBPW, cnt++) {
+ word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
+
+ chr = (char *)&word;
+ for (tmp=0; tmp<NBPW; tmp++, boff++, chr++) {
+ if (buffer[boff] != *chr) {
+ sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
+ woff, *chr, buffer[boff]);
+ return woff;
+ }
+ }
+
+/****** only if a word elined
+ wptr = (long *)&buffer[boff];
+ if (*wptr != word) {
+ sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
+ woff, word, *wptr);
+ return woff;
+ }
+ boff += NBPW;
+******/
+ }
+
+ /*
+ * partial word at end of buffer
+ */
+
+ if (cnt=((bsize-boff) % NBPW)) {
+#if DEBUG
+printf("partial at end\n");
+#endif
+ word = ((LOWER16BITS(pid) << 48) | (LOWER32BITS(woff) << 16) | LOWER16BITS(pid));
+
+ chr = (char *)&word;
+
+
+ for (tmp=0; tmp<cnt && boff<bsize; boff++, tmp++, chr++) {
+ if (buffer[boff] != *chr) {
+ sprintf(Errmsg, "Data mismatch at offset %d, exp:%#o, act:%#o",
+ offset+boff, *chr, buffer[boff]);
+ return offset+boff;
+ }
+ }
+ }
+
+ sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
+ return -1; /* buffer is ok */
+
+#else
+
+ if (errmsg != NULL) {
+ *errmsg = Errmsg;
+ }
+ sprintf(Errmsg, "Not supported on this OS.");
+ return 0;
+
+#endif
+
+
+} /* end of datapidchk */
+
+#if UNIT_TEST
+
+/***********************************************************************
+ * main for doing unit testing
+ ***********************************************************************/
+int
+main(ac, ag)
+int ac;
+char **ag;
+{
+
+int size=1234;
+char *buffer;
+int ret;
+char *errmsg;
+
+ if ((buffer=(char *)malloc(size)) == NULL) {
+ perror("malloc");
+ exit(2);
+ }
+
+
+ datapidgen(-1, buffer, size, 3);
+
+/***
+fwrite(buffer, size, 1, stdout);
+fwrite("\n", 1, 1, stdout);
+****/
+
+ printf("datapidgen(-1, buffer, size, 3)\n");
+
+ ret=datapidchk(-1, buffer, size, 3, &errmsg);
+ printf("datapidchk(-1, buffer, %d, 3, &errmsg) returned %d %s\n",
+ size, ret, errmsg);
+ ret=datapidchk(-1, &buffer[1], size-1, 4, &errmsg);
+ printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+ buffer[25]= 0x0;
+ buffer[26]= 0x0;
+ buffer[27]= 0x0;
+ buffer[28]= 0x0;
+ printf("changing char 25-28\n");
+
+ ret=datapidchk(-1, &buffer[1], size-1, 4, &errmsg);
+ printf("datapidchk(-1, &buffer[1], %d, 4, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+printf("------------------------------------------\n");
+
+ datapidgen(getpid(), buffer, size, 5);
+
+/*******
+fwrite(buffer, size, 1, stdout);
+fwrite("\n", 1, 1, stdout);
+******/
+
+ printf("\ndatapidgen(getpid(), buffer, size, 5)\n");
+
+ ret=datapidchk(getpid(), buffer, size, 5, &errmsg);
+ printf("datapidchk(getpid(), buffer, %d, 5, &errmsg) returned %d %s\n",
+ size, ret, errmsg);
+
+ ret=datapidchk(getpid(), &buffer[1], size-1, 6, &errmsg);
+ printf("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+ buffer[25]= 0x0;
+ printf("changing char 25\n");
+
+ ret=datapidchk(getpid(), &buffer[1], size-1, 6, &errmsg);
+ printf("datapidchk(getpid(), &buffer[1], %d, 6, &errmsg) returned %d %s\n",
+ size-1, ret, errmsg);
+
+ exit(0);
+}
+
+#endif
diff --git a/ltp_framework/lib/file_lock.c b/ltp_framework/lib/file_lock.c
new file mode 100644
index 0000000..300b9d7
--- /dev/null
+++ b/ltp_framework/lib/file_lock.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/sysmacros.h>
+#include <string.h> /* memset, strerror */
+#include "file_lock.h"
+
+
+#ifndef EFSEXCLWR
+#define EFSEXCLWR 503
+#endif
+
+/*
+ * String containing the last system call.
+ *
+ */
+char Fl_syscall_str[128];
+
+static char errmsg[256];
+
+/***********************************************************************
+ *
+ * Test interface to the fcntl system call.
+ * It will loop if the LOCK_NB flags is NOT set.
+ ***********************************************************************/
+int
+file_lock(fd, flags, errormsg)
+int fd;
+int flags;
+char **errormsg;
+{
+ register int cmd, ret;
+ struct flock flocks;
+
+ memset(&flocks, 0, sizeof(struct flock));
+
+ if (flags&LOCK_NB)
+ cmd = F_SETLK;
+ else
+ cmd = F_SETLKW;
+
+ flocks.l_whence = 0;
+ flocks.l_start = 0;
+ flocks.l_len = 0;
+
+ if (flags&LOCK_UN)
+ flocks.l_type = F_UNLCK;
+ else if (flags&LOCK_EX)
+ flocks.l_type = F_WRLCK;
+ else if (flags&LOCK_SH)
+ flocks.l_type = F_RDLCK;
+ else {
+ errno = EINVAL;
+ if (errormsg != NULL) {
+ sprintf(errmsg,
+ "Programmer error, called file_lock with in valid flags\n");
+ *errormsg = errmsg;
+ }
+ return -1;
+ }
+
+ sprintf(Fl_syscall_str,
+ "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
+ fd, cmd, flocks.l_type, flocks.l_whence,
+ (long long)flocks.l_start, (long long)flocks.l_len);
+
+ while (1) {
+ ret = fcntl(fd, cmd, &flocks);
+
+ if (ret < 0) {
+ if (cmd == F_SETLK)
+ switch (errno) {
+ /* these errors are okay */
+ case EACCES: /* Permission denied */
+ case EINTR: /* interrupted system call */
+#ifdef EFILESH
+ case EFILESH: /* file shared */
+#endif
+ case EFSEXCLWR: /* File is write protected */
+ continue; /* retry getting lock */
+ }
+ if (errormsg != NULL) {
+ sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
+ fd, cmd, errno, strerror(errno));
+ *errormsg = errmsg;
+ }
+ return -1;
+ }
+ break;
+ }
+
+ return ret;
+
+} /* end of file_lock */
+
+/***********************************************************************
+ *
+ * Test interface to the fcntl system call.
+ * It will loop if the LOCK_NB flags is NOT set.
+ ***********************************************************************/
+int
+record_lock(fd, flags, start, len, errormsg)
+int fd;
+int flags;
+int start;
+int len;
+char **errormsg;
+{
+ register int cmd, ret;
+ struct flock flocks;
+
+ memset(&flocks, 0, sizeof(struct flock));
+
+ if (flags&LOCK_NB)
+ cmd = F_SETLK;
+ else
+ cmd = F_SETLKW;
+
+ flocks.l_whence = 0;
+ flocks.l_start = start;
+ flocks.l_len = len;
+
+ if (flags&LOCK_UN)
+ flocks.l_type = F_UNLCK;
+ else if (flags&LOCK_EX)
+ flocks.l_type = F_WRLCK;
+ else if (flags&LOCK_SH)
+ flocks.l_type = F_RDLCK;
+ else {
+ errno = EINVAL;
+ if (errormsg != NULL) {
+ sprintf(errmsg,
+ "Programmer error, called record_lock with in valid flags\n");
+ *errormsg = errmsg;
+ }
+ return -1;
+ }
+
+ sprintf(Fl_syscall_str,
+ "fcntl(%d, %d, &flocks): type:%d whence:%d, start:%lld len:%lld\n",
+ fd, cmd, flocks.l_type, flocks.l_whence,
+ (long long)flocks.l_start, (long long)flocks.l_len);
+
+ while (1) {
+ ret = fcntl(fd, cmd, &flocks);
+
+ if (ret < 0) {
+ if (cmd == F_SETLK)
+ switch (errno) {
+ /* these errors are okay */
+ case EACCES: /* Permission denied */
+ case EINTR: /* interrupted system call */
+#ifdef EFILESH
+ case EFILESH: /* file shared */
+#endif
+ case EFSEXCLWR: /* File is write protected */
+ continue; /* retry getting lock */
+ }
+ if (errormsg != NULL) {
+ sprintf(errmsg, "fcntl(%d, %d, &flocks): errno:%d %s\n",
+ fd, cmd, errno, strerror(errno));
+ *errormsg = errmsg;
+ }
+ return -1;
+ }
+ break;
+ }
+
+ return ret;
+
+} /* end of record_lock */
+
diff --git a/ltp_framework/lib/forker.c b/ltp_framework/lib/forker.c
new file mode 100644
index 0000000..ad8b4a7
--- /dev/null
+++ b/ltp_framework/lib/forker.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+/**************************************************************
+ *
+ * OS Testing - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME : forker
+ * background
+ *
+ * FUNCTION TITLE : fork desired number of copies of the current process
+ * fork a process and return control to caller
+ *
+ * SYNOPSIS:
+ * int forker(ncopies, mode, prefix)
+ * int ncopies;
+ * int mode;
+ * char *prefix;
+ *
+ * int background(prefix);
+ * char *prefix;
+ *
+ * AUTHOR : Richard Logan
+ *
+ * CO-PILOT(s) : Dean Roehrich
+ *
+ * INITIAL RELEASE : UNICOS 8.0
+ *
+ * DESIGN DESCRIPTION
+ * The background function will do a fork of the current process.
+ * The parent process will then exit, thus orphaning the
+ * child process. Doing this will not nice the child process
+ * like executing a cmd in the background using "&" from the shell.
+ * If the fork fails and prefix is not NULL, a error message is printed
+ * to stderr and the process will exit with a value of errno.
+ *
+ * The forker function will fork <ncopies> minus one copies
+ * of the current process. There are two modes in how the forks
+ * will be done. Mode 0 (default) will have all new processes
+ * be childern of the parent process. Using Mode 1,
+ * the parent process will have one child and that child will
+ * fork the next process, if necessary, and on and on.
+ * The forker function will return the number of successful
+ * forks. This value will be different for the parent and each child.
+ * Using mode 0, the parent will get the total number of successful
+ * forks. Using mode 1, the newest child will get the total number
+ * of forks. The parent will get a return value of 1.
+ *
+ * The forker function also updates the global variables
+ * Forker_pids[] and Forker_npids. The Forker_pids array will
+ * be updated to contain the pid of each new process. The
+ * Forker_npids variable contains the number of entries
+ * in Forker_pids. Note, not all processes will have
+ * access to all pids via Forker_pids. If using mode 0, only the
+ * parent process and the last process will have all information.
+ * If using mode 1, only the last child process will have all information.
+ *
+ * If the prefix parameter is not NULL and the fork system call fails,
+ * a error message will be printed to stderr. The error message
+ * the be preceeded with prefix string. If prefix is NULL,
+ * no error message is printed.
+ *
+ * SPECIAL REQUIREMENTS
+ * None.
+ *
+ * UPDATE HISTORY
+ * This should contain the description, author, and date of any
+ * "interesting" modifications (i.e. info should helpful in
+ * maintaining/enhancing this module).
+ * username description
+ * ----------------------------------------------------------------
+ * rrl This functions will first written during
+ * the SFS testing days, 1993.
+ *
+ * BUGS/LIMITATIONS
+ * The child pids are stored in the fixed array, Forker_pids.
+ * The array only has space for 4098 pids. Only the first
+ * 4098 pids will be stored in the array.
+ *
+ **************************************************************/
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h> /* fork, getpid, sleep */
+#include <string.h>
+#include <stdlib.h> /* exit */
+#include "forker.h"
+
+int Forker_pids[FORKER_MAX_PIDS]; /* holds pids of forked processes */
+int Forker_npids=0; /* number of entries in Forker_pids */
+
+/***********************************************************************
+ *
+ * This function will fork and the parent will exit zero and
+ * the child will return. This will orphan the returning process
+ * putting it in the background.
+ *
+ * Return Value
+ * 0 : if fork did not fail
+ * !0 : if fork failed, the return value will be the errno.
+ ***********************************************************************/
+int
+background(prefix)
+char *prefix;
+{
+ switch (fork()) {
+ case -1:
+ if (prefix != NULL)
+ fprintf(stderr, "%s: In %s background(), fork() failed, errno:%d %s\n",
+ prefix, __FILE__, errno, strerror(errno));
+ exit(errno);
+
+ case 0: /* child process */
+ break;
+
+ default:
+ exit(0);
+ }
+
+ return 0;
+
+} /* end of background */
+
+/***********************************************************************
+ * Forker will fork ncopies-1 copies of self.
+ *
+ ***********************************************************************/
+int
+forker(ncopies, mode, prefix)
+int ncopies;
+int mode; /* 0 - all childern of parent, 1 - only 1 direct child */
+char *prefix; /* if ! NULL, an message will be printed to stderr */
+ /* if fork fails. The prefix (program name) will */
+ /* preceed the message */
+{
+ int cnt;
+ int pid;
+ static int ind = 0;
+
+ Forker_pids[ind]=0;
+
+ for (cnt=1; cnt < ncopies; cnt++) {
+
+ switch ( mode ) {
+ case 1 : /* only 1 direct child */
+ if ((pid = fork()) == -1) {
+ if (prefix != NULL)
+ fprintf(stderr, "%s: %s,forker(): fork() failed, errno:%d %s\n",
+ prefix, __FILE__, errno, strerror(errno));
+ return 0;
+ }
+ Forker_npids++;
+
+ switch (pid ) {
+ case 0: /* child - continues the forking */
+
+ if (Forker_npids < FORKER_MAX_PIDS)
+ Forker_pids[Forker_npids-1]=getpid();
+ break;
+
+ default: /* parent - stop the forking */
+ if (Forker_npids < FORKER_MAX_PIDS)
+ Forker_pids[Forker_npids-1]=pid;
+ return cnt-1;
+ }
+
+ break;
+
+ default : /* all new processes are childern of parent */
+ if ((pid = fork()) == -1) {
+ if (prefix != NULL)
+ fprintf(stderr, "%s: %s,forker(): fork() failed, errno:%d %s\n",
+ prefix, __FILE__, errno, strerror(errno));
+ return cnt-1;
+ }
+ Forker_npids++;
+
+ switch (pid ) {
+ case 0: /* child - stops the forking */
+ if (Forker_npids < FORKER_MAX_PIDS)
+ Forker_pids[Forker_npids-1]=getpid();
+ return cnt;
+
+ default: /* parent - continues the forking */
+ if (Forker_npids < FORKER_MAX_PIDS)
+ Forker_pids[Forker_npids-1]=pid;
+ break;
+ }
+ break;
+ }
+ }
+
+ if (Forker_npids < FORKER_MAX_PIDS)
+ Forker_pids[Forker_npids]=0;
+ return cnt-1;
+
+} /* end of forker */
+
+
+#if UNIT_TEST
+
+/*
+ * The following is a unit test main for the background and forker
+ * functions.
+ */
+
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int ncopies=1;
+ int mode=0;
+ int ret;
+ int ind;
+
+ if (argc == 1) {
+ printf("Usage: %s ncopies [mode]\n", argv[0]);
+ exit(1);
+ }
+
+ if (sscanf(argv[1], "%i", &ncopies) != 1) {
+ printf("%s: ncopies argument must be integer\n", argv[0]);
+ exit(1);
+ }
+
+ if (argc == 3)
+ if (sscanf(argv[2], "%i", &mode) != 1) {
+ printf("%s: mode argument must be integer\n", argv[0]);
+ exit(1);
+ }
+
+ printf("Starting Pid = %d\n", getpid());
+ ret=background(argv[0]);
+ printf("After background() ret:%d, pid = %d\n", ret, getpid());
+
+ ret=forker(ncopies, mode, argv[0]);
+
+ printf("forker(%d, %d, %s) ret:%d, pid = %d, sleeping 30 seconds.\n",
+ ncopies, mode, argv[0], ret, getpid());
+
+ printf("%d My version of Forker_pids[], Forker_npids = %d\n",
+ getpid(), Forker_npids);
+
+ for (ind=0; ind<Forker_npids; ind++) {
+ printf("%d ind:%-2d pid:%d\n", getpid(), ind, Forker_pids[ind]);
+ }
+
+ sleep(30);
+ exit(0);
+}
+
+#endif /* UNIT_TEST */ \ No newline at end of file
diff --git a/ltp_framework/lib/get_high_address.c b/ltp_framework/lib/get_high_address.c
new file mode 100644
index 0000000..72cacef
--- /dev/null
+++ b/ltp_framework/lib/get_high_address.c
@@ -0,0 +1,40 @@
+/* $Header: /cvsroot/ltp/ltp/lib/get_high_address.c,v 1.6 2009/07/20 10:59:32 vapier Exp $ */
+
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+#include <unistd.h>
+
+char *get_high_address(void)
+{
+ return (char *)sbrk(0) + (4 * getpagesize());
+} \ No newline at end of file
diff --git a/ltp_framework/lib/get_path.c b/ltp_framework/lib/get_path.c
new file mode 100644
index 0000000..6501a06
--- /dev/null
+++ b/ltp_framework/lib/get_path.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 Cyril Hrubis chrubis@suse.cz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ */
+
+ /*
+ * Looks for binary prog_name in $PATH.
+ *
+ * If such file exists and if you are able at least to read it, zero is
+ * returned and absolute path to the file is filled into buf. In case buf is
+ * too short to hold the absolute path + prog_name for the file we are looking
+ * for -1 is returned as well as when there is no such file in all paths in
+ * $PATH.
+ */
+
+#include "test.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define MIN(a, b) ((a)<(b)?(a):(b))
+
+static int file_exist(const char *path)
+{
+ struct stat st;
+
+ if (!access(path, R_OK) && !stat(path, &st) && S_ISREG(st.st_mode))
+ return 1;
+
+ return 0;
+}
+
+int tst_get_path(const char *prog_name, char *buf, size_t buf_len)
+{
+ const char *path = (const char*) getenv("PATH");
+ const char *start = path;
+ const char *end;
+ size_t size, ret;
+
+
+ if (path == NULL)
+ return -1;
+
+ do {
+ end = strchr(start, ':');
+
+ if (end != NULL)
+ snprintf(buf, MIN(buf_len, (size_t)(end - start + 1)), "%s", start);
+ else
+ snprintf(buf, buf_len, "%s", start);
+
+ size = strlen(buf);
+
+ /*
+ * "::" inside $PATH, $PATH ending with ':' or $PATH starting
+ * with ':' should be expanded into current working directory.
+ */
+ if (size == 0) {
+ snprintf(buf, buf_len, ".");
+ size = strlen(buf);
+ }
+
+ /*
+ * If there is no '/' ad the end of path from $PATH add it.
+ */
+ if (buf[size - 1] != '/')
+ ret = snprintf(buf + size, buf_len - size, "/%s", prog_name);
+ else
+ ret = snprintf(buf + size, buf_len - size, "%s", prog_name);
+
+ if (buf_len - size > ret && file_exist(buf))
+ return 0;
+
+ start = end + 1;
+
+ } while (end != NULL);
+
+ return -1;
+} \ No newline at end of file
diff --git a/ltp_framework/lib/libltp.a b/ltp_framework/lib/libltp.a
new file mode 100644
index 0000000..6f969a4
--- /dev/null
+++ b/ltp_framework/lib/libltp.a
Binary files differ
diff --git a/ltp_framework/lib/libtestsuite.c b/ltp_framework/lib/libtestsuite.c
new file mode 100644
index 0000000..1703ff7
--- /dev/null
+++ b/ltp_framework/lib/libtestsuite.c
@@ -0,0 +1,164 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * NAME
+ * libtestsuite.c
+ *
+ * DESCRIPTION
+ * file containing generic routines which are used by some of the LTP
+ * testsuite tests. Currently, the following routines are present in
+ * this library:
+ *
+ * my_getpwnam(), do_file_setup()
+ *
+ * HISTORY
+ * 11/03/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
+ * - Add the following functions to synchronise father and sons processes
+ * sync_pipe_create(), sync_pipe_wait(), sync_pipe_notify()
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <errno.h>
+
+#include "libtestsuite.h"
+#include "test.h"
+#include "usctest.h"
+
+struct passwd *
+my_getpwnam(char *name)
+{
+ struct passwd *saved_pwent;
+ struct passwd *pwent;
+
+ if ((pwent = getpwnam(name)) == NULL) {
+ perror("getpwnam");
+ tst_brkm(TBROK, NULL, "getpwnam() failed");
+ }
+ saved_pwent = (struct passwd *)malloc(sizeof(struct passwd));
+
+ *saved_pwent = *pwent;
+
+ return(saved_pwent);
+}
+
+void
+do_file_setup(char *fname)
+{
+ int fd;
+
+ if ((fd = open(fname,O_RDWR|O_CREAT,0700)) == -1) {
+ tst_resm(TBROK, "open(%s, O_RDWR|O_CREAT,0700) Failed, "
+ "errno=%d : %s", fname, errno, strerror(errno));
+ }
+
+ if (close(fd) == -1) {
+ tst_resm(TWARN, "close(%s) Failed on file create, errno=%d : "
+ "%s", fname, errno, strerror(errno));
+ }
+}
+
+static char pipe_name[256];
+
+void generate_pipe_name(const char *name)
+{
+ char *p;
+
+ p = strrchr(name, '/');
+ if (p == NULL)
+ p = (char *) name;
+ else
+ p++;
+ snprintf(pipe_name, 255, "%s/ltp_fifo_%s", P_tmpdir, p);
+}
+
+int sync_pipe_create(int fd[], const char *name)
+{
+ int ret;
+
+ if (name != NULL) {
+ generate_pipe_name(name);
+
+ ret = open(pipe_name, O_RDWR);
+ if (ret != -1) {
+ fd[0] = ret;
+ fd[1] = open(pipe_name, O_RDWR);
+ } else {
+ ret = mkfifo(pipe_name, S_IRWXU);
+ if (!ret) {
+ fd[0] = open(pipe_name, O_RDWR);
+ fd[1] = open(pipe_name, O_RDWR);
+ }
+ }
+ return ret;
+ } else
+ return pipe(fd);
+}
+
+int sync_pipe_close(int fd[], const char *name)
+{
+ int r = 0;
+
+ if (fd[0] != -1)
+ r = close (fd[0]);
+ if (fd[1] != -1)
+ r |= close (fd[1]);
+
+ if (name != NULL) {
+ generate_pipe_name(name);
+ unlink(pipe_name);
+ }
+ return r;
+}
+
+int sync_pipe_wait(int fd[])
+{
+ char buf;
+ int r;
+
+ if (fd[1] != -1) {
+ close (fd[1]);
+ fd[1] = -1;
+ }
+
+ r = read (fd[0], &buf, 1);
+
+ if ((r != 1) || (buf != 'A'))
+ return -1;
+ return 0;
+}
+
+int sync_pipe_notify(int fd[])
+{
+ char buf = 'A';
+ int r;
+
+ if (fd[0] != -1) {
+ close (fd[0]);
+ fd[0] = -1;
+ }
+
+ r = write (fd[1], &buf, 1);
+
+ if (r != 1)
+ return -1;
+ return 0;
+} \ No newline at end of file
diff --git a/ltp_framework/lib/ltp.pc b/ltp_framework/lib/ltp.pc
new file mode 100644
index 0000000..5c4c042
--- /dev/null
+++ b/ltp_framework/lib/ltp.pc
@@ -0,0 +1,10 @@
+prefix=/opt/ltp
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${exec_prefix}/lib
+
+Name: LTP
+Description: Linux Test Project
+Version: LTP_VERSION
+Libs: -L${libdir} -lltp
+Cflags: -I${includedir}
diff --git a/ltp_framework/lib/ltp.pc.in b/ltp_framework/lib/ltp.pc.in
new file mode 100644
index 0000000..9620129
--- /dev/null
+++ b/ltp_framework/lib/ltp.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+includedir=@includedir@
+libdir=@libdir@
+
+Name: LTP
+Description: Linux Test Project
+Version: @VERSION@
+Libs: -L${libdir} -lltp
+Cflags: -I${includedir}
diff --git a/ltp_framework/lib/mount_utils.c b/ltp_framework/lib/mount_utils.c
new file mode 100644
index 0000000..5a9fd8c
--- /dev/null
+++ b/ltp_framework/lib/mount_utils.c
@@ -0,0 +1,213 @@
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <mntent.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * Return the block device for a given path. You must free the string after you
+ * call this function.
+ *
+ * Returns NULL if the device isn't found, memory couldn't be allocated, or if
+ * the `block device' isn't a real block device (e.g. nfs mounts, etc).
+ */
+char *
+get_block_device(const char *path)
+{
+
+ char *mnt_dir = NULL, *mnt_fsname = NULL;
+ char *resolved_path = NULL;
+ FILE *mtab_f;
+ int done = 0;
+ struct mntent *entry;
+ struct stat junk;
+
+ if (path == NULL) {
+ errno = EINVAL;
+ } else if ((resolved_path = realpath(path, NULL)) != NULL &&
+ (mtab_f = setmntent("/etc/mtab", "r")) != NULL)
+ {
+
+ do {
+
+ entry = getmntent(mtab_f);
+
+ if (entry != NULL) {
+
+ if (!strncmp(entry->mnt_dir, resolved_path, strlen(entry->mnt_dir))) {
+
+ char copy_string = 0;
+
+ if (mnt_dir == NULL) {
+
+ mnt_dir = malloc(strlen(entry->mnt_dir)+1);
+ mnt_fsname = malloc(strlen(entry->mnt_fsname)+1);
+
+ copy_string = mnt_dir != NULL && mnt_fsname != NULL;
+
+ } else {
+
+ if (!strncmp(entry->mnt_dir, mnt_dir, strlen(entry->mnt_dir))) {
+
+ mnt_dir = realloc(mnt_dir, strlen(entry->mnt_dir));
+ mnt_fsname = realloc(mnt_fsname, strlen(entry->mnt_fsname));
+ copy_string = 1;
+
+ }
+
+ }
+
+ if (copy_string != 0) {
+ strcpy(mnt_dir, entry->mnt_dir);
+ strcpy(mnt_fsname, entry->mnt_fsname);
+#if DEBUG
+ printf("%s is a subset of %s\n", path, entry->mnt_dir);
+ } else {
+ printf("%s is not a subset of %s\n", path, entry->mnt_dir);
+#endif
+ }
+
+#if DEBUG
+ } else {
+ printf("%s is not a subset of %s\n", path, entry->mnt_dir);
+#endif
+ }
+
+ }
+
+ } while (done == 0 && entry != NULL);
+
+ endmntent(mtab_f);
+
+ }
+
+ if (mnt_dir != NULL) {
+ free(mnt_dir);
+ }
+ if (resolved_path != NULL) {
+ free(resolved_path);
+ }
+
+ if (mnt_fsname != NULL && stat(mnt_fsname, &junk) < 0 &&
+ errno == ENOENT) {
+ free(mnt_fsname);
+ mnt_fsname = NULL;
+ errno = ENODEV;
+ }
+
+ return mnt_fsname;
+
+}
+
+/*
+ * Return the mountpoint for a given path. You must free the string after you
+ * call this function.
+ *
+ * Returns NULL if memory couldn't be allocated.
+ */
+char *
+get_mountpoint(const char *path)
+{
+
+ char *mnt_dir = NULL;
+ char *resolved_path = NULL;
+ FILE *mtab_f;
+ int done = 0;
+ struct mntent *entry;
+
+ if (path == NULL) {
+ errno = EINVAL;
+ } else if ((resolved_path = realpath(path, NULL)) != NULL &&
+ (mtab_f = setmntent("/etc/mtab", "r")) != NULL)
+ {
+
+ do {
+
+ entry = getmntent(mtab_f);
+
+ if (entry != NULL) {
+
+ if (!strncmp(entry->mnt_dir, resolved_path, strlen(entry->mnt_dir))) {
+
+ char copy_string = 0;
+
+ if (mnt_dir == NULL) {
+
+ mnt_dir = malloc(strlen(entry->mnt_dir)+1);
+ copy_string = mnt_dir != NULL;
+
+ } else {
+
+ if (!strncmp(entry->mnt_dir, mnt_dir, strlen(entry->mnt_dir))) {
+
+ mnt_dir = realloc(mnt_dir, strlen(entry->mnt_dir));
+ copy_string = 1;
+
+ }
+
+ }
+
+ if (copy_string != 0) {
+ strcpy(mnt_dir, entry->mnt_dir);
+#if DEBUG
+ printf("%s is a subset of %s\n", path, entry->mnt_dir);
+ } else {
+ printf("%s is not a subset of %s\n", path, entry->mnt_dir);
+#endif
+ }
+
+#if DEBUG
+ } else {
+ printf("%s is not a subset of %s\n", path, entry->mnt_dir);
+#endif
+ }
+
+ }
+
+ } while (done == 0 && entry != NULL);
+
+ endmntent(mtab_f);
+
+ }
+
+ if (resolved_path != NULL) {
+ free(resolved_path);
+ }
+
+ return mnt_dir;
+
+}
+#if UNIT_TEST
+int
+main(void)
+{
+
+ char *mnt_fsname;
+ char *paths[] = {
+ "/home",
+ "/mnt",
+ "/tmp/foo", /* mkdir /tmp/foo; mount -t tmpfs none /tmp/foo/ */
+ "/proc",
+ "/optimus/store"
+ };
+ int i;
+
+ for (i = 0; i < sizeof(paths) / sizeof(*paths); i++) {
+ mnt_fsname = get_block_device(paths[i]);
+ printf("%s - %s\n", paths[i], mnt_fsname);
+ if (mnt_fsname != NULL) {
+ free(mnt_fsname);
+ mnt_fsname = NULL;
+ }
+ }
+
+ return 0;
+
+}
+#endif \ No newline at end of file
diff --git a/ltp_framework/lib/open_flags.c b/ltp_framework/lib/open_flags.c
new file mode 100644
index 0000000..5623382
--- /dev/null
+++ b/ltp_framework/lib/open_flags.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+/**************************************************************
+ *
+ * OS Testing - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME : parse_open_flags
+ * openflags2symbols
+ *
+ * FUNCTION TITLE : converts open flag symbols into bitmask
+ * converts open flag bitmask into symbols
+ *
+ * SYNOPSIS:
+ * int parse_open_flags(symbols, badname)
+ * char *symbols;
+ * char **badname;
+ *
+ * char *openflags2symbols(openflags, sep, mode)
+ * int openflags;
+ * char *sep;
+ * int mode;
+ *
+ * AUTHOR : Richard Logan
+ *
+ * CO-PILOT(s) : Dean Roehrich
+ *
+ * INITIAL RELEASE : UNICOS 8.0
+ *
+ * DESIGN DESCRIPTION
+ * The parse_open_flags function can be used to convert
+ * a list of comma separated open(2) flag symbols (i.e. O_TRUNC)
+ * into the bitmask that can be used by open(2).
+ * If a symbol is unknown and <badname> is not NULL, <badname>
+ * will updated to point that symbol in <string>.
+ * Parse_open_flags will return -1 on this error.
+ * Otherwise parse_open_flags will return the open flag bitmask.
+ * If parse_open_flags returns, <string> will left unchanged.
+ *
+ * The openflags2symbols function attempts to convert open flag
+ * bits into human readable symbols (i.e. O_TRUNC). If there
+ * are more than one symbol, the <sep> string will be placed as
+ * a separator between symbols. Commonly used separators would
+ * be a comma "," or pipe "|". If <mode> is one and not all
+ * <openflags> bits can be converted to symbols, the "UNKNOWN"
+ * symbol will be added to return string.
+ * Openflags2symbols will return the indentified symbols.
+ * If no symbols are recognized the return value will be a empty
+ * string or the "UNKNOWN" symbol.
+ *
+ * SPECIAL REQUIREMENTS
+ * None.
+ *
+ * UPDATE HISTORY
+ * This should contain the description, author, and date of any
+ * "interesting" modifications (i.e. info should helpful in
+ * maintaining/enhancing this module).
+ * username description
+ * ----------------------------------------------------------------
+ * rrl This code was first created during the beginning
+ * of the SFS testing days. I think that was in 1993.
+ * This code was updated in 05/96.
+ * (05/96) openflags2symbols was written.
+ *
+ * BUGS/LIMITATIONS
+ * Currently (05/96) all known symbols are coded into openflags2symbols.
+ * If new open flags are added this code will have to updated
+ * to know about them or they will not be recognized.
+ *
+ **************************************************************/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <string.h> /* strcat */
+#include "open_flags.h"
+
+#define UNKNOWN_SYMBOL "UNKNOWN"
+
+static char Open_symbols[512]; /* space for openflags2symbols return value */
+
+struct open_flag_t {
+ char *symbol;
+ int flag;
+};
+
+static struct open_flag_t Open_flags[] = {
+ { "O_RDONLY", O_RDONLY },
+ { "O_WRONLY", O_WRONLY },
+ { "O_RDWR", O_RDWR },
+ { "O_SYNC", O_SYNC },
+ { "O_CREAT", O_CREAT },
+ { "O_TRUNC", O_TRUNC },
+ { "O_EXCL", O_EXCL },
+ { "O_APPEND", O_APPEND },
+ { "O_NONBLOCK", O_NONBLOCK },
+#if O_NOCTTY
+ { "O_NOCTTY", O_NOCTTY },
+#endif
+#if O_DSYNC
+ { "O_DSYNC", O_DSYNC },
+#endif
+#if O_RSYNC
+ { "O_RSYNC", O_RSYNC },
+#endif
+#if O_ASYNC
+ { "O_ASYNC", O_ASYNC },
+#endif
+#if O_PTYIGN
+ { "O_PTYIGN", O_PTYIGN },
+#endif
+#if O_NDELAY
+ { "O_NDELAY", O_NDELAY },
+#endif
+#if O_RAW
+ { "O_RAW", O_RAW },
+#endif
+#ifdef O_SSD
+ { "O_SSD", O_SSD },
+#endif
+#if O_BIG
+ { "O_BIG", O_BIG },
+#endif
+#if O_PLACE
+ { "O_PLACE", O_PLACE },
+#endif
+#if O_RESTART
+ { "O_RESTART", O_RESTART },
+#endif
+#if O_SFSXOP
+ { "O_SFSXOP", O_SFSXOP },
+#endif
+#if O_SFS_DEFER_TM
+ { "O_SFS_DEFER_TM", O_SFS_DEFER_TM },
+#endif
+#if O_WELLFORMED
+ { "O_WELLFORMED", O_WELLFORMED },
+#endif
+#if O_LDRAW
+ { "O_LDRAW", O_LDRAW },
+#endif
+#if O_T3D
+ { "O_T3D", O_T3D },
+#endif /* O_T3D */
+#if O_PARALLEL
+ { "O_PARALLEL", O_PARALLEL },
+ { "O_FSA", O_PARALLEL|O_WELLFORMED|O_RAW }, /* short cut */
+#endif /* O_PARALLEL */
+#ifdef O_LARGEFILE
+ { "O_LARGEFILE", O_LARGEFILE },
+#endif
+#ifdef O_DIRECT
+ { "O_DIRECT", O_DIRECT },
+#endif
+#ifdef O_PRIV
+ { "O_PRIV", O_PRIV },
+#endif
+
+};
+
+int
+parse_open_flags(char *string, char **badname)
+{
+ int bits = 0;
+ char *name;
+ char *cc;
+ char savecc;
+ int found;
+ unsigned int ind;
+
+ name=string;
+ cc=name;
+
+ while ( 1 ) {
+
+ for (; ((*cc != ',') && (*cc != '\0')); cc++);
+ savecc = *cc;
+ *cc = '\0';
+
+ found = 0;
+
+ for (ind=0; ind < sizeof(Open_flags)/sizeof(struct open_flag_t); ind++) {
+ if (strcmp(name, Open_flags[ind].symbol) == 0) {
+ bits |= Open_flags[ind].flag;
+ found=1;
+ break;
+ }
+ }
+
+ *cc = savecc; /* restore string */
+
+ if (found == 0) { /* invalid name */
+ if (badname != NULL)
+ *badname = name;
+ return -1;
+ }
+
+ if (savecc == '\0')
+ break;
+
+ name = ++cc;
+
+ } /* end while */
+
+ return bits;
+
+} /* end of parse_open_flags */
+
+
+char *
+openflags2symbols(int openflags, char *sep, int mode)
+{
+ int ind;
+ int size;
+ int bits = openflags;
+ int havesome=0;
+
+ Open_symbols[0]='\0';
+
+ size=sizeof(Open_flags)/sizeof(struct open_flag_t);
+
+ /*
+ * Deal with special case of O_RDONLY. If O_WRONLY nor O_RDWR
+ * bits are not set, assume O_RDONLY.
+ */
+
+ if ((bits & (O_WRONLY | O_RDWR)) == 0) {
+ strcat(Open_symbols, "O_RDONLY");
+ havesome=1;
+ }
+
+ /*
+ * Loop through all but O_RDONLY elments of Open_flags
+ */
+ for (ind=1; ind < size; ind++) {
+
+ if ((bits & Open_flags[ind].flag) == Open_flags[ind].flag) {
+ if (havesome)
+ strcat(Open_symbols, sep);
+
+ strcat(Open_symbols, Open_flags[ind].symbol);
+ havesome++;
+
+ /* remove flag bits from bits */
+ bits = bits & (~Open_flags[ind].flag);
+ }
+ }
+
+ /*
+ * If not all bits were identified and mode was equal to 1,
+ * added UNKNOWN_SYMBOL to return string
+ */
+ if (bits && mode == 1) { /* not all bits were identified */
+ if (havesome)
+ strcat(Open_symbols, sep);
+ strcat(Open_symbols, UNKNOWN_SYMBOL);
+ }
+
+ return Open_symbols;
+
+} /* end of openflags2symbols */
+
+
+#ifdef UNIT_TEST
+
+/*
+ * The following code provides a UNIT test main for
+ * parse_open_flags and openflags2symbols functions.
+ */
+
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int bits;
+ int ret;
+ char *err;
+
+ if (argc == 1) {
+ printf("Usage: %s openflagsbits\n\t%s symbols\n", argv[0], argv[0]);
+ exit(1);
+ }
+
+ if (sscanf(argv[1], "%i", &bits) == 1) {
+ printf("openflags2symbols(%#o, \",\", 1) returned %s\n",
+ bits, openflags2symbols(bits, ",", 1));
+
+ } else {
+ ret=parse_open_flags(argv[1], &err);
+ if (ret == -1)
+ printf("parse_open_flags(%s, &err) returned -1, err = %s\n",
+ argv[0], err);
+ else
+ printf("parse_open_flags(%s, &err) returned %#o\n", argv[0], ret);
+ }
+
+ exit(0);
+}
+
+#endif /* end of UNIT_TEST */ \ No newline at end of file
diff --git a/ltp_framework/lib/parse_opts.c b/ltp_framework/lib/parse_opts.c
new file mode 100644
index 0000000..358106e
--- /dev/null
+++ b/ltp_framework/lib/parse_opts.c
@@ -0,0 +1,879 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+/* $Id: parse_opts.c,v 1.14 2009/08/28 09:59:52 vapier Exp $ */
+
+/**********************************************************
+ *
+ * OS Testing - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME : parse_opts
+ *
+ * FUNCTION TITLE : parse standard & user options for system call tests
+ *
+ * SYNOPSIS:
+ * #include "usctest.h"
+ *
+ * char *parse_opts(ac, av, user_optarr, uhf)
+ * int ac;
+ * char **av;
+ * option_t user_optarr[];
+ * void (*uhf)();
+ *
+ * AUTHOR : William Roske/Richard Logan
+ *
+ * INITIAL RELEASE : UNICOS 7.0
+ *
+ * DESCRIPTION
+ * The parse_opts library routine takes that argc and argv parameters
+ * recevied by main() and an array of structures defining user options.
+ * It parses the command line setting flag and argument locations
+ * associated with the options. It uses getopt to do the actual cmd line
+ * parsing. uhf() is a function to print user define help
+ *
+ * This module contains the functions usc_global_setup_hook and
+ * usc_test_looping, which are called by marcos defined in usctest.h.
+ *
+ * RETURN VALUE
+ * parse_opts returns a pointer to an error message if an error occurs.
+ * This pointer is (char *)NULL if parsing is successful.
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+#include "config.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+#if UNIT_TEST
+#include <time.h>
+#endif /* UNIT_TEST */
+
+#include "test.h"
+#define _USC_LIB_ 1 /* indicates we are the library to the usctest.h include */
+#include "usctest.h"
+
+#ifndef USC_COPIES
+#define USC_COPIES "USC_COPIES"
+#endif
+
+#ifndef UNIT_TEST
+#define UNIT_TEST 0
+#endif
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+/* The timing information block. */
+struct tblock tblock={0,((long) -1)>>1,0,0};
+
+#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
+extern pid_t spawned_program_pid;
+#endif
+
+/* Define flags and args for standard options */
+int STD_FUNCTIONAL_TEST=1, /* flag indicating to do functional testing code */
+ STD_TIMING_ON=0, /* flag indicating to print timing stats */
+ STD_PAUSE=0, /* flag indicating to pause before actual start, */
+ /* for contention mode */
+ STD_INFINITE=0, /* flag indciating to loop forever */
+ STD_LOOP_COUNT=1, /* number of iterations */
+ STD_COPIES=1, /* number of copies */
+ STD_ERRNO_LOG=0; /* flag indicating to do errno logging */
+
+float STD_LOOP_DURATION=0.0, /* duration value in fractional seconds */
+ STD_LOOP_DELAY=0.0; /* loop delay value in fractional seconds */
+
+
+char **STD_opt_arr = NULL; /* array of option strings */
+int STD_nopts=0, /* number of elements in STD_opt_arr */
+ STD_argind=1; /* argv index to next argv element */
+ /* (first argument) */
+ /* To getopt users, it is like optind */
+
+/*
+ * The following variables are to support system testing additions.
+ */
+static int STD_TP_barrier=0; /* flag to do barrier in TEST_PAUSE */
+ /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
+static int STD_LP_barrier=0; /* flag to do barrier in TEST_LOOPING */
+ /* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
+static int STD_TP_shmem_sz=0; /* shmalloc this many words per pe in TEST_PAUSE */
+static int STD_LD_shmem=0; /* flag to do shmem_puts and shmem_gets during delay */
+static int STD_LP_shmem=0; /* flag to do shmem_puts and gets during TEST_LOOPING */
+static int STD_LD_recfun=0; /* do recressive function calls in loop delay */
+static int STD_LP_recfun=0; /* do recressive function calls in TEST_LOOPING */
+static int STD_TP_sbrk=0; /* do sbrk in TEST_PAUSE */
+static int STD_LP_sbrk=0; /* do sbrk in TEST_LOOPING */
+static char *STD_start_break=0; /* original sbrk size */
+static int Debug=0;
+
+struct std_option_t {
+ char *optstr;
+ char *help;
+ char *flag;
+ char **arg;
+} std_options[] = {
+ { "c:", " -c n Run n copies concurrently\n", NULL, NULL},
+ { "e" , " -e Turn on errno logging\n", NULL, NULL},
+ { "f" , " -f Turn off functional testing\n", NULL, NULL},
+ { "h" , " -h Show this help screen\n", NULL, NULL},
+ { "i:", " -i n Execute test n times\n", NULL, NULL},
+ { "I:", " -I x Execute test for x seconds\n", NULL, NULL},
+ { "p" , " -p Pause for SIGUSR1 before starting\n", NULL, NULL},
+ { "P:", " -P x Pause for x seconds between iterations\n", NULL, NULL},
+ { "t" , " -t Turn on syscall timing\n", NULL, NULL},
+#ifdef UCLINUX
+ { "C:", " -C ARG Run the child process with arguments ARG (for internal use)\n",
+ NULL, NULL},
+#endif
+ {NULL, NULL, NULL, NULL}};
+
+void print_help(void (*user_help)());
+
+/*
+ * Structure for usc_recressive_func argument
+ */
+struct usc_bigstack_t {
+ char space[4096];
+};
+
+static struct usc_bigstack_t *STD_bigstack=NULL;
+
+/*
+ * Counter of errnos returned (-e option). Indexed by errno.
+ * Make the array USC_MAX_ERRNO long. That is the first Fortran
+ * Lib errno. No syscall should return an errno that high.
+ */
+int STD_ERRNO_LIST[USC_MAX_ERRNO];
+
+/* define the string length for Mesg and Mesg2 strings */
+#define STRLEN 2048
+
+static char Mesg2[STRLEN]; /* holds possible return string */
+static void usc_recressive_func();
+
+/*
+ * Define bits for options that might have env variable default
+ */
+#define OPT_iteration 01
+#define OPT_nofunccheck 02
+#define OPT_duration 04
+#define OPT_delay 010
+#define OPT_copies 020
+
+#ifdef UCLINUX
+/* Allocated and used in self_exec.c: */
+extern char *child_args; /* Arguments to child when -C is used */
+#endif
+
+/**********************************************************************
+ * parse_opts:
+ **********************************************************************/
+char *
+parse_opts(int ac, char **av, const option_t *user_optarr, void (*uhf)())
+{
+ int found; /* flag to indicate that an option specified was */
+ /* found in the user's list */
+ int k; /* scratch integer for returns and short time usage */
+ float ftmp; /* tmp float for parsing env variables */
+ char *ptr; /* used in getting env variables */
+ int options=0; /* no options specified */
+ int optstrlen, i;
+ char *optionstr;
+ int opt; /* return of getopt */
+
+ /*
+ * If not the first time this function is called, release the old STD_opt_arr
+ * vector.
+ */
+
+#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
+ spawned_program_pid = getpid();
+#endif
+
+ if (STD_opt_arr != NULL) {
+ free(STD_opt_arr);
+ STD_opt_arr = NULL;
+ }
+ /* Calculate how much space we need for the option string */
+ optstrlen = 0;
+ for (i = 0; std_options[i].optstr; ++i)
+ optstrlen += strlen(std_options[i].optstr);
+ if (user_optarr)
+ for (i = 0; user_optarr[i].option; ++i) {
+ if (strlen(user_optarr[i].option) > 2)
+ return "parse_opts: ERROR - Only short options are allowed";
+ optstrlen += strlen(user_optarr[i].option);
+ }
+ optstrlen += 1;
+
+ /* Create the option string for getopt */
+ optionstr = malloc(optstrlen);
+ if (!optionstr)
+ return "parse_opts: ERROR - Could not allocate memory for optionstr";
+
+ optionstr[0] = '\0';
+
+ for (i = 0; std_options[i].optstr; ++i)
+ strcat(optionstr, std_options[i].optstr);
+ if (user_optarr)
+ for (i = 0; user_optarr[i].option; ++i)
+ /* only add the option if it wasn't there already */
+ if (strchr(optionstr, user_optarr[i].option[0]) == NULL)
+ strcat(optionstr, user_optarr[i].option);
+
+#if DEBUG > 1
+ printf("STD_nopts = %d\n", STD_nopts);
+#endif
+
+ /*
+ * Loop through av parsing options.
+ */
+ while ((opt = getopt(ac, av, optionstr)) > 0) {
+
+ STD_argind = optind;
+#if DEBUG > 0
+ printf("parse_opts: getopt returned '%c'\n", opt);
+#endif
+
+ switch (opt) {
+ case '?': /* Unknown option */
+ return "Unknown option";
+ break;
+ case ':': /* Missing Arg */
+ return "Missing argument";
+ break;
+ case 'i': /* Iterations */
+ options |= OPT_iteration;
+ STD_LOOP_COUNT = atoi(optarg);
+ if (STD_LOOP_COUNT == 0) STD_INFINITE = 1;
+ break;
+ case 'P': /* Delay between iterations */
+ options |= OPT_delay;
+ STD_LOOP_DELAY = atof(optarg);
+ break;
+ case 'I': /* Time duration */
+ options |= OPT_duration;
+ STD_LOOP_DURATION = atof(optarg);
+ if (STD_LOOP_DURATION == 0.0) STD_INFINITE=1;
+ break;
+ case 'c': /* Copies */
+ options |= OPT_copies;
+ STD_COPIES = atoi(optarg);
+ break;
+ case 'f': /* Functional testing */
+ STD_FUNCTIONAL_TEST = 0;
+ break;
+ case 'p': /* Pause for SIGUSR1 */
+ STD_PAUSE = 1;
+ break;
+ case 't': /* syscall timing */
+ STD_TIMING_ON = 1;
+ break;
+ case 'e': /* errno loggin */
+ STD_ERRNO_LOG = 1;
+ break;
+ case 'h': /* Help */
+ print_help(uhf);
+ exit(0);
+ break;
+#ifdef UCLINUX
+ case 'C': /* Run child */
+ child_args = optarg;
+ break;
+#endif
+ default:
+
+ /* Check all the user specified options */
+ found=0;
+ for (i = 0; user_optarr[i].option; ++i) {
+
+ if (opt == user_optarr[i].option[0]) {
+ /* Yup, This is a user option, set the flag and look for argument */
+ if (user_optarr[i].flag) {
+ *user_optarr[i].flag=1;
+ }
+ found++;
+
+ /* save the argument at the user's location */
+ if (user_optarr[i].option[strlen(user_optarr[i].option)-1] == ':') {
+ *user_optarr[i].arg = optarg;
+ }
+ break; /* option found - break out of the for loop */
+ }
+ }
+ /* This condition "should never happen". SO CHECK FOR IT!!!! */
+ if (!found) {
+ sprintf(Mesg2,
+ "parse_opts: ERROR - option:\"%c\" NOT FOUND... INTERNAL "
+ "ERROR", opt);
+ return(Mesg2);
+ }
+ }
+
+ } /* end of while */
+ free(optionstr);
+
+ STD_argind = optind;
+
+ /*
+ * Turn on debug
+ */
+ if ((ptr = getenv("USC_DEBUG")) != NULL) {
+ Debug = 1;
+ printf("env USC_DEBUG is defined, turning on debug\n");
+ }
+ if ((ptr = getenv("USC_VERBOSE")) != NULL) {
+ Debug = 1;
+ printf("env USC_VERBOSE is defined, turning on debug\n");
+ }
+
+ /*
+ * If the USC_ITERATION_ENV environmental variable is set to
+ * a number, use that number as iteration count (same as -c option).
+ * The -c option with arg will be used even if this env var is set.
+ */
+ if (!(options & OPT_iteration) && (ptr = getenv(USC_ITERATION_ENV)) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1) {
+ if (k == 0) { /* if arg is 0, set infinite loop flag */
+ STD_INFINITE = 1;
+ if (Debug)
+ printf("Using env %s, set STD_INFINITE to 1\n",
+ USC_ITERATION_ENV);
+ } else { /* else, set the loop count to the arguement */
+ STD_LOOP_COUNT=k;
+ if (Debug)
+ printf("Using env %s, set STD_LOOP_COUNT to %d\n",
+ USC_ITERATION_ENV, k);
+ }
+ }
+ }
+
+ /*
+ * If the USC_NO_FUNC_CHECK environmental variable is set, we'll
+ * unset the STD_FUNCTIONAL_TEST variable.
+ */
+ if (!(options & OPT_nofunccheck) &&
+ (ptr = getenv(USC_NO_FUNC_CHECK)) != NULL) {
+ STD_FUNCTIONAL_TEST=0; /* Turn off functional testing */
+ if (Debug)
+ printf("Using env %s, set STD_FUNCTIONAL_TEST to 0\n",
+ USC_NO_FUNC_CHECK);
+ }
+
+ /*
+ * If the USC_LOOP_WALLTIME environmental variable is set,
+ * use that number as duration (same as -I option).
+ * The -I option with arg will be used even if this env var is set.
+ */
+
+ if (!(options & OPT_duration) &&
+ (ptr = getenv(USC_LOOP_WALLTIME)) != NULL) {
+ if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
+ STD_LOOP_DURATION = ftmp;
+ if (Debug)
+ printf("Using env %s, set STD_LOOP_DURATION to %f\n",
+ USC_LOOP_WALLTIME, ftmp);
+ if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
+ STD_INFINITE = 1;
+ if (Debug)
+ printf("Using env %s, set STD_INFINITE to 1\n", USC_LOOP_WALLTIME);
+ }
+ }
+ }
+ if (!(options & OPT_duration) && (ptr = getenv("USC_DURATION")) != NULL) {
+ if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
+ STD_LOOP_DURATION = ftmp;
+ if (Debug)
+ printf("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n", ftmp);
+ if (STD_LOOP_DURATION == 0.0) { /* if arg is 0, set infinite loop flag */
+ STD_INFINITE = 1;
+ if (Debug)
+ printf("Using env USC_DURATION, set STD_INFINITE to 1\n");
+ }
+ }
+ }
+ /*
+ * If the USC_LOOP_DELAY environmental variable is set,
+ * use that number as delay in factional seconds (same as -P option).
+ * The -P option with arg will be used even if this env var is set.
+ */
+ if (!(options & OPT_delay) && (ptr = getenv(USC_LOOP_DELAY)) != NULL) {
+ if (sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0) {
+ STD_LOOP_DELAY = ftmp;
+ if (Debug)
+ printf("Using env %s, set STD_LOOP_DELAY = %f\n",
+ USC_LOOP_DELAY, ftmp);
+ }
+ }
+
+ /*
+ * If the USC_COPIES environmental variable is set,
+ * use that number as copies (same as -c option).
+ * The -c option with arg will be used even if this env var is set.
+ */
+ if (!(options & OPT_copies) && (ptr = getenv(USC_COPIES)) != NULL) {
+ if (sscanf(ptr, "%d", &STD_COPIES) == 1 && STD_COPIES >= 0) {
+ if (Debug)
+ printf("Using env %s, set STD_COPIES = %d\n",
+ USC_COPIES, STD_COPIES);
+ }
+ }
+
+ /*
+ * The following are special system testing envs to turn on special
+ * hooks in the code.
+ */
+ if ((ptr = getenv("USC_TP_BARRIER")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
+ STD_TP_barrier=k;
+ else
+ STD_TP_barrier=1;
+ if (Debug)
+ printf("using env USC_TP_BARRIER, Set STD_TP_barrier to %d\n",
+ STD_TP_barrier);
+ }
+
+ if ((ptr = getenv("USC_LP_BARRIER")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0)
+ STD_LP_barrier=k;
+ else
+ STD_LP_barrier=1;
+ if (Debug)
+ printf("using env USC_LP_BARRIER, Set STD_LP_barrier to %d\n",
+ STD_LP_barrier);
+ }
+
+ if ((ptr = getenv("USC_TP_SHMEM")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
+ STD_TP_shmem_sz=k;
+ if (Debug)
+ printf("Using env USC_TP_SHMEM, Set STD_TP_shmem_sz to %d\n",
+ STD_TP_shmem_sz);
+ }
+ }
+
+ if ((ptr = getenv("USC_LP_SHMEM")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
+ STD_LP_shmem=k;
+ if (Debug)
+ printf("Using env USC_LP_SHMEM, Set STD_LP_shmem to %d\n",
+ STD_LP_shmem);
+ }
+ }
+
+ if ((ptr = getenv("USC_LD_SHMEM")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
+ STD_LD_shmem=k;
+ if (Debug)
+ printf("Using env USC_LD_SHMEM, Set STD_LD_shmem to %d\n",
+ STD_LD_shmem);
+ }
+ }
+
+ if ((ptr = getenv("USC_TP_SBRK")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
+ STD_TP_sbrk=k;
+ if (Debug)
+ printf("Using env USC_TP_SBRK, Set STD_TP_sbrk to %d\n",
+ STD_TP_sbrk);
+ }
+ }
+
+#if !defined(UCLINUX)
+ if ((ptr = getenv("USC_LP_SBRK")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
+ STD_LP_sbrk=k;
+ if (Debug)
+ printf("Using env USC_LP_SBRK, Set STD_LP_sbrk to %d\n",
+ STD_LP_sbrk);
+ }
+ }
+#endif /* if !defined(UCLINUX) */
+
+ if ((ptr = getenv("USC_LP_RECFUN")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
+ STD_LP_recfun = k;
+ if (STD_bigstack != NULL)
+ STD_bigstack = malloc(sizeof(struct usc_bigstack_t));
+ if (Debug)
+ printf("Using env USC_LP_RECFUN, Set STD_LP_recfun to %d\n",
+ STD_LP_recfun);
+ }
+ }
+
+ if ((ptr = getenv("USC_LD_RECFUN")) != NULL) {
+ if (sscanf(ptr, "%i", &k) == 1 && k >= 0) {
+ STD_LD_recfun = k;
+ if (STD_bigstack != NULL)
+ STD_bigstack = malloc(sizeof(struct usc_bigstack_t));
+ if (Debug)
+ printf("Using env USC_LD_RECFUN, Set STD_LD_recfun to %d\n",
+ STD_LD_recfun);
+ }
+ }
+
+#if UNIT_TEST
+ printf("The following variables after option and env parsing:\n");
+ printf("STD_FUNCTIONAL_TEST = %d\n", STD_FUNCTIONAL_TEST);
+ printf("STD_LOOP_DURATION = %f\n", STD_LOOP_DURATION);
+ printf("STD_LOOP_DELAY = %f\n", STD_LOOP_DELAY);
+ printf("STD_COPIES = %d\n", STD_COPIES);
+ printf("STD_LOOP_COUNT = %d\n", STD_LOOP_COUNT);
+ printf("STD_INFINITE = %d\n", STD_INFINITE);
+ printf("STD_TIMING_ON = %d\n", STD_TIMING_ON);
+ printf("STD_ERRNO_LOG = %d\n", STD_ERRNO_LOG);
+ printf("STD_PAUSE = %d\n", STD_PAUSE);
+#endif
+
+ return((char *) NULL);
+
+} /* end of parse_opts */
+
+/*********************************************************************
+ * print_help() - print help message and user help message
+ *********************************************************************/
+void print_help(void (*user_help)())
+{
+ STD_opts_help();
+
+ if (user_help)
+ user_help();
+}
+
+/*********************************************************************
+ * STD_opts_help() - return a help string for the STD_OPTIONS.
+ *********************************************************************/
+void STD_opts_help()
+{
+ int i;
+
+ for (i = 0; std_options[i].optstr; ++i) {
+ if (std_options[i].help)
+ printf("%s", std_options[i].help);
+ }
+}
+
+/*
+ * routine to goto when we get the SIGUSR1 for STD_PAUSE
+ */
+void STD_go(int sig)
+{
+ return;
+}
+
+/***********************************************************************
+ * This function will do desired end of global setup test
+ * hooks.
+ * Currently it will only do a pause waiting for sigusr1 if
+ * STD_PAUSE is set.
+ *
+ ***********************************************************************/
+int usc_global_setup_hook()
+{
+#ifndef UCLINUX
+ int cnt;
+ /* temp variable to store old signal action to be restored after pause */
+ int (*_TMP_FUNC)(void);
+
+ /*
+ * Fork STD_COPIES-1 copies.
+ */
+ for (cnt=1;cnt<STD_COPIES;cnt++) {
+ switch (fork() ) {
+ case -1:
+ fprintf(stderr, "%s: fork failed: %d - %s\n",
+ __FILE__, errno, strerror(errno));
+ break;
+ case 0: /* child */
+ cnt=STD_COPIES; /* to stop the forking */
+ break;
+
+ default: /* parent */
+ break;
+ }
+ }
+
+ /*
+ * pause waiting for sigusr1.
+ */
+ if (STD_PAUSE) {
+ _TMP_FUNC = (int (*)())signal(SIGUSR1, STD_go);
+ pause();
+ signal(SIGUSR1, (void (*)())_TMP_FUNC);
+ }
+
+#if !defined(UCLINUX)
+
+ if (STD_TP_sbrk || STD_LP_sbrk) {
+ STD_start_break=sbrk(0); /* get original sbreak size */
+ }
+
+ if (STD_TP_sbrk) {
+ sbrk(STD_TP_sbrk);
+ if (Debug)
+ printf("after sbrk(%d)\n", STD_TP_sbrk);
+ }
+
+#endif /* if !defined(UCLINUX) */
+#endif
+ return 0;
+}
+
+#define USECS_PER_SEC 1000000 /* microseconds per second */
+
+/***********************************************************************
+ * This function returns the number of get_current_time()'s return
+ * per second.
+ ***********************************************************************/
+
+static int get_timepersec()
+{
+ return USECS_PER_SEC; /* microseconds per second */
+
+}
+
+/***********************************************************************
+ * this function will get current time in microseconds since 1970.
+ ***********************************************************************/
+static int get_current_time()
+{
+ struct timeval curtime;
+
+ gettimeofday(&curtime, NULL);
+
+ /* microseconds since 1970 */
+ return (curtime.tv_sec*USECS_PER_SEC) + curtime.tv_usec;
+}
+
+/***********************************************************************
+ *
+ * This function will determine if test should continue iterating
+ * If the STD_INFINITE flag is set, return 1.
+ * If the STD_LOOP_COUNT variable is set, compare it against
+ * the counter.
+ * If the STD_LOOP_DURATION variable is set, compare current time against
+ * calculated stop_time.
+ * This function will return 1 until all desired looping methods
+ * have been met.
+ *
+ * counter integer is supplied by the user program.
+ ***********************************************************************/
+int usc_test_looping(int counter)
+{
+ static int first_time = 1;
+ static int stop_time = 0; /* stop time in rtc or usecs */
+ static int delay; /* delay in clocks or usecs */
+ int hertz = 0; /* clocks per second or usecs per second */
+ int ct, end; /* current time, end delay time */
+ int keepgoing = 0; /* used to determine return value */
+
+ /*
+ * If this is the first iteration and we are looping for
+ * duration of STD_LOOP_DURATION seconds (fractional) or
+ * doing loop delays, get the clocks per second.
+ */
+ if (first_time) {
+
+ first_time = 0;
+ if (STD_LOOP_DELAY || STD_LOOP_DURATION) {
+ hertz = get_timepersec();
+ }
+
+ /*
+ * If looping for duration, calculate stop time in
+ * clocks.
+ */
+
+ if (STD_LOOP_DURATION) {
+ ct=get_current_time();
+ stop_time = (int)((float)hertz * STD_LOOP_DURATION) + ct;
+ }
+
+ /*
+ * If doing delay each iteration, calcuate the number
+ * of clocks for each delay.
+ */
+ if (STD_LOOP_DELAY) {
+ delay = (int)((float)hertz * STD_LOOP_DELAY);
+ }
+
+ }
+
+ /*
+ * if delay each iteration, loop for delay clocks.
+ * This will not be done on first iteration.
+ * The delay will happen before determining if
+ * there will be another iteration.
+ */
+ else if (STD_LOOP_DELAY) {
+ ct = get_current_time();
+ end = ct + delay;
+ while (ct < end) {
+ /*
+ * The following are special test hooks in the delay loop.
+ */
+ if (STD_LD_recfun) {
+ if (Debug)
+ printf("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
+ STD_LD_recfun);
+ usc_recressive_func(0, STD_LD_recfun, *STD_bigstack);
+ }
+
+ ct=get_current_time();
+ }
+ }
+
+ if (STD_INFINITE) {
+ keepgoing++;
+ }
+
+ if (STD_LOOP_COUNT && counter < STD_LOOP_COUNT) {
+ keepgoing++;
+ }
+
+ if (STD_LOOP_DURATION != 0.0 && get_current_time() < stop_time) {
+ keepgoing++;
+ }
+
+ if (keepgoing == 0)
+ return 0;
+
+ /*
+ * The following code allows special system testing hooks.
+ */
+
+ if (STD_LP_recfun) {
+ if (Debug)
+ printf("calling usc_recressive_func(0, %d, *STD_bigstack)\n",
+ STD_LP_recfun);
+ usc_recressive_func(0, STD_LP_recfun, *STD_bigstack);
+ }
+
+#if !defined(UCLINUX)
+
+ if (STD_LP_sbrk) {
+ if (Debug)
+ printf("about to do sbrk(%d)\n", STD_LP_sbrk);
+ sbrk(STD_LP_sbrk);
+ }
+#endif
+
+
+ if (keepgoing)
+ return 1;
+ else
+ return 0; /* done - stop iterating */
+}
+
+
+/*
+ * This function recressively calls itself max times.
+ */
+static void usc_recressive_func(int cnt, int max, struct usc_bigstack_t bstack)
+{
+ if (cnt < max)
+ usc_recressive_func(cnt+1, max, bstack);
+
+}
+
+#if UNIT_TEST
+/******************************************************************************
+ * UNIT TEST CODE
+ * UNIT TEST CODE
+ *
+ * this following code is provide so that unit testing can
+ * be done fairly easily.
+ ******************************************************************************/
+
+int Help = 0;
+int Help2 = 0;
+char *ptr;
+
+/*
+ * Code from usctest.h that not part of this file since we are the library.
+ */
+
+struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
+
+int TEST_RETURN;
+int TEST_ERRNO;
+
+/* for test specific parse_opts options */
+option_t Options[] = {
+ { "help", &Help2, NULL }, /* -help option */
+ { "h", &Help, NULL }, /* -h option */
+ { TIMING, NULL, NULL}, /* disable -timing option */
+
+#if INVALID_TEST_CASES
+ { "missingflag", NULL, &ptr }, /* error */
+ { "missingarg:", &Help, NULL }, /* error */
+#endif /* INVALID_TEST_CASES */
+
+ { NULL, NULL, NULL }
+};
+
+int main(int argc, char **argv)
+{
+ int lc;
+ char *msg;
+ struct timeval t;
+ int cnt;
+
+ if ((msg = parse_opts(argc, argv, Options)) != NULL) {
+ printf("ERROR: %s\n", msg);
+ exit(1);
+ }
+
+ TEST_PAUSE;
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ TEST(gettimeofday(&t, NULL));
+ printf("iter=%d: sec:%d, usec:%6.6d %s", lc+1, t.tv_sec,
+ t.tv_usec, ctime(&t.tv_sec));
+ }
+
+
+ TEST_CLEANUP;
+
+ exit(0);
+}
+
+#endif /* UNIT_TEST */
diff --git a/ltp_framework/lib/pattern.c b/ltp_framework/lib/pattern.c
new file mode 100644
index 0000000..fc59d9b
--- /dev/null
+++ b/ltp_framework/lib/pattern.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#include <string.h>
+#include "pattern.h"
+
+/*
+ * The routines in this module are used to fill/check a data buffer
+ * with/against a known pattern.
+ */
+
+int
+pattern_check(buf, buflen, pat, patlen, patshift)
+char *buf;
+int buflen;
+char *pat;
+int patlen;
+int patshift;
+{
+ int nb, ncmp, nleft;
+ char *cp;
+
+ if (patlen)
+ patshift = patshift % patlen;
+
+ cp = buf;
+ nleft = buflen;
+
+ /*
+ * The following 2 blocks of code are to compare the first patlen
+ * bytes of buf. We need 2 checks if patshift is > 0 since we
+ * must check the last (patlen - patshift) bytes, and then the
+ * first (patshift) bytes.
+ */
+
+ nb = patlen - patshift;
+ if (nleft < nb) {
+ return (memcmp(cp, pat + patshift, nleft) ? -1 : 0);
+ } else {
+ if (memcmp(cp, pat + patshift, nb))
+ return -1;
+
+ nleft -= nb;
+ cp += nb;
+ }
+
+ if (patshift > 0) {
+ nb = patshift;
+ if (nleft < nb) {
+ return (memcmp(cp, pat, nleft) ? -1 : 0);
+ } else {
+ if (memcmp(cp, pat, nb))
+ return -1;
+
+ nleft -= nb;
+ cp += nb;
+ }
+ }
+
+ /*
+ * Now, verify the rest of the buffer using the algorithm described
+ * in the function header.
+ */
+
+ ncmp = cp - buf;
+ while (ncmp < buflen) {
+ nb = (ncmp < nleft) ? ncmp : nleft;
+ if (memcmp(buf, cp, nb))
+ return -1;
+
+ cp += nb;
+ ncmp += nb;
+ nleft -= nb;
+ }
+
+ return 0;
+}
+
+int
+pattern_fill(buf, buflen, pat, patlen, patshift)
+char *buf;
+int buflen;
+char *pat;
+int patlen;
+int patshift;
+{
+ int trans, ncopied, nleft;
+ char *cp;
+
+ if (patlen)
+ patshift = patshift % patlen;
+
+ cp = buf;
+ nleft = buflen;
+
+ /*
+ * The following 2 blocks of code are to fill the first patlen
+ * bytes of buf. We need 2 sections if patshift is > 0 since we
+ * must first copy the last (patlen - patshift) bytes into buf[0]...,
+ * and then the first (patshift) bytes of pattern following them.
+ */
+
+ trans = patlen - patshift;
+ if (nleft < trans) {
+ memcpy(cp, pat + patshift, nleft);
+ return 0;
+ } else {
+ memcpy(cp, pat + patshift, trans);
+ nleft -= trans;
+ cp += trans;
+ }
+
+ if (patshift > 0) {
+ trans = patshift;
+ if (nleft < trans) {
+ memcpy(cp, pat, nleft);
+ return 0;
+ } else {
+ memcpy(cp, pat, trans);
+ nleft -= trans;
+ cp += trans;
+ }
+ }
+
+ /*
+ * Now, fill the rest of the buffer using the algorithm described
+ * in the function header comment.
+ */
+
+ ncopied = cp - buf;
+ while (ncopied < buflen) {
+ trans = (ncopied < nleft) ? ncopied : nleft;
+ memcpy(cp, buf, trans);
+ cp += trans;
+ ncopied += trans;
+ nleft -= trans;
+ }
+
+ return(0);
+} \ No newline at end of file
diff --git a/ltp_framework/lib/random_range.c b/ltp_framework/lib/random_range.c
new file mode 100644
index 0000000..b1bde84
--- /dev/null
+++ b/ltp_framework/lib/random_range.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include "random_range.h"
+
+/*
+ * Internal format of the range array set up by parse_range()
+ */
+
+struct range {
+ int min;
+ int max;
+ int mult;
+};
+
+/*
+ * parse_ranges() is a function to parse a comma-separated list of range
+ * tokens each having the following form:
+ *
+ * num
+ * or
+ * min:max[:mult]
+ *
+ * any of the values may be blank (ie. min::mult, :max, etc.) and default
+ * values for missing arguments may be supplied by the caller.
+ *
+ * The special first form is short hand for 'num:num'.
+ *
+ * After parsing the string, the ranges are put into an array of integers,
+ * which is malloc'd by the routine. The min, max, and mult entries of each
+ * range can be extracted from the array using the range_min(), range_max(),
+ * and range_mult() functions.
+ *
+ * It is the responsibility of the caller to free the space allocated by
+ * parse_ranges() - a single call to free() will free the space.
+ *
+ * str The string to parse - assumed to be a comma-separated
+ * list of tokens having the above format.
+ * defmin default value to plug in for min, if it is missing
+ * defmax default value to plug in for max, if it is missing
+ * defmult default value to plug in for mult, if missing
+ * parse_func A user-supplied function pointer, which parse_ranges()
+ * can call to parse the min, max, and mult strings. This
+ * allows for customized number formats. The function
+ * MUST have the following prototype:
+ * parse_func(char *str, int *val)
+ * The function should return -1 if str cannot be parsed
+ * into an integer, or >= 0 if it was successfully
+ * parsed. The resulting integer will be stored in
+ * *val. If parse_func is NULL, parse_ranges will parse
+ * the tokens in a manner consistent with the the sscanf
+ * %i format.
+ * range_ptr A user-supplied char **, which will be set to point
+ * at malloc'd space which holds the parsed range
+ * values. If range_ptr is NULL, parse_ranges() just
+ * parses the string. The data returned in range_ptr
+ * should not be processed directly - use the functions
+ * range_min(), range_max(), and range_mult() to access
+ * data for a given range.
+ * errptr user-supplied char ** which can be set to point to a
+ * static error string. If errptr is NULL, it is ignored.
+ *
+ * parse_range() returns -1 on error, or the number of ranges parsed.
+ */
+
+static int str_to_int();
+static long long divider(long long, long long, long long, long long);
+
+int
+parse_ranges(str, defmin, defmax, defmult, parse_func, rangeptr, errptr)
+char *str;
+int defmin;
+int defmax;
+int defmult;
+int (*parse_func)();
+char **rangeptr;
+char **errptr;
+{
+ int ncommas;
+ char *tmpstr, *cp, *tok, *n1str, *n2str, *multstr;
+ struct range *rp, *ranges;
+ static char errmsg[256];
+
+ if (errptr != NULL) {
+ *errptr = errmsg;
+ }
+
+ for (ncommas = 0, cp = str; *cp != '\0'; cp++) {
+ if (*cp == ',') {
+ ncommas++;
+ }
+ }
+
+ if (parse_func == NULL) {
+ parse_func = str_to_int;
+ }
+
+ tmpstr = strdup(str);
+ ranges = (struct range *)malloc((ncommas+1) * sizeof(struct range));
+ rp = ranges;
+
+ tok = strtok(tmpstr, ",");
+ while (tok != NULL) {
+ n1str = tok;
+ n2str = NULL;
+ multstr = NULL;
+
+ rp->min = defmin;
+ rp->max = defmax;
+ rp->mult = defmult;
+
+ if ((cp = strchr(n1str, ':')) != NULL) {
+ *cp = '\0';
+ n2str = cp+1;
+
+ if ((cp = strchr(n2str, ':')) != NULL) {
+ *cp = '\0';
+ multstr = cp+1;
+ }
+ }
+
+ /*
+ * Parse the 'min' field - if it is zero length (:n2[:mult]
+ * format), retain the default value, otherwise, pass the
+ * string to the parse function.
+ */
+
+ if ((int)strlen(n1str) > 0) {
+ if ((*parse_func)(n1str, &rp->min) < 0) {
+ sprintf(errmsg, "error parsing string %s into an integer", n1str);
+ free(tmpstr);
+ free(ranges);
+ return -1;
+ }
+ }
+
+ /*
+ * Process the 'max' field - if one was not present (n1 format)
+ * set max equal to min. If the field was present, but
+ * zero length (n1: format), retain the default. Otherwise
+ * pass the string to the parse function.
+ */
+
+ if (n2str == NULL) {
+ rp->max = rp->min;
+ } else if ((int)strlen(n2str) > 0) {
+ if ((*parse_func)(n2str, &rp->max) < 0) {
+ sprintf(errmsg, "error parsing string %s into an integer", n2str);
+ free(tmpstr);
+ free(ranges);
+ return -1;
+ }
+ }
+
+ /*
+ * Process the 'mult' field - if one was not present
+ * (n1:n2 format), or the field was zero length (n1:n2: format)
+ * then set the mult field to defmult - otherwise pass then
+ * mult field to the parse function.
+ */
+
+ if (multstr != NULL && (int)strlen(multstr) > 0) {
+ if ((*parse_func)(multstr, &rp->mult) < 0) {
+ sprintf(errmsg, "error parsing string %s into an integer", multstr);
+ free(tmpstr);
+ free(ranges);
+ return -1;
+ }
+ }
+
+ rp++;
+ tok = strtok(NULL, ",");
+ }
+
+ free(tmpstr);
+
+ if (rangeptr != NULL) {
+ *rangeptr = (char *)ranges;
+ } else {
+ free(ranges); /* just running in parse mode */
+ }
+
+ return (rp - ranges);
+}
+
+/*
+ * The default integer-parsing function
+ */
+
+static int
+str_to_int(str, ip)
+char *str;
+int *ip;
+{
+ char c;
+
+ if (sscanf(str, "%i%c", ip, &c) != 1) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Three simple functions to return the min, max, and mult values for a given
+ * range. It is assumed that rbuf is a range buffer set up by parse_ranges(),
+ * and that r is a valid range within that buffer.
+ */
+
+int
+range_min(rbuf, r)
+char *rbuf;
+int r;
+{
+ return ((struct range *)rbuf)[r].min;
+}
+
+int
+range_max(rbuf, r)
+char *rbuf;
+int r;
+{
+ return ((struct range *)rbuf)[r].max;
+}
+
+int
+range_mult(rbuf, r)
+char *rbuf;
+int r;
+{
+ return ((struct range *)rbuf)[r].mult;
+}
+
+/*****************************************************************************
+ * random_range(int start, int end, int mult, char **errp)
+ *
+ * Returns a psuedo-random number which is >= 'start', <= 'end', and a multiple
+ * of 'mult'. Start and end may be any valid integer, but mult must be an
+ * integer > 0. errp is a char ** which will be set to point to a static
+ * error message buffer if it is not NULL, and an error occurs.
+ *
+ * The errp is the only way to check if the routine fails - currently the only
+ * failure conditions are:
+ *
+ * mult < 1
+ * no numbers in the start-end range that are a multiple of 'mult'
+ *
+ * If random_range_fails, and errp is a valid pointer, it will point to an
+ * internal error buffer. If errp is a vaild pointer, and random_range
+ * is successful, errp will be set to NULL.
+ *
+ * Note - if mult is 1 (the most common case), there are error conditions
+ * possible, and errp need not be used.
+ *
+ * Note: Uses lrand48(), assuming that set_random_seed() uses srand48() when
+ * setting the seed.
+ *****************************************************************************/
+
+long
+random_range(min, max, mult, errp)
+int min;
+int max;
+int mult;
+char **errp;
+{
+ int r, nmults, orig_min, orig_max, orig_mult, tmp;
+ extern long lrand48();
+ static char errbuf[128];
+
+ /*
+ * Sanity check
+ */
+
+ if (mult < 1) {
+ if (errp != NULL) {
+ sprintf(errbuf, "mult arg must be greater than 0");
+ *errp = errbuf;
+ }
+ return -1;
+ }
+
+ /*
+ * Save original parameter values for use in error message
+ */
+
+ orig_min = min;
+ orig_max = max;
+ orig_mult = mult;
+
+ /*
+ * switch min/max if max < min
+ */
+
+ if (max < min) {
+ tmp = max;
+ max = min;
+ min = tmp;
+ }
+
+ /*
+ * select the random number
+ */
+
+ if ((r = min % mult)) /* bump to the next higher 'mult' multiple */
+ min += mult - r;
+
+ if ((r = max % mult)) /* reduce to the next lower 'mult' multiple */
+ max -= r;
+
+ if (min > max) { /* no 'mult' multiples between min & max */
+ if (errp != NULL) {
+ sprintf(errbuf, "no numbers in the range %d:%d that are a multiple of %d", orig_min, orig_max, orig_mult);
+ *errp = errbuf;
+ }
+ return -1;
+ }
+
+ if (errp != NULL) {
+ *errp = NULL;
+ }
+
+ nmults = ((max - min) / mult) + 1;
+#if CRAY
+ /*
+ * If max is less than 2gb, then the value can fit in 32 bits
+ * and the standard lrand48() routine can be used.
+ */
+ if (max <= (long)2147483647) {
+ return (long) (min + (((long)lrand48() % nmults) * mult));
+ } else {
+ /*
+ * max is greater than 2gb - meeds more than 32 bits.
+ * Since lrand48 only will get a number up to 32bits.
+ */
+ long randnum;
+ randnum=divider(min, max, 0, -1);
+ return (long) (min + ((randnum % nmults) * mult));
+ }
+
+#else
+ return (min + ((lrand48() % nmults) * mult));
+#endif
+
+}
+
+/*
+ * Just like random_range, but all values are longs.
+ */
+long
+random_rangel(min, max, mult, errp)
+long min;
+long max;
+long mult;
+char **errp;
+{
+ long r, nmults, orig_min, orig_max, orig_mult, tmp;
+ extern long lrand48();
+ static char errbuf[128];
+
+ /*
+ * Sanity check
+ */
+
+ if (mult < 1) {
+ if (errp != NULL) {
+ sprintf(errbuf, "mult arg must be greater than 0");
+ *errp = errbuf;
+ }
+ return -1;
+ }
+
+ /*
+ * Save original parameter values for use in error message
+ */
+
+ orig_min = min;
+ orig_max = max;
+ orig_mult = mult;
+
+ /*
+ * switch min/max if max < min
+ */
+
+ if (max < min) {
+ tmp = max;
+ max = min;
+ min = tmp;
+ }
+
+ /*
+ * select the random number
+ */
+
+ if ((r = min % mult)) /* bump to the next higher 'mult' multiple */
+ min += mult - r;
+
+ if ((r = max % mult)) /* reduce to the next lower 'mult' multiple */
+ max -= r;
+
+ if (min > max) { /* no 'mult' multiples between min & max */
+ if (errp != NULL) {
+ sprintf(errbuf,
+ "no numbers in the range %ld:%ld that are a multiple of %ld",
+ orig_min, orig_max, orig_mult);
+ *errp = errbuf;
+ }
+ return -1;
+ }
+
+ if (errp != NULL) {
+ *errp = NULL;
+ }
+
+ nmults = ((max - min) / mult) + 1;
+#if CRAY || (_MIPS_SZLONG == 64)
+ /*
+ * If max is less than 2gb, then the value can fit in 32 bits
+ * and the standard lrand48() routine can be used.
+ */
+ if (max <= (long)2147483647) {
+ return (long) (min + (((long)lrand48() % nmults) * mult));
+ } else {
+ /*
+ * max is greater than 2gb - meeds more than 32 bits.
+ * Since lrand48 only will get a number up to 32bits.
+ */
+ long randnum;
+ randnum=divider(min, max, 0, -1);
+ return (long) (min + ((randnum % nmults) * mult));
+ }
+
+#else
+ return (min + ((lrand48() % nmults) * mult));
+#endif
+}
+
+/*
+ * Attempts to be just like random_range, but everything is long long (64 bit)
+ */
+long long
+random_rangell(min, max, mult, errp)
+long long min;
+long long max;
+long long mult;
+char **errp;
+{
+ long long r, nmults, orig_min, orig_max, orig_mult, tmp;
+ long long randnum;
+ extern long lrand48();
+ static char errbuf[128];
+
+ /*
+ * Sanity check
+ */
+
+ if (mult < 1) {
+ if (errp != NULL) {
+ sprintf(errbuf, "mult arg must be greater than 0");
+ *errp = errbuf;
+ }
+ return -1;
+ }
+
+ /*
+ * Save original parameter values for use in error message
+ */
+
+ orig_min = min;
+ orig_max = max;
+ orig_mult = mult;
+
+ /*
+ * switch min/max if max < min
+ */
+
+ if (max < min) {
+ tmp = max;
+ max = min;
+ min = tmp;
+ }
+
+ /*
+ * select the random number
+ */
+
+ if ((r = min % mult)) /* bump to the next higher 'mult' multiple */
+ min += mult - r;
+
+ if ((r = max % mult)) /* reduce to the next lower 'mult' multiple */
+ max -= r;
+
+ if (min > max) { /* no 'mult' multiples between min & max */
+ if (errp != NULL) {
+ sprintf(errbuf,
+ "no numbers in the range %lld:%lld that are a multiple of %lld",
+ orig_min, orig_max, orig_mult);
+ *errp = errbuf;
+ }
+ return -1;
+ }
+
+ if (errp != NULL) {
+ *errp = NULL;
+ }
+
+ nmults = ((max - min) / mult) + 1;
+ /*
+ * If max is less than 2gb, then the value can fit in 32 bits
+ * and the standard lrand48() routine can be used.
+ */
+ if (max <= (long)2147483647) {
+ return (long long) (min + (((long long)lrand48() % nmults) * mult));
+ } else {
+ /*
+ * max is greater than 2gb - meeds more than 32 bits.
+ * Since lrand48 only will get a number up to 32bits.
+ */
+ randnum=divider(min, max, 0, -1);
+ return (long long) (min + ((randnum % nmults) * mult));
+ }
+
+}
+
+/*
+ * This functional will recusively call itself to return a random
+ * number min and max. It was designed to work the 64bit numbers
+ * even when compiled as 32 bit process.
+ * algorithm: to use the official lrand48() routine - limited to 32 bits.
+ * find the difference between min and max (max-min).
+ * if the difference is 2g or less, use the random number gotton from lrand48().
+ * Determine the midway point between min and max.
+ * if the midway point is less than 2g from min or max,
+ * randomly add the random number gotton from lrand48() to
+ * either min or the midpoint.
+ * Otherwise, call outself with min and max being min and midway value or
+ * midway value and max. This will reduce the range in half.
+ */
+static long long
+divider(long long min, long long max, long long cnt, long long rand)
+{
+ long long med, half, diff;
+
+ /*
+ * prevent run away code. We are dividing by two each count.
+ * if we get to a count of more than 32, we should have gotten
+ * to 2gb.
+ */
+ if (cnt > 32)
+ return -1;
+
+ /*
+ * Only get a random number the first time.
+ */
+ if (cnt == 0 || rand < -1) {
+ rand = (long long)lrand48(); /* 32 bit random number */
+ }
+
+ diff = max - min;
+
+ if (diff <= 2147483647)
+ return min + rand;
+
+ half = diff/(long long)2; /* half the distance between min and max */
+ med = min + half; /* med way point between min and max */
+
+#if DEBUG
+printf("divider: min=%lld, max=%lld, cnt=%lld, rand=%lld\n", min, max, cnt, rand);
+printf(" diff = %lld, half = %lld, med = %lld\n", diff, half, med);
+#endif
+
+ if (half <= 2147483647) {
+ /*
+ * If half is smaller than 2gb, we can use the random number
+ * to pick the number within the min to med or med to max
+ * if the cnt bit of rand is zero or one, respectively.
+ */
+ if (rand & (1<<cnt))
+ return med + rand;
+ else
+ return min + rand;
+ } else {
+ /*
+ * recursively call ourself to reduce the value to the bottom half
+ * or top half (bit cnt is set).
+ */
+ if (rand & (1<<cnt)) {
+ return divider(med, max, cnt+1, rand);
+ } else {
+ return divider(min, med, cnt+1, rand);
+ }
+
+ }
+
+}
+
+
+/*****************************************************************************
+ * random_range_seed(s)
+ *
+ * Sets the random seed to s. Uses srand48(), assuming that lrand48() will
+ * be used in random_range().
+ *****************************************************************************/
+
+void
+random_range_seed(s)
+long s;
+{
+ extern void srand48();
+
+ srand48(s);
+}
+
+/****************************************************************************
+ * random_bit(mask)
+ *
+ * This function randomly returns a single bit from the bits
+ * set in mask. If mask is zero, zero is returned.
+ *
+ ****************************************************************************/
+long
+random_bit(long mask)
+{
+ int nbits = 0; /* number of set bits in mask */
+ long bit; /* used to count bits and num of set bits choosen */
+ int nshift; /* used to count bit shifts */
+
+ if (mask == 0)
+ return 0;
+
+ /*
+ * get the number of bits set in mask
+ */
+#ifndef CRAY
+
+ bit=1L;
+ for (nshift=0; (unsigned int)nshift<sizeof(long)*8; nshift++) {
+ if (mask & bit)
+ nbits++;
+ bit=bit<<1;
+ }
+
+#else
+ nbits=_popcnt(mask);
+#endif /* if CRAY */
+
+ /*
+ * randomly choose a bit.
+ */
+ bit=random_range(1, nbits, 1, NULL);
+
+ /*
+ * shift bits until you determine which bit was randomly choosen.
+ * nshift will hold the number of shifts to make.
+ */
+
+ nshift=0;
+ while (bit) {
+ /* check if the current one's bit is set */
+ if (mask & 1L) {
+ bit--;
+ }
+ mask = mask >> 1;
+ nshift++;
+ }
+
+ return 01L << (nshift-1);
+
+}
+
+
+#if RANDOM_BIT_UNITTEST
+/*
+ * The following is a unit test main function for random_bit().
+ */
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int ind;
+ int cnt, iter;
+ long mask, ret;
+
+ printf("test for first and last bit set\n");
+ mask=1L;
+ ret=random_bit(mask);
+ printf("random_bit(%#o) returned %#o\n", mask, ret);
+
+ mask=1L<<(sizeof(long)*8-1);
+ ret=random_bit(mask);
+ printf("random_bit(%#o) returned %#o\n", mask, ret);
+
+ if (argc >= 3) {
+ iter=atoi(argv[1]);
+ for (ind=2; ind<argc; ind++) {
+ printf("Calling random_bit %d times for mask %#o\n", iter, mask);
+ sscanf(argv[ind], "%i", &mask);
+ for (cnt=0; cnt<iter; cnt++) {
+ ret=random_bit(mask);
+ printf("random_bit(%#o) returned %#o\n", mask, ret);
+ }
+ }
+ }
+ exit(0);
+}
+
+#endif /* end if RANDOM_BIT_UNITTEST */
+
+
+#if UNIT_TEST
+/*
+ * The following is a unit test main function for random_range*().
+ */
+
+#define PARTNUM 10 /* used to determine even distribution of random numbers */
+#define MEG 1024*1024*1024
+#define GIG 1073741824
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int ind;
+ int cnt, iter=10;
+ int imin=0, imult=1, itmin, itmax=0;
+#if CRAY
+ int imax=6*GIG; /* higher than 32 bits */
+#else
+ int imax=1048576;
+#endif
+
+ long lret, lmin=0, lmult=1, ltmin, ltmax=0;
+#if CRAY || (_MIPS_SZLONG == 64)
+ long lmax=6*(long)GIG; /* higher than 32 bits */
+#else
+ long lmax=1048576;
+#endif
+ long long llret, llmin=0, llmult=1, lltmin, lltmax=0;
+ long long llmax=(long long)80*(long long)GIG;
+
+ long part;
+ long long lpart;
+ long cntarr[PARTNUM];
+ long valbound[PARTNUM];
+ long long lvalbound[PARTNUM];
+
+ for (ind=0; ind<PARTNUM; ind++)
+ cntarr[ind]=0;
+
+ if (argc < 2) {
+ printf("Usage: %s func [iterations] \n", argv[0]);
+ printf("func can be random_range, random_rangel, random_rangell\n");
+ exit(1);
+ }
+
+ if (argc >= 3) {
+ if (sscanf(argv[2], "%i", &iter) != 1) {
+ printf("Usage: %s [func iterations] \n", argv[0]);
+ printf("argv[2] is not a number\n");
+ exit(1);
+ }
+ }
+
+
+ /*
+ * random_rangel ()
+ */
+ if (strcmp(argv[1], "random_rangel") == 0) {
+ ltmin=lmax;
+ part = lmax/PARTNUM;
+ for (ind=0; ind<PARTNUM; ind++) {
+ valbound[ind]=part*ind;
+ }
+
+ for (cnt=0; cnt<iter; cnt++) {
+ lret=random_rangel(lmin, lmax, lmult, NULL);
+ if (iter < 100)
+ printf("%ld\n", lret);
+ if (lret < ltmin)
+ ltmin = lret;
+ if (lret > ltmax)
+ ltmax = lret;
+ for (ind=0; ind<PARTNUM-1; ind++) {
+ if (valbound[ind] < lret && lret <= valbound[ind+1]) {
+ cntarr[ind]++;
+ break;
+ }
+ }
+ if (lret > valbound[PARTNUM-1]) {
+ cntarr[PARTNUM-1]++;
+ }
+ }
+ for (ind=0; ind<PARTNUM-1; ind++) {
+ printf("%2d %-13ld to %-13ld %5ld %4.4f\n", ind+1,
+ valbound[ind], valbound[ind+1], cntarr[ind],
+ (float)(cntarr[ind]/(float)iter));
+ }
+ printf("%2d %-13ld to %-13ld %5ld %4.4f\n", PARTNUM,
+ valbound[PARTNUM-1], lmax, cntarr[PARTNUM-1],
+ (float)(cntarr[PARTNUM-1]/(float)iter));
+ printf(" min=%ld, max=%ld\n", ltmin, ltmax);
+
+ } else if (strcmp(argv[1], "random_rangell") == 0) {
+ /*
+ * random_rangell() unit test
+ */
+ lltmin=llmax;
+ lpart = llmax/PARTNUM;
+ for (ind=0; ind<PARTNUM; ind++) {
+ lvalbound[ind]=(long long)(lpart*ind);
+ }
+
+ for (cnt=0; cnt<iter; cnt++) {
+ llret=random_rangell(llmin, llmax, llmult, NULL);
+ if (iter < 100)
+ printf("random_rangell returned %lld\n", llret);
+ if (llret < lltmin)
+ lltmin = llret;
+ if (llret > lltmax)
+ lltmax = llret;
+
+ for (ind=0; ind<PARTNUM-1; ind++) {
+ if (lvalbound[ind] < llret && llret <= lvalbound[ind+1]) {
+ cntarr[ind]++;
+ break;
+ }
+ }
+ if (llret > lvalbound[PARTNUM-1]) {
+ cntarr[PARTNUM-1]++;
+ }
+ }
+ for (ind=0; ind<PARTNUM-1; ind++) {
+ printf("%2d %-13lld to %-13lld %5ld %4.4f\n", ind+1,
+ lvalbound[ind], lvalbound[ind+1], cntarr[ind],
+ (float)(cntarr[ind]/(float)iter));
+ }
+ printf("%2d %-13lld to %-13lld %5ld %4.4f\n", PARTNUM,
+ lvalbound[PARTNUM-1], llmax, cntarr[PARTNUM-1],
+ (float)(cntarr[PARTNUM-1]/(float)iter));
+ printf(" min=%lld, max=%lld\n", lltmin, lltmax);
+
+ } else {
+ /*
+ * random_range() unit test
+ */
+ itmin=imax;
+ part = imax/PARTNUM;
+ for (ind=0; ind<PARTNUM; ind++) {
+ valbound[ind]=part*ind;
+ }
+
+ for (cnt=0; cnt<iter; cnt++) {
+ lret=random_range(imin, imax, imult, NULL);
+ if (iter < 100)
+ printf("%ld\n", lret);
+ if (lret < itmin)
+ itmin = lret;
+ if (lret > itmax)
+ itmax = lret;
+
+ for (ind=0; ind<PARTNUM-1; ind++) {
+ if (valbound[ind] < lret && lret <= valbound[ind+1]) {
+ cntarr[ind]++;
+ break;
+ }
+ }
+ if (lret > valbound[PARTNUM-1]) {
+ cntarr[PARTNUM-1]++;
+ }
+ }
+ for (ind=0; ind<PARTNUM-1; ind++) {
+ printf("%2d %-13ld to %-13ld %5ld %4.4f\n", ind+1,
+ valbound[ind], valbound[ind+1], cntarr[ind],
+ (float)(cntarr[ind]/(float)iter));
+ }
+ printf("%2d %-13ld to %-13ld %5ld %4.4f\n", PARTNUM,
+ valbound[PARTNUM-1], (long)imax, cntarr[PARTNUM-1],
+ (float)(cntarr[PARTNUM-1]/(float)iter));
+ printf(" min=%d, max=%d\n", itmin, itmax);
+
+ }
+
+ exit(0);
+}
+
+#endif \ No newline at end of file
diff --git a/ltp_framework/lib/rmobj.c b/ltp_framework/lib/rmobj.c
new file mode 100644
index 0000000..1ac9ee3
--- /dev/null
+++ b/ltp_framework/lib/rmobj.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+/* $Id: rmobj.c,v 1.5 2009/07/20 10:59:32 vapier Exp $ */
+
+/**********************************************************
+ *
+ * OS Testing - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME : rmobj()
+ *
+ * FUNCTION TITLE : Remove an object
+ *
+ * SYNOPSIS:
+ * int rmobj(char *obj, char **errmsg)
+ *
+ * AUTHOR : Kent Rogers
+ *
+ * INITIAL RELEASE : UNICOS 7.0
+ *
+ * USER DESCRIPTION
+ * This routine will remove the specified object. If the specified
+ * object is a directory, it will recursively remove the directory
+ * and everything underneath it. It assumes that it has privilege
+ * to remove everything that it tries to remove. If rmobj() encounters
+ * any problems, and errmsg is not NULL, errmsg is set to point to a
+ * string explaining the error.
+ *
+ * DETAILED DESCRIPTION
+ * Allocate space for the directory and its contents
+ * Open the directory to get access to what is in it
+ * Loop through the objects in the directory:
+ * If the object is not "." or "..":
+ * Determine the file type by calling lstat()
+ * If the object is not a directory:
+ * Remove the object with unlink()
+ * Else:
+ * Call rmobj(object) to remove the object's contents
+ * Determine the link count on object by calling lstat()
+ * If the link count >= 3:
+ * Remove the directory with unlink()
+ * Else
+ * Remove the directory with rmdir()
+ * Close the directory and free the pointers
+ *
+ * RETURN VALUE
+ * If there are any problems, rmobj() will set errmsg (if it was not
+ * NULL) and return -1. Otherwise it will return 0.
+ *
+ ************************************************************/
+#include <errno.h> /* for errno */
+#include <stdio.h> /* for NULL */
+#include <stdlib.h> /* for malloc() */
+#include <string.h> /* for string function */
+#include <limits.h> /* for PATH_MAX */
+#include <sys/types.h> /* for opendir(), readdir(), closedir(), stat() */
+#include <sys/stat.h> /* for [l]stat() */
+#include <dirent.h> /* for opendir(), readdir(), closedir() */
+#include <unistd.h> /* for rmdir(), unlink() */
+#include "rmobj.h"
+
+#define SYSERR strerror(errno)
+
+int
+rmobj(char *obj, char **errmsg)
+{
+ int ret_val = 0; /* return value from this routine */
+ DIR *dir; /* pointer to a directory */
+ struct dirent *dir_ent; /* pointer to directory entries */
+ char dirobj[PATH_MAX]; /* object inside directory to modify */
+ struct stat statbuf; /* used to hold stat information */
+ static char err_msg[1024]; /* error message */
+
+ /* Determine the file type */
+ if (lstat(obj, &statbuf) < 0) {
+ if (errmsg != NULL) {
+ sprintf(err_msg, "lstat(%s) failed; errno=%d: %s",
+ obj, errno, SYSERR);
+ *errmsg = err_msg;
+ }
+ return -1;
+ }
+
+ /* Take appropriate action, depending on the file type */
+ if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
+ /* object is a directory */
+
+ /* Do NOT perform the request if the directory is "/" */
+ if (!strcmp(obj, "/")) {
+ if (errmsg != NULL) {
+ sprintf(err_msg, "Cannot remove /");
+ *errmsg = err_msg;
+ }
+ return -1;
+ }
+
+ /* Open the directory to get access to what is in it */
+ if ((dir = opendir(obj)) == NULL) {
+ if (rmdir(obj) != 0) {
+ if (errmsg != NULL) {
+ sprintf(err_msg, "rmdir(%s) failed; errno=%d: %s",
+ obj, errno, SYSERR);
+ *errmsg = err_msg;
+ }
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+
+ /* Loop through the entries in the directory, removing each one */
+ for (dir_ent = (struct dirent *)readdir(dir);
+ dir_ent != NULL;
+ dir_ent = (struct dirent *)readdir(dir)) {
+
+ /* Don't remove "." or ".." */
+ if (!strcmp(dir_ent->d_name, ".") || !strcmp(dir_ent->d_name, ".."))
+ continue;
+
+ /* Recursively call this routine to remove the current entry */
+ sprintf(dirobj, "%s/%s", obj, dir_ent->d_name);
+ if (rmobj(dirobj, errmsg) != 0)
+ ret_val = -1;
+ }
+
+ /* Close the directory */
+ closedir(dir);
+
+ /* If there were problems removing an entry, don't attempt to
+ remove the directory itself */
+ if (ret_val == -1)
+ return -1;
+
+ /* Get the link count, now that all the entries have been removed */
+ if (lstat(obj, &statbuf) < 0) {
+ if (errmsg != NULL) {
+ sprintf(err_msg, "lstat(%s) failed; errno=%d: %s",
+ obj, errno, SYSERR);
+ *errmsg = err_msg;
+ }
+ return -1;
+ }
+
+ /* Remove the directory itself */
+ if (statbuf.st_nlink >= 3) {
+ /* The directory is linked; unlink() must be used */
+ if (unlink(obj) < 0) {
+ if (errmsg != NULL) {
+ sprintf(err_msg, "unlink(%s) failed; errno=%d: %s",
+ obj, errno, SYSERR);
+ *errmsg = err_msg;
+ }
+ return -1;
+ }
+ } else {
+ /* The directory is not linked; remove() can be used */
+ if (remove(obj) < 0) {
+ if (errmsg != NULL) {
+ sprintf(err_msg, "remove(%s) failed; errno=%d: %s",
+ obj, errno, SYSERR);
+ *errmsg = err_msg;
+ }
+ return -1;
+ }
+ }
+ } else {
+ /* object is not a directory; just use unlink() */
+ if (unlink(obj) < 0) {
+ if (errmsg != NULL) {
+ sprintf(err_msg, "unlink(%s) failed; errno=%d: %s",
+ obj, errno, SYSERR);
+ *errmsg = err_msg;
+ }
+ return -1;
+ }
+ } /* if obj is a directory */
+
+ /*
+ * Everything must have went ok.
+ */
+ return 0;
+} /* rmobj() */ \ No newline at end of file
diff --git a/ltp_framework/lib/safe_macros.c b/ltp_framework/lib/safe_macros.c
new file mode 100644
index 0000000..11f5fe6
--- /dev/null
+++ b/ltp_framework/lib/safe_macros.c
@@ -0,0 +1,312 @@
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "test.h"
+#include "safe_macros.h"
+
+char *
+safe_basename(const char *file, const int lineno, void (*cleanup_fn)(void),
+ char *path)
+{
+ char *rval;
+
+ rval = basename(path);
+ if (rval == NULL)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "basename failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_chdir(const char *file, const int lineno, void (*cleanup_fn)(void),
+ const char *path)
+{
+ int rval;
+
+ rval = chdir(path);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "chdir failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_close(const char *file, const int lineno, void (*cleanup_fn)(void),
+ int fildes)
+{
+ int rval;
+
+ rval = close(fildes);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "close failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_creat(const char *file, const int lineno, void (*cleanup_fn)(void),
+ char *pathname, mode_t mode)
+{
+ int rval;
+
+ rval = creat(pathname, mode);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "pipe failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+char *
+safe_dirname(const char *file, const int lineno, void (*cleanup_fn)(void),
+ char *path)
+{
+ char *rval;
+
+ rval = dirname(path);
+ if (rval == NULL)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "dirname failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+char *
+safe_getcwd(const char *file, const int lineno, void (*cleanup_fn)(void),
+ char *buf, size_t size)
+{
+ char *rval;
+
+ rval = getcwd(buf, size);
+ if (rval == NULL)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "getcwd failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+struct passwd*
+safe_getpwnam(const char *file, const int lineno, void (*cleanup_fn)(void),
+ const char *name)
+{
+ struct passwd *rval;
+
+ rval = getpwnam(name);
+ if (rval == NULL)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "getpwnam failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_getrusage(const char *file, const int lineno, void (*cleanup_fn)(void),
+ int who, struct rusage *usage)
+{
+ int rval;
+
+ rval = getrusage(who, usage);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "getrusage failed at %s:%d",
+ file, lineno);
+
+ return rval;
+}
+
+void*
+safe_malloc(const char *file, const int lineno, void (*cleanup_fn)(void),
+ size_t size)
+{
+ void *rval;
+
+ rval = malloc(size);
+ if (rval == NULL)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "malloc failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_mkdir(const char *file, const int lineno, void (*cleanup_fn)(void),
+ const char *pathname, mode_t mode)
+{
+ int rval;
+
+ rval = mkdir(pathname, mode);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "mkdir failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+void*
+safe_mmap(const char *file, const int lineno, void (*cleanup_fn)(void),
+ void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ void *rval;
+
+ rval = mmap(addr, length, prot, flags, fd, offset);
+ if (rval == MAP_FAILED)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "mmap failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_munmap(const char *file, const int lineno, void (*cleanup_fn)(void),
+ void *addr, size_t length)
+{
+ int rval;
+
+ rval = munmap(addr, length);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "munmap failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_open(const char *file, const int lineno, void (*cleanup_fn)(void),
+ const char *pathname, int oflags, ...)
+{
+ va_list ap;
+ int rval;
+ mode_t mode;
+
+ va_start(ap, oflags);
+ mode = va_arg(ap, mode_t);
+ va_end(ap);
+
+ rval = open(pathname, oflags, mode);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "open failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_pipe(const char *file, const int lineno, void (*cleanup_fn)(void),
+ int fildes[2])
+{
+ int rval;
+
+ rval = pipe(fildes);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "pipe failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+ssize_t
+safe_read(const char *file, const int lineno, void (*cleanup_fn)(void),
+ char len_strict, int fildes, void *buf, size_t nbyte)
+{
+ ssize_t rval;
+
+ rval = read(fildes, buf, nbyte);
+ if ((len_strict == 0 && rval == -1) || rval != nbyte)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "read failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+ int
+safe_setegid(const char *file, const int lineno, void (*cleanup_fn)(void),
+ gid_t egid)
+{
+ int rval;
+
+ rval = setegid(egid);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "setegid failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_seteuid(const char *file, const int lineno, void (*cleanup_fn)(void),
+ uid_t euid)
+{
+ int rval;
+
+ rval = seteuid(euid);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "seteuid failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_setgid(const char *file, const int lineno, void (*cleanup_fn)(void),
+ gid_t gid)
+{
+ int rval;
+
+ rval = setgid(gid);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "setgid failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_setuid(const char *file, const int lineno, void (*cleanup_fn)(void),
+ uid_t uid)
+{
+ int rval;
+
+ rval = setuid(uid);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "setuid failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+int
+safe_unlink(const char *file, const int lineno, void (*cleanup_fn)(void),
+ const char *pathname)
+{
+ int rval;
+
+ rval = unlink(pathname);
+ if (rval == -1)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "unlink failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
+
+ssize_t
+safe_write(const char *file, const int lineno, void (cleanup_fn)(void),
+ char len_strict, int fildes, const void *buf, size_t nbyte)
+{
+ ssize_t rval;
+
+ rval = write(fildes, buf, nbyte);
+ if ((len_strict == 0 && rval == -1) || rval != nbyte)
+ tst_brkm(TBROK|TERRNO, cleanup_fn, "write failed at %s:%d",
+ file, lineno);
+
+ return (rval);
+}
diff --git a/ltp_framework/lib/search_path.c b/ltp_framework/lib/search_path.c
new file mode 100644
index 0000000..a9dff82
--- /dev/null
+++ b/ltp_framework/lib/search_path.c
@@ -0,0 +1,277 @@
+/* $Header: /cvsroot/ltp/ltp/lib/search_path.c,v 1.4 2009/07/20 10:59:32 vapier Exp $ */
+
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+
+/**********************************************************
+ *
+ * UNICOS Feature Test and Evaluation - Cray Research, Inc.
+ *
+ * FUNCTION NAME : search_path
+ *
+ * FUNCTION TITLE : search PATH locations for desired filename
+ *
+ * SYNOPSIS:
+ * int search_path(cmd, res_path, access_mode, fullpath)
+ * char *cmd;
+ * char *res_path;
+ * int access_mode;
+ * int fullpath;
+ *
+ * AUTHOR : Richard Logan
+ *
+ * INITIAL RELEASE : UNICOS 7.0
+ *
+ * DESCRIPTION
+ * Search_path will walk through PATH and attempt to find "cmd". If cmd is
+ * a full or relative path, it is checked but PATH locations are not scanned.
+ * search_path will put the resulting path in res_path. It is assumed
+ * that res_path points to a string that is at least PATH_MAX
+ * (or MAXPATHLEN on the suns) in size. Access_mode is just as is
+ * says, the mode to be used on access to determine if cmd can be found.
+ * If fullpath is set, res_path will contain the full path to cmd.
+ * If it is not set, res_path may or may not contain the full path to cmd.
+ * If fullpath is not set, the path in PATH prepended to cmd is used,
+ * which could be a relative path. If fullpath is set, the current
+ * directory is prepended to path/cmd before access is called.
+ * If cmd is found, search_path will return 0. If cmd cannot be
+ * found, 1 is returned. If an error has occurred, -1 is returned
+ * and an error mesg is placed in res_path.
+ * If the length of path/cmd is larger then PATH_MAX, then that path
+ * location is skipped.
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+
+struct stat stbuf;
+
+#ifndef AS_CMD
+#define AS_CMD 0
+#endif
+
+/*
+ * Make sure PATH_MAX is defined. Define it to MAXPATHLEN, if set. Otherwise
+ * set it to 1024.
+ */
+#ifndef PATH_MAX
+#ifndef MAXPATHLEN
+#define PATH_MAX 1024
+#else /* MAXPATHLEN */
+#define PATH_MAX MAXPATHLEN
+#endif /* MAXPATHLEN */
+#endif /* PATH_MAX */
+
+
+#if AS_CMD
+main(argc, argv)
+int argc;
+char **argv;
+{
+ char path[PATH_MAX];
+ int ind;
+
+ if (argc <= 1) {
+ printf("missing argument\n");
+ exit(1);
+ }
+
+ for (ind=1;ind < argc; ind++) {
+ if (search_path(argv[ind], path, F_OK, 0) < 0) {
+ printf("ERROR: %s\n", path);
+ }
+ else {
+ printf("path of %s is %s\n", argv[ind], path);
+ }
+ }
+
+}
+
+#endif
+
+/*
+ */
+int
+search_path(cmd, res_path, access_mode, fullpath)
+char *cmd; /* The requested filename */
+char *res_path; /* The resulting path or error mesg */
+int access_mode; /* the mode used by access(2) */
+int fullpath; /* if set, cwd will be prepended to all non-full paths */
+{
+ char *cp; /* used to scan PATH for directories */
+ int ret; /* return value from access */
+ char *pathenv;
+ char tmppath[PATH_MAX];
+ char curpath[PATH_MAX];
+ char *path;
+ int lastpath;
+ int toolong=0;
+
+#if DEBUG
+printf("search_path: cmd = %s, access_mode = %d, fullpath = %d\n", cmd, access_mode, fullpath);
+#endif
+
+ /*
+ * full or relative path was given
+ */
+ if ((cmd[0] == '/') || ( (cp=strchr(cmd, '/')) != NULL )) {
+ if (access(cmd, access_mode) == 0) {
+
+ if (cmd[0] != '/') { /* relative path */
+ if (getcwd(curpath, PATH_MAX) == NULL) {
+ strcpy(res_path, curpath);
+ return -1;
+ }
+ if ((strlen(curpath) + strlen(cmd) + 1) > (size_t)PATH_MAX) {
+ sprintf(res_path, "cmd (as relative path) and cwd is longer than %d",
+ PATH_MAX);
+ return -1;
+ }
+ sprintf(res_path, "%s/%s", curpath, cmd);
+ }
+ else
+ strcpy(res_path, cmd);
+ return 0;
+ }
+ else {
+ sprintf(res_path, "file %s not found", cmd);
+ return -1;
+ }
+ }
+
+ /* get the PATH variable */
+ if ((pathenv=getenv("PATH")) == NULL) {
+ /* no path to scan, return */
+ sprintf(res_path, "Unable to get PATH env. variable");
+ return -1;
+ }
+
+ /*
+ * walk through each path in PATH.
+ * Each path in PATH is placed in tmppath.
+ * pathenv cannot be modified since it will affect PATH.
+ * If a signal came in while we have modified the PATH
+ * memory, we could create a problem for the caller.
+ */
+
+ curpath[0]='\0';
+
+ cp = pathenv;
+ path = pathenv;
+ lastpath = 0;
+ for (;;) {
+
+ if (lastpath)
+ break;
+
+ if (cp != pathenv)
+ path = ++cp; /* already set on first iteration */
+
+ /* find end of current path */
+
+ for (; ((*cp != ':') && (*cp != '\0')); cp++);
+
+ /*
+ * copy path to tmppath so it can be NULL terminated
+ * and so we do not modify path memory.
+ */
+ strncpy(tmppath, path, (cp-path) );
+ tmppath[cp-path]='\0';
+#if DEBUG
+printf("search_path: tmppath = %s\n", tmppath);
+#endif
+
+ if (*cp == '\0')
+ lastpath=1; /* this is the last path entry */
+
+ /* Check lengths so not to overflow res_path */
+ if (strlen(tmppath) + strlen(cmd) + 2 > (size_t)PATH_MAX) {
+ toolong++;
+ continue;
+ }
+
+ sprintf(res_path, "%s/%s", tmppath, cmd);
+#if DEBUG
+printf("search_path: res_path = '%s'\n", res_path);
+#endif
+
+
+ /* if the path is not full at this point, prepend the current
+ * path to get the full path.
+ * Note: this could not be wise to do when under a protected
+ * directory.
+ */
+
+ if (fullpath && res_path[0] != '/') { /* not a full path */
+ if (curpath[0] == '\0') {
+ if (getcwd(curpath, PATH_MAX) == NULL) {
+ strcpy(res_path, curpath);
+ return -1;
+ }
+ }
+ if ((strlen(curpath) + strlen(res_path) + 2) > (size_t)PATH_MAX) {
+ toolong++;
+ continue;
+ }
+ sprintf(tmppath, "%s/%s", curpath, res_path);
+ strcpy(res_path, tmppath);
+#if DEBUG
+printf("search_path: full res_path= '%s'\n", res_path);
+#endif
+
+ }
+
+
+ if ((ret=access(res_path, access_mode)) == 0) {
+#if DEBUG
+printf("search_path: found res_path = %s\n", res_path);
+#endif
+ return 0;
+ }
+ }
+
+ /* return failure */
+ if (toolong)
+ sprintf(res_path,
+ "Unable to find file, %d path/file strings were too long", toolong);
+ else
+ strcpy(res_path, "Unable to find file");
+ return 1; /* not found */
+}
diff --git a/ltp_framework/lib/self_exec.c b/ltp_framework/lib/self_exec.c
new file mode 100644
index 0000000..a457468
--- /dev/null
+++ b/ltp_framework/lib/self_exec.c
@@ -0,0 +1,218 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: t -*- */
+/*
+ * self_exec.c: self_exec magic required to run child functions on uClinux
+ *
+ * Copyright (C) 2005 Paul J.Y. Lahaie <pjlahaie-at-steamballoon.com>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * This software was produced by Steamballoon Incorporated
+ * 55 Byward Market Square, 2nd Floor North, Ottawa, ON K1N 9C3, Canada
+ */
+
+#define _GNU_SOURCE /* for asprintf */
+
+#include "config.h"
+
+#ifdef UCLINUX
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include "test.h"
+
+/* Set from parse_opts.c: */
+char *child_args; /* Arguments to child when -C is used */
+
+static char *start_cwd; /* Stores the starting directory for self_exec */
+
+int asprintf(char **app, const char *fmt, ...)
+{
+ va_list ptr;
+ int rv;
+ char *p;
+
+ /*
+ * First iteration - find out size of buffer required and allocate it.
+ */
+ va_start(ptr, fmt);
+ rv = vsnprintf(NULL, 0, fmt, ptr);
+ va_end(ptr);
+
+ p = malloc(++rv); /* allocate the buffer */
+ *app = p;
+ if (!p) {
+ return -1;
+ }
+
+ /*
+ * Second iteration - actually produce output.
+ */
+ va_start(ptr, fmt);
+ rv = vsnprintf(p, rv, fmt, ptr);
+ va_end(ptr);
+
+ return rv;
+}
+
+void
+maybe_run_child(void (*child)(), char *fmt, ...)
+{
+ va_list ap;
+ char *child_dir;
+ char *p, *tok;
+ int *iptr, i, j;
+ char *s;
+ char **sptr;
+ char *endptr;
+
+ /* Store the current directory for later use. */
+ start_cwd = getcwd(NULL, 0);
+
+ if (child_args) {
+ char *args = strdup(child_args);
+
+ child_dir = strtok(args, ",");
+ if (strlen(child_dir) == 0) {
+ tst_resm(TBROK, NULL, "Could not get directory from -C option");
+ tst_exit();
+ }
+
+ va_start(ap, fmt);
+
+ for (p = fmt; *p; p++) {
+ tok = strtok(NULL, ",");
+ if (!tok || strlen(tok) == 0) {
+ tst_resm(TBROK, "Invalid argument to -C option");
+ tst_exit();
+ }
+
+ switch (*p) {
+ case 'd':
+ iptr = va_arg(ap, int *);
+ i = strtol(tok, &endptr, 10);
+ if (*endptr != '\0') {
+ tst_resm(TBROK, "Invalid argument to -C option");
+ tst_exit();
+ }
+ *iptr = i;
+ break;
+ case 'n':
+ j = va_arg(ap, int);
+ i = strtol(tok, &endptr, 10);
+ if (*endptr != '\0') {
+ tst_resm(TBROK, "Invalid argument to -C option");
+ tst_exit();
+ }
+ if (j != i) {
+ va_end(ap);
+ return;
+ }
+ break;
+ case 's':
+ s = va_arg(ap, char *);
+ if (!strncpy(s, tok, strlen(tok)+1)) {
+ tst_resm(TBROK, "Could not strncpy for -C option");
+ tst_exit();
+ }
+ break;
+ case 'S':
+ sptr = va_arg(ap, char **);
+ *sptr = strdup(tok);
+ if (!*sptr) {
+ tst_resm(TBROK, "Could not strdup for -C option");
+ tst_exit();
+ }
+ break;
+ default:
+ tst_resm(TBROK, "Format string option %c not implemented", *p);
+ tst_exit();
+ break;
+ }
+ }
+
+ va_end(ap);
+
+ if (chdir(child_dir) < 0) {
+ tst_resm(TBROK, "Could not change to %s for child", child_dir);
+ tst_exit();
+ }
+
+ (*child)();
+ tst_resm(TWARN, "Child function returned unexpectedly");
+ /* Exit here? or exit silently? */
+ }
+}
+
+int
+self_exec(char *argv0, char *fmt, ...)
+{
+ va_list ap;
+ char *p;
+ char *tmp_cwd;
+ char *arg;
+ int ival;
+ char *str;
+
+ if ((tmp_cwd = getcwd(NULL, 0)) == NULL) {
+ tst_resm(TBROK, "Could not getcwd()");
+ return -1;
+ }
+
+ arg = strdup( tmp_cwd );
+
+ if (( arg = strdup( tmp_cwd )) == NULL) {
+ tst_resm(TBROK, "Could not produce self_exec string");
+ return -1;
+ }
+
+ va_start(ap, fmt);
+
+ for (p = fmt; *p; p++) {
+ switch (*p) {
+ case 'd':
+ case 'n':
+ ival = va_arg(ap, int);
+ if (asprintf(&arg, "%s,%d", arg, ival) < 0) {
+ tst_resm(TBROK, "Could not produce self_exec string");
+ return -1;
+ }
+ break;
+ case 's':
+ case 'S':
+ str = va_arg(ap, char *);
+ if (asprintf(&arg, "%s,%s", arg, str) < 0) {
+ tst_resm(TBROK, "Could not produce self_exec string");
+ return -1;
+ }
+ break;
+ default:
+ tst_resm(TBROK, "Format string option %c not implemented", *p);
+ return -1;
+ break;
+ }
+ }
+
+ va_end(ap);
+
+ if (chdir(start_cwd) < 0) {
+ tst_resm(TBROK, "Could not change to %s for self_exec", start_cwd);
+ return -1;
+ }
+
+ return execlp(argv0, argv0, "-C", arg, (char *) NULL);
+}
+
+#endif /* UCLINUX */ \ No newline at end of file
diff --git a/ltp_framework/lib/str_to_bytes.c b/ltp_framework/lib/str_to_bytes.c
new file mode 100644
index 0000000..26e4897
--- /dev/null
+++ b/ltp_framework/lib/str_to_bytes.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+#include <stdio.h>
+#include <sys/param.h>
+#include "str_to_bytes.h"
+
+/****************************************************************************
+ * str_to_bytes(s)
+ *
+ * Computes the number of bytes described by string s. s is assumed to be
+ * a base 10 positive (ie. >= 0) number followed by an optional single
+ * character multiplier. The following multipliers are supported:
+ *
+ * char mult
+ * -----------------
+ * b BSIZE or BBSIZE
+ * k 1024 bytes
+ * K 1024 * sizeof(long)
+ * m 2^20 (1048576)
+ * M 2^20 (1048576 * sizeof(long)
+ * g 2^30 (1073741824)
+ * G 2^30 (1073741824) * sizeof(long)
+ *
+ * for instance, "1k" and "1024" would both cause str_to_bytes to return 1024.
+ *
+ * Returns -1 if mult is an invalid character, or if the integer portion of
+ * s is not a positive integer.
+ *
+ ****************************************************************************/
+
+#if CRAY
+#define B_MULT BSIZE /* block size */
+#elif sgi
+#define B_MULT BBSIZE /* block size */
+#elif defined(__linux__) || defined(__sun) || defined(__hpux)
+#define B_MULT DEV_BSIZE /* block size */
+#elif defined(_AIX)
+#define B_MULT UBSIZE
+#endif
+
+
+#define K_MULT 1024 /* Kilo or 2^10 */
+#define M_MULT 1048576 /* Mega or 2^20 */
+#define G_MULT 1073741824 /* Giga or 2^30 */
+#define T_MULT 1099511627776 /* tera or 2^40 */
+
+int
+str_to_bytes(s)
+char *s;
+{
+ char mult, junk;
+ int nconv;
+ float num;
+
+ nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
+ if (nconv == 0 || nconv == 3)
+ return -1;
+
+ if (nconv == 1)
+ return num;
+
+ switch (mult) {
+ case 'b':
+ return (int)(num * (float)B_MULT);
+ case 'k':
+ return (int)(num * (float)K_MULT);
+ case 'K':
+ return (int)((num * (float)K_MULT) * sizeof(long));
+ case 'm':
+ return (int)(num * (float)M_MULT);
+ case 'M':
+ return (int)((num * (float)M_MULT) * sizeof(long));
+ case 'g':
+ return (int)(num * (float)G_MULT);
+ case 'G':
+ return (int)((num * (float)G_MULT) * sizeof(long));
+ default:
+ return -1;
+ }
+}
+
+long
+str_to_lbytes(s)
+char *s;
+{
+ char mult, junk;
+ long nconv;
+ float num;
+
+ nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
+ if (nconv == 0 || nconv == 3)
+ return -1;
+
+ if (nconv == 1)
+ return (long)num;
+
+ switch (mult) {
+ case 'b':
+ return (long)(num * (float)B_MULT);
+ case 'k':
+ return (long)(num * (float)K_MULT);
+ case 'K':
+ return (long)((num * (float)K_MULT) * sizeof(long));
+ case 'm':
+ return (long)(num * (float)M_MULT);
+ case 'M':
+ return (long)((num * (float)M_MULT) * sizeof(long));
+ case 'g':
+ return (long)(num * (float)G_MULT);
+ case 'G':
+ return (long)((num * (float)G_MULT) * sizeof(long));
+ default:
+ return -1;
+ }
+}
+
+/*
+ * Force 64 bits number when compiled as 32 IRIX binary.
+ * This allows for a number bigger than 2G.
+ */
+
+long long
+str_to_llbytes(s)
+char *s;
+{
+ char mult, junk;
+ long nconv;
+ double num;
+
+ nconv = sscanf(s, "%lf%c%c", &num, &mult, &junk);
+ if (nconv == 0 || nconv == 3)
+ return -1;
+
+ if (nconv == 1)
+ return (long long)num;
+
+ switch (mult) {
+ case 'b':
+ return (long long)(num * (float)B_MULT);
+ case 'k':
+ return (long long)(num * (float)K_MULT);
+ case 'K':
+ return (long long)((num * (float)K_MULT) * sizeof(long long));
+ case 'm':
+ return (long long)(num * (float)M_MULT);
+ case 'M':
+ return (long long)((num * (float)M_MULT) * sizeof(long long));
+ case 'g':
+ return (long long)(num * (float)G_MULT);
+ case 'G':
+ return (long long)((num * (float)G_MULT) * sizeof(long long));
+ default:
+ return -1;
+ }
+}
+
+#ifdef UNIT_TEST
+
+main(int argc, char **argv)
+{
+ int ind;
+
+ if (argc == 1) {
+ fprintf(stderr, "missing str_to_bytes() parameteres\n");
+ exit(1);
+ }
+
+ for (ind=1; ind<argc; ind++) {
+
+ printf("str_to_bytes(%s) returned %d\n",
+ argv[ind], str_to_bytes(argv[ind]));
+
+ printf("str_to_lbytes(%s) returned %ld\n",
+ argv[ind], str_to_lbytes(argv[ind]));
+
+ printf("str_to_llbytes(%s) returned %lld\n",
+ argv[ind], str_to_llbytes(argv[ind]));
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/ltp_framework/lib/string_to_tokens.c b/ltp_framework/lib/string_to_tokens.c
new file mode 100644
index 0000000..5bbd8e3
--- /dev/null
+++ b/ltp_framework/lib/string_to_tokens.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+/**********************************************************
+ *
+ * OS Testing - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME : string_to_tokens
+ *
+ * FUNCTION TITLE : Break a string into its tokens
+ *
+ * SYNOPSIS:
+ *
+ * int string_to_tokens(arg_string, arg_array, array_size, separator)
+ * char *arg_string;
+ * char *arg_array[];
+ * int array_size;
+ * char *separator;
+ *
+ * AUTHOR : Richard Logan
+ *
+ * DATE : 10/94
+ *
+ * INITIAL RELEASE : UNICOS 7.0
+ *
+ * DESCRIPTION
+ * This function parses the string 'arg_string', placing pointers to
+ * the 'separator' separated tokens into the elements of 'arg_array'.
+ * The array is terminated with a null pointer.
+ * 'arg_array' must contains at least 'array_size' elements.
+ * Only the first 'array_size' minus one tokens will be placed into
+ * 'arg_array'. If there are more than 'array_size'-1 tokens, the rest are
+ * ignored by this routine.
+ *
+ * RETURN VALUE
+ * This function returns the number of 'separator' separated tokens that
+ * were found in 'arg_string'.
+ * If 'arg_array' or 'separator' is NULL or 'array_size' is less than 2, -1 is returned.
+ *
+ * WARNING
+ * This function uses strtok() to parse 'arg_string', and thus
+ * physically alters 'arg_string' by placing null characters where the
+ * separators originally were.
+ *
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+#include <stdio.h>
+#include <string.h> /* for string functions */
+#include "string_to_tokens.h"
+
+int
+string_to_tokens(char *arg_string, char *arg_array[], int array_size, char *separator)
+{
+ int num_toks = 0; /* number of tokens found */
+ char *strtok();
+
+ if (arg_array == NULL || array_size <= 1 || separator == NULL)
+ return -1;
+
+ /*
+ * Use strtok() to parse 'arg_string', placing pointers to the
+ * individual tokens into the elements of 'arg_array'.
+ */
+ if ((arg_array[num_toks] = strtok(arg_string, separator)) == NULL) {
+ return 0;
+ }
+
+ for (num_toks=1;num_toks<array_size; num_toks++) {
+ if ((arg_array[num_toks] = strtok(NULL, separator)) == NULL)
+ break;
+ }
+
+ if (num_toks == array_size)
+ arg_array[num_toks] = NULL;
+
+ /*
+ * Return the number of tokens that were found in 'arg_string'.
+ */
+ return(num_toks);
+
+} /* end of string_to_tokens */ \ No newline at end of file
diff --git a/ltp_framework/lib/system_specific_hugepages_info.c b/ltp_framework/lib/system_specific_hugepages_info.c
new file mode 100644
index 0000000..2344add
--- /dev/null
+++ b/ltp_framework/lib/system_specific_hugepages_info.c
@@ -0,0 +1,93 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2009
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * DESCRIPTION
+ * get_no_of_hugepages() --> Return No. of hugepages for this systems
+ * from /proc/meminfo
+ * hugepages_size() --> Return Hugepages Size for this system
+ * from /proc/meminfo
+ */
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <test.h>
+
+int get_no_of_hugepages() {
+ #ifdef __linux__
+ FILE *f;
+ char buf[BUFSIZ];
+
+ f = popen("grep 'HugePages_Total' /proc/meminfo | cut -d ':' -f2 | tr -d ' \n'", "r");
+ if (!f)
+ tst_brkm(TBROK, NULL,
+ "Could not get info about Total_Hugepages from /proc/meminfo");
+ if (!fgets(buf, 10, f)) {
+ fclose(f);
+ tst_brkm(TBROK, NULL,
+ "Could not read Total_Hugepages from /proc/meminfo");
+ }
+ pclose(f);
+ return(atoi(buf));
+ #else
+ return -1;
+ #endif
+}
+
+int get_no_of_free_hugepages() {
+ #ifdef __linux__
+ FILE *f;
+ char buf[BUFSIZ];
+
+ f = popen("grep 'HugePages_Free' /proc/meminfo | cut -d ':' -f2 | tr -d ' \n'", "r");
+ if (!f)
+ tst_brkm(TBROK, NULL,
+ "Could not get info about HugePages_Free from /proc/meminfo");
+ if (!fgets(buf, 10, f)) {
+ fclose(f);
+ tst_brkm(TBROK, NULL,
+ "Could not read HugePages_Free from /proc/meminfo");
+ }
+ pclose(f);
+ return(atoi(buf));
+ #else
+ return -1;
+ #endif
+}
+
+int hugepages_size() {
+ #ifdef __linux__
+ FILE *f;
+ char buf[BUFSIZ];
+
+ f = popen("grep 'Hugepagesize' /proc/meminfo | cut -d ':' -f2 | tr -d 'kB \n'", "r");
+ if (!f)
+ tst_brkm(TBROK, NULL,
+ "Could not get info about HugePages_Size from /proc/meminfo");
+ if (!fgets(buf, 10, f)) {
+ fclose(f);
+ tst_brkm(TBROK, NULL,
+ "Could not read HugePages_Size from /proc/meminfo");
+ }
+ pclose(f);
+ return(atoi(buf));
+ #else
+ return -1;
+ #endif
+}
diff --git a/ltp_framework/lib/system_specific_process_info.c b/ltp_framework/lib/system_specific_process_info.c
new file mode 100644
index 0000000..d3c9638
--- /dev/null
+++ b/ltp_framework/lib/system_specific_process_info.c
@@ -0,0 +1,88 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2009
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * DESCRIPTION
+ * get_max_pids(): Return the maximum number of pids for this system by
+ * reading /proc/sys/kernel/pid_max
+ *
+ * get_free_pids(): Return number of free pids by subtracting the number
+ * of pids currently used ('ps -eT') from max_pids
+ */
+
+
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/types.h>
+#include "test.h"
+
+#define BUFSIZE 512
+
+int get_max_pids(void)
+{
+#ifdef __linux__
+
+ FILE *f;
+ char buf[BUFSIZE];
+
+ f = fopen("/proc/sys/kernel/pid_max", "r");
+ if (!f) {
+ tst_resm(TBROK, "Could not open /proc/sys/kernel/pid_max");
+ return -1;
+ }
+ if (!fgets(buf, BUFSIZE, f)) {
+ fclose(f);
+ tst_resm(TBROK, "Could not read /proc/sys/kernel/pid_max");
+ return -1;
+ }
+ fclose(f);
+ return atoi(buf);
+#else
+ return SHRT_MAX;
+#endif
+}
+
+
+int get_free_pids(void)
+{
+ FILE *f;
+ int rc, used_pids, max_pids;
+
+ f = popen("ps -eT | wc -l", "r");
+ if (!f) {
+ tst_resm(TBROK, "Could not run 'ps' to calculate used "
+ "pids");
+ return -1;
+ }
+ rc = fscanf(f, "%i", &used_pids);
+ pclose(f);
+
+ if (rc != 1 || used_pids < 0) {
+ tst_resm(TBROK, "Could not read output of 'ps' to "
+ "calculate used pids");
+ return -1;
+ }
+
+ max_pids = get_max_pids();
+
+ if (max_pids < 0)
+ return -1;
+
+ return max_pids - used_pids;
+}
diff --git a/ltp_framework/lib/tlibio.c b/ltp_framework/lib/tlibio.c
new file mode 100644
index 0000000..eaaaaa0
--- /dev/null
+++ b/ltp_framework/lib/tlibio.c
@@ -0,0 +1,2084 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+/*
+ *
+ * Lib i/o
+ *
+ * This file contains several functions to doing reads and writes.
+ * It was written so that a single function could be called in a test
+ * program and only a io type field value would have to change to
+ * do different types of io. There is even a couple of functions that
+ * will allow you to parse a string to determine the iotype.
+ *
+ * This file contains functions for writing/reading to/from open files
+ * Prototypes:
+ *
+ * Functions declared in this module - see individual function code for
+ * usage comments:
+ *
+ * int stride_bounds(int offset, int stride, int nstrides,
+ * int bytes_per_stride, int *min, int *max);
+
+ * int lio_write_buffer(int fd, int method, char *buffer, int size,
+ * char **errmsg, long wrd);
+ * int lio_read_buffer(int fd, int method, char *buffer, int size,
+ * char **errmsg, long wrd);
+ *
+ * #ifdef CRAY
+ * int lio_wait4asyncio(int method, int fd, struct iosw **statptr)
+ * int lio_check_asyncio(char *io_type, int size, struct iosw *status)
+ * #endif
+ * #ifdef sgi
+ * int lio_wait4asyncio(int method, int fd, aiocb_t *aiocbp)
+ * int lio_check_asyncio(char *io_type, int size, aiocb_t *aiocbp, int method)
+ * #endif
+ *
+ * int lio_parse_io_arg1(char *string)
+ * void lio_help1(char *prefix);
+ *
+ * int lio_parse_io_arg2(char *string, char **badtoken)
+ * void lio_help2(char *prefix);
+ *
+ * int lio_set_debug(int level);
+ *
+ * char Lio_SysCall[];
+ * struct lio_info_type Lio_info1[];
+ * struct lio_info_type Lio_info2[];
+ *
+ * Author : Richard Logan
+ *
+ */
+
+#ifdef __linux__
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#define _LARGEFILE64_SOURCE
+#endif
+#include "config.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <signal.h>
+#include <stdint.h>
+#ifdef CRAY
+#include <sys/secparm.h>
+#include <sys/iosw.h>
+#include <sys/listio.h>
+#else
+/* for linux or sgi */
+#include <sys/uio.h> /* readv(2)/writev(2) */
+#include <string.h> /* bzero */
+#endif
+#if defined(__linux__) || defined(__sun) || defined(__hpux) || defined(_AIX)
+#if !defined(UCLINUX) && !defined(__UCLIBC__)
+#include <aio.h>
+#endif
+#endif
+#include <stdlib.h> /* atoi, abs */
+
+#include "tlibio.h" /* defines LIO* marcos */
+#include "random_range.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX MAXPATHLEN
+#endif
+
+#if 0 /* disabled until it's needed -- roehrich 6/11/97 */
+#define BUG1_workaround 1 /* Work around a condition where aio_return gives
+ * a value of zero but there is no errno followup
+ * and the read/write operation actually did its
+ * job. spr/pv 705244
+ */
+#endif
+
+
+static void lio_async_signal_handler();
+#ifdef sgi
+static void lio_async_callback_handler();
+#endif
+
+/*
+ * Define the structure as used in lio_parse_arg1 and lio_help1
+ */
+struct lio_info_type Lio_info1[] = {
+ { "s", LIO_IO_SYNC, "sync i/o" },
+ { "p", LIO_IO_ASYNC|LIO_WAIT_SIGACTIVE, "async i/o using a loop to wait for a signal" },
+ { "b", LIO_IO_ASYNC|LIO_WAIT_SIGPAUSE, "async i/o using pause" },
+ { "a", LIO_IO_ASYNC|LIO_WAIT_RECALL, "async i/o using recall/aio_suspend" },
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ { "r",
+ LIO_RANDOM|LIO_IO_TYPES|LIO_WAIT_TYPES, "random sync i/o types and wait methods" },
+ { "R",
+ LIO_RANDOM|LIO_IO_ATYPES|LIO_WAIT_ATYPES, "random i/o types and wait methods" },
+#else
+ { "r",
+ LIO_RANDOM|LIO_IO_TYPES|LIO_WAIT_TYPES, "random i/o types and wait methods" },
+ { "R",
+ LIO_RANDOM|LIO_IO_TYPES|LIO_WAIT_TYPES, "random i/o types and wait methods" },
+#endif
+ { "l", LIO_IO_SLISTIO|LIO_WAIT_RECALL, "single stride sync listio" },
+ { "L", LIO_IO_ALISTIO|LIO_WAIT_RECALL, "single stride async listio using recall" },
+ { "X", LIO_IO_ALISTIO|LIO_WAIT_SIGPAUSE, "single stride async listio using pause" },
+ { "v", LIO_IO_SYNCV, "single buffer sync readv/writev" },
+ { "P", LIO_IO_SYNCP, "sync pread/pwrite" },
+};
+
+/*
+ * Define the structure used by lio_parse_arg2 and lio_help2
+ */
+struct lio_info_type Lio_info2[] = {
+ { "sync", LIO_IO_SYNC, "sync i/o (read/write)"},
+ { "async", LIO_IO_ASYNC, "async i/o (reada/writea/aio_read/aio_write)" },
+ { "slistio", LIO_IO_SLISTIO, "single stride sync listio" },
+ { "alistio", LIO_IO_ALISTIO, "single stride async listio" },
+ { "syncv", LIO_IO_SYNCV, "single buffer sync readv/writev"},
+ { "syncp", LIO_IO_SYNCP, "pread/pwrite"},
+ { "active", LIO_WAIT_ACTIVE, "spin on status/control values" },
+ { "recall", LIO_WAIT_RECALL, "use recall(2)/aio_suspend(3) to wait for i/o to complete" },
+ { "sigactive", LIO_WAIT_SIGACTIVE, "spin waiting for signal" },
+ { "sigpause", LIO_WAIT_SIGPAUSE, "call pause(2) to wait for signal" },
+/* nowait is a touchy thing, it's an accident that this implementation worked at all. 6/27/97 roehrich */
+/* { "nowait", LIO_WAIT_NONE, "do not wait for async io to complete" },*/
+ { "random", LIO_RANDOM, "set random bit" },
+ { "randomall",
+ LIO_RANDOM|LIO_IO_TYPES|LIO_WAIT_TYPES,
+ "all random i/o types and wait methods (except nowait)" },
+};
+
+char Lio_SysCall[PATH_MAX]; /* string containing last i/o system call */
+
+static volatile int Received_signal = 0; /* number of signals received */
+static volatile int Rec_signal;
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+static volatile int Received_callback = 0; /* number of callbacks received */
+static volatile int Rec_callback;
+#endif
+static char Errormsg[500];
+static int Debug_level = 0;
+
+
+
+/***********************************************************************
+ * stride_bounds()
+ *
+ * Determine the bounds of a strided request, normalized to offset. Returns
+ * the number of bytes needed to satisfy the request, and optionally sets
+ * *min and *max to the mininum and maximum bytes referenced, normalized
+ * around offset.
+ *
+ * Returns -1 on error - the only possible error conditions are illegal values
+ * for nstrides and/or bytes_per_stride - both parameters must be >= 0.
+ *
+ * (maule, 11/16/95)
+ ***********************************************************************/
+
+int
+stride_bounds(offset, stride, nstrides, bytes_per_stride, min, max)
+int offset;
+int stride;
+int nstrides;
+int bytes_per_stride;
+int *min;
+int *max;
+{
+ int nbytes, min_byte, max_byte;
+
+ /*
+ * sanity checks ...
+ */
+
+ if (nstrides < 0 || bytes_per_stride < 0) {
+ return -1;
+ }
+
+ if (stride == 0) {
+ stride = bytes_per_stride;
+ }
+
+ /*
+ * Determine the # of bytes needed to satisfy the request. This
+ * value, along with the offset argument, determines the min and max
+ * bytes referenced.
+ */
+
+
+ nbytes = abs(stride) * (nstrides-1) + bytes_per_stride;
+
+ if (stride < 0) {
+ max_byte = offset + bytes_per_stride - 1;
+ min_byte = max_byte - nbytes + 1;
+ } else {
+ min_byte = offset;
+ max_byte = min_byte + nbytes - 1;
+ }
+
+ if (min != NULL) {
+ *min = min_byte;
+ }
+
+ if (max != NULL) {
+ *max = max_byte;
+ }
+
+ return nbytes;
+}
+
+/***********************************************************************
+ * This function will allow someone to set the debug level.
+ ***********************************************************************/
+int
+lio_set_debug(level)
+{
+ int old;
+
+ old = Debug_level;
+ Debug_level = level;
+ return old;
+}
+
+/***********************************************************************
+ * This function will parse a string and return desired io-method.
+ * Only the first character of the string is used.
+ *
+ * This function does not provide for meaningful option arguments,
+ * but it supports current growfiles/btlk interface.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+int
+lio_parse_io_arg1(char *string)
+{
+ unsigned int ind;
+ int found=0;
+ int mask=0;
+
+ /*
+ * Determine if token is a valid string.
+ */
+ for (ind=0; ind<sizeof(Lio_info1)/sizeof(struct lio_info_type); ind++) {
+ if (strcmp(string, Lio_info1[ind].token) == 0) {
+ mask |= Lio_info1[ind].bits;
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ return -1;
+ }
+
+ return mask;
+
+}
+
+/***********************************************************************
+ * This function will print a help message describing the characters
+ * that can be parsed by lio_parse_io_arg1().
+ * They will be printed one per line.
+ * (rrl 04/96)
+ ***********************************************************************/
+void
+lio_help1(char *prefix)
+{
+ unsigned int ind;
+
+ for (ind=0; ind<sizeof(Lio_info1)/sizeof(struct lio_info_type); ind++) {
+ printf("%s %s : %s\n", prefix,
+ Lio_info1[ind].token, Lio_info1[ind].desc);
+ }
+
+ return;
+}
+
+/***********************************************************************
+ * This function will parse a string and return the desired io-method.
+ * This function will take a comma separated list of io type and wait
+ * method tokens as defined in Lio_info2[]. If a token does not match
+ * any of the tokens in Lio_info2[], it will be coverted to a number.
+ * If it was a number, those bits are also set.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+int
+lio_parse_io_arg2(char *string, char **badtoken)
+{
+ char *token = string;
+ char *cc = token;
+ char savecc;
+ int found;
+ int mask=0;
+
+ int tmp;
+ unsigned int ind;
+ char chr;
+
+ if (token == NULL)
+ return -1;
+
+ for (;;) {
+ for (; ((*cc != ',') && (*cc != '\0')); cc++);
+ savecc = *cc;
+ *cc = '\0';
+
+ found = 0;
+
+ /*
+ * Determine if token is a valid string or number and if
+ * so, add the bits to the mask.
+ */
+ for (ind=0; ind<sizeof(Lio_info2)/sizeof(struct lio_info_type); ind++) {
+ if (strcmp(token, Lio_info2[ind].token) == 0) {
+ mask |= Lio_info2[ind].bits;
+ found = 1;
+ break;
+ }
+ }
+
+ /*
+ * If token does not match one of the defined tokens, determine
+ * if it is a number, if so, add the bits.
+ */
+ if (!found) {
+ if (sscanf(token, "%i%c", &tmp, &chr) == 1) {
+ mask |= tmp;
+ found=1;
+ }
+ }
+
+ *cc = savecc;
+
+ if (!found) { /* token is not valid */
+ if (badtoken != NULL)
+ *badtoken = token;
+ return(-1);
+ }
+
+ if (savecc == '\0')
+ break;
+
+ token = ++cc;
+ }
+
+ return mask;
+}
+
+/***********************************************************************
+ * This function will print a help message describing the tokens
+ * that can be parsed by lio_parse_io_arg2().
+ * It will print them one per line.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+void
+lio_help2(char *prefix)
+{
+ unsigned int ind;
+
+ for (ind=0; ind<sizeof(Lio_info2)/sizeof(struct lio_info_type); ind++) {
+ printf("%s %s : %s\n", prefix,
+ Lio_info2[ind].token, Lio_info2[ind].desc);
+ }
+ return;
+}
+
+/***********************************************************************
+ * This is an internal signal handler.
+ * If the handler is called, it will increment the Received_signal
+ * global variable.
+ ***********************************************************************/
+static void
+lio_async_signal_handler(int sig)
+{
+ if (Debug_level)
+ printf("DEBUG %s/%d: received signal %d, a signal caught %d times\n",
+ __FILE__, __LINE__, sig, Received_signal+1);
+
+ Received_signal++;
+
+ return;
+}
+
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+/***********************************************************************
+ * This is an internal callback handler.
+ * If the handler is called, it will increment the Received_callback
+ * global variable.
+ ***********************************************************************/
+static void
+lio_async_callback_handler(sigval_t sigval)
+{
+ if (Debug_level)
+ printf("DEBUG %s/%d: received callback, nbytes=%ld, a callback called %d times\n",
+ __FILE__, __LINE__, (long)sigval.sival_int, Received_callback+1);
+
+ Received_callback++;
+
+ return;
+}
+#endif /* sgi */
+
+/***********************************************************************
+ * lio_random_methods
+ * This function will randomly choose an io type and wait method
+ * from set of io types and wait methods. Since this information
+ * is stored in a bitmask, it randomly chooses an io type from
+ * the io type bits specified and does the same for wait methods.
+ *
+ * Return Value
+ * This function will return a value with all non choosen io type
+ * and wait method bits cleared. The LIO_RANDOM bit is also
+ * cleared. All other bits are left unchanged.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+int
+lio_random_methods(long curr_mask)
+{
+ int mask=0;
+
+ /* remove random select, io type, and wait method bits from curr_mask */
+ mask = curr_mask & (~(LIO_IO_TYPES | LIO_WAIT_TYPES | LIO_RANDOM));
+
+ /* randomly select io type from specified io types */
+ mask = mask | random_bit(curr_mask & LIO_IO_TYPES);
+
+ /* randomly select wait methods from specified wait methods */
+ mask = mask | random_bit(curr_mask & LIO_WAIT_TYPES);
+
+ return mask;
+}
+
+static void wait4sync_io(int fd, int read)
+{
+ fd_set s;
+ FD_ZERO(&s);
+ FD_SET(fd, &s);
+
+ select(fd+1, read ? &s : NULL, read ? NULL : &s, NULL, NULL);
+}
+
+/***********************************************************************
+ * Generic write function
+ * This function can be used to do a write using write(2), writea(2),
+ * aio_write(3), writev(2), pwrite(2),
+ * or single stride listio(2)/lio_listio(3).
+ * By setting the desired bits in the method
+ * bitmask, the caller can control the type of write and the wait method
+ * that will be used. If no io type bits are set, write will be used.
+ *
+ * If async io was attempted and no wait method bits are set then the
+ * wait method is: recall(2) for writea(2) and listio(2); aio_suspend(3) for
+ * aio_write(3) and lio_listio(3).
+ *
+ * If multiple wait methods are specified,
+ * only one wait method will be used. The order is predetermined.
+ *
+ * If the call specifies a signal and one of the two signal wait methods,
+ * a signal handler for the signal is set. This will reset an already
+ * set handler for this signal.
+ *
+ * If the LIO_RANDOM method bit is set, this function will randomly
+ * choose a io type and wait method from bits in the method argument.
+ *
+ * If an error is encountered, an error message will be generated
+ * in a internal static buffer. If errmsg is not NULL, it will
+ * be updated to point to the static buffer, allowing the caller
+ * to print the error message.
+ *
+ * Return Value
+ * If a system call fails, -errno is returned.
+ * If LIO_WAIT_NONE bit is set, the return value is the return value
+ * of the system call.
+ * If the io did not fail, the amount of data written is returned.
+ * If the size the system call say was written is different
+ * then what was asked to be written, errmsg is updated for
+ * this error condition. The return value is still the amount
+ * the system call says was written.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+int
+lio_write_buffer(fd, method, buffer, size, sig, errmsg, wrd)
+int fd; /* open file descriptor */
+int method; /* contains io type and wait method bitmask */
+char *buffer; /* pointer to buffer */
+int size; /* the size of the io */
+int sig; /* signal to use if async io */
+char **errmsg; /* char pointer that will be updated to point to err message */
+long wrd; /* to allow future features, use zero for now */
+{
+ int ret = 0; /* syscall return or used to get random method */
+ char *io_type; /* Holds string of type of io */
+ int omethod = method;
+ int listio_cmd; /* Holds the listio/lio_listio cmd */
+#ifdef CRAY
+ struct listreq request; /* Used when a listio is wanted */
+ struct iosw status, *statptr[1];
+#else
+ /* for linux or sgi */
+ struct iovec iov; /* iovec for writev(2) */
+#endif
+#if defined (sgi)
+ aiocb_t aiocbp; /* POSIX aio control block */
+ aiocb_t *aiolist[1]; /* list of aio control blocks for lio_listio */
+ off64_t poffset; /* pwrite(2) offset */
+#endif
+#if defined(__linux__) && !defined(__UCLIBC__)
+ struct aiocb aiocbp; /* POSIX aio control block */
+ struct aiocb *aiolist[1]; /* list of aio control blocks for lio_listio */
+ off64_t poffset; /* pwrite(2) offset */
+#endif
+ /*
+ * If LIO_RANDOM bit specified, get new method randomly.
+ */
+ if (method & LIO_RANDOM) {
+ if (Debug_level > 3)
+ printf("DEBUG %s/%d: method mask to choose from: %#o\n", __FILE__, __LINE__, method );
+ method = lio_random_methods(method);
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: random chosen method %#o\n", __FILE__, __LINE__, method);
+ }
+
+ if (errmsg != NULL)
+ *errmsg = Errormsg;
+
+ Rec_signal=Received_signal; /* get the current number of signals received */
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ Rec_callback=Received_callback; /* get the current number of callbacks received */
+#endif
+
+#ifdef CRAY
+ memset(&status, 0x00, sizeof(struct iosw));
+ memset(&request, 0x00, sizeof(struct listreq));
+ statptr[0] = &status;
+#else
+ /* for linux or sgi */
+ memset(&iov, 0x00, sizeof(struct iovec));
+ iov.iov_base = buffer;
+ iov.iov_len = size;
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+#if defined(sgi)
+ memset(&aiocbp, 0x00, sizeof(aiocb_t));
+#else
+ memset(&aiocbp, 0x00, sizeof(struct aiocb));
+#endif
+ aiocbp.aio_fildes = fd;
+ aiocbp.aio_nbytes = size;
+ aiocbp.aio_buf = buffer;
+/* aiocbp.aio_offset = lseek( fd, 0, SEEK_CUR ); -- set below */
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_NONE;
+ aiocbp.aio_sigevent.sigev_signo = 0;
+#ifdef sgi
+ aiocbp.aio_sigevent.sigev_func = NULL;
+ aiocbp.aio_sigevent.sigev_value.sival_int = 0;
+#elif defined(__linux__) && !defined(__UCLIBC__)
+ aiocbp.aio_sigevent.sigev_notify_function = NULL;
+ aiocbp.aio_sigevent.sigev_notify_attributes = 0;
+#endif
+ aiolist[0] = &aiocbp;
+
+ if ((ret = lseek( fd, 0, SEEK_CUR )) == -1) {
+ ret = 0;
+ /* If there is an error and it is not ESPIPE then kick out the error.
+ * If the fd is a fifo then we have to make sure that
+ * lio_random_methods() didn't select pwrite/pread; if it did then
+ * switch to write/read.
+ */
+ if (errno == ESPIPE) {
+ if (method & LIO_IO_SYNCP) {
+ if (omethod & LIO_RANDOM) {
+ method &= ~LIO_IO_SYNCP;
+ method |= LIO_IO_SYNC;
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: random chosen method switched to %#o for fifo\n", __FILE__, __LINE__, method );
+ }
+ else if (Debug_level) {
+ printf("DEBUG %s/%d: pwrite will fail when it writes to a fifo\n",
+ __FILE__, __LINE__ );
+ }
+ }
+ /* else: let it ride */
+ }
+ else{
+ sprintf(Errormsg, "%s/%d lseek(fd=%d,0,SEEK_CUR) failed, errno=%d %s",
+ __FILE__, __LINE__, fd, errno, strerror(errno));
+ return -errno;
+ }
+ }
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ poffset = (off64_t)ret;
+#endif
+ aiocbp.aio_offset = ret;
+
+#endif
+
+ /*
+ * If the LIO_USE_SIGNAL bit is not set, only use the signal
+ * if the LIO_WAIT_SIGPAUSE or the LIO_WAIT_SIGACTIVE bits are bit.
+ * Otherwise there is not necessary a signal handler to trap
+ * the signal.
+ */
+ if (sig && !(method & LIO_USE_SIGNAL) &&
+ ! (method & LIO_WAIT_SIGTYPES) ) {
+
+ sig=0; /* ignore signal parameter */
+ }
+
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ if (sig && (method & LIO_WAIT_CBTYPES))
+ sig=0; /* ignore signal parameter */
+#endif
+
+ /*
+ * only setup signal hander if sig was specified and
+ * a sig wait method was specified.
+ * Doing this will change the handler for this signal. The
+ * old signal handler will not be restored.
+ *** restoring the signal handler could be added ***
+ */
+
+ if (sig && (method & LIO_WAIT_SIGTYPES)) {
+#ifdef CRAY
+ sigctl(SCTL_REG, sig, lio_async_signal_handler);
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
+ aiocbp.aio_sigevent.sigev_signo = sig;
+ sigset(sig, lio_async_signal_handler);
+#endif /* sgi */
+ }
+#if defined(sgi)
+ else if (method & LIO_WAIT_CBTYPES) {
+ /* sival_int just has to be something that I can use
+ * to identify the callback, and "size" happens to be handy...
+ */
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_CALLBACK;
+ aiocbp.aio_sigevent.sigev_func = lio_async_callback_handler;
+ aiocbp.aio_sigevent.sigev_value.sival_int = size;
+ }
+#endif
+#if defined(__linux__) && !defined(__UCLIBC__)
+ else if (method & LIO_WAIT_CBTYPES) {
+ /* sival_int just has to be something that I can use
+ * to identify the callback, and "size" happens to be handy...
+ */
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_THREAD;
+ aiocbp.aio_sigevent.sigev_notify_function = lio_async_callback_handler;
+ aiocbp.aio_sigevent.sigev_notify_attributes = (void*)(uintptr_t)size;
+ }
+#endif
+ /*
+ * Determine the system call that will be called and produce
+ * the string of the system call and place it in Lio_SysCall.
+ * Also update the io_type char pointer to give brief description
+ * of system call. Execute the system call and check for
+ * system call failure. If sync i/o, return the number of
+ * bytes written/read.
+ */
+
+ if ((method & LIO_IO_SYNC) || (method & (LIO_IO_TYPES | LIO_IO_ATYPES)) == 0) {
+ /*
+ * write(2) is used if LIO_IO_SYNC bit is set or not none
+ * of the LIO_IO_TYPES bits are set (default).
+ */
+
+ sprintf(Lio_SysCall,
+ "write(%d, buf, %d)", fd, size);
+ io_type="write";
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+ while (1) {
+ if (((ret = write(fd, buffer, size)) == -1) && errno!=EAGAIN && errno!=EINTR) {
+ sprintf(Errormsg, "%s/%d write(%d, buf, %d) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, errno, strerror(errno));
+ return -errno;
+ }
+
+ if (ret!=-1) {
+ if (ret != size) {
+ sprintf(Errormsg,
+ "%s/%d write(%d, buf, %d) returned=%d",
+ __FILE__, __LINE__,
+ fd, size, ret);
+ size-=ret;
+ buffer+=ret;
+ }
+ else {
+ if (Debug_level > 1)
+ printf("DEBUG %s/%d: write completed without error (ret %d)\n",
+ __FILE__, __LINE__, ret);
+
+ return ret;
+ }
+ }
+ wait4sync_io(fd, 0);
+ }
+
+ }
+
+ else if (method & LIO_IO_ASYNC) {
+#ifdef CRAY
+ sprintf(Lio_SysCall,
+ "writea(%d, buf, %d, &status, %d)", fd, size, sig);
+ io_type="writea";
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ sigoff();
+ if ((ret = writea(fd, buffer, size, &status, sig)) == -1) {
+ sprintf(Errormsg,
+ "%s/%d writea(%d, buf, %d, &stat, %d) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, sig, errno, strerror(errno));
+ sigon();
+ return -errno;
+ }
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ sprintf(Lio_SysCall,
+ "aio_write(fildes=%d, buf, nbytes=%d, signo=%d)", fd, size, sig);
+ io_type="aio_write";
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ if (sig)
+ sighold( sig );
+ if ((ret = aio_write(&aiocbp)) == -1) {
+ sprintf(Errormsg,
+ "%s/%d aio_write(fildes=%d, buf, nbytes=%d, signo=%d) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, sig, errno, strerror(errno));
+ if (sig)
+ sigrelse( sig );
+ return -errno;
+ }
+#endif
+ } /* LIO_IO_ASYNC */
+
+ else if (method & LIO_IO_SLISTIO) {
+#ifdef CRAY
+ request.li_opcode = LO_WRITE;
+ request.li_fildes = fd;
+ request.li_buf = buffer;
+ request.li_nbyte = size;
+ request.li_status = &status;
+ request.li_signo = sig;
+ request.li_nstride = 0;
+ request.li_filstride = 0;
+ request.li_memstride = 0;
+
+ listio_cmd=LC_WAIT;
+ io_type="listio(2) sync write";
+
+ sprintf(Lio_SysCall,
+ "listio(LC_WAIT, &req, 1) LO_WRITE, fd:%d, nbyte:%d",
+ fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ sigoff();
+ if (listio(listio_cmd, &request, 1) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ sigon();
+ return -errno;
+ }
+
+ if (Debug_level > 1)
+ printf("DEBUG %s/%d: %s did not return -1\n",
+ __FILE__, __LINE__, Lio_SysCall);
+
+ ret=lio_check_asyncio(io_type, size, &status);
+ return ret;
+
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+
+ aiocbp.aio_lio_opcode = LIO_WRITE;
+ listio_cmd=LIO_WAIT;
+ io_type="lio_listio(3) sync write";
+
+ sprintf(Lio_SysCall,
+ "lio_listio(LIO_WAIT, aiolist, 1, NULL) LIO_WRITE, fd:%d, nbyte:%d, sig:%d",
+ fd, size, sig );
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ if (sig)
+ sighold( sig );
+ if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ if (sig)
+ sigrelse( sig );
+ return -errno;
+ }
+
+ if (Debug_level > 1)
+ printf("DEBUG %s/%d: %s did not return -1\n",
+ __FILE__, __LINE__, Lio_SysCall);
+
+ ret=lio_check_asyncio(io_type, size, &aiocbp, method);
+ return ret;
+#endif
+ } /* LIO_IO_SLISTIO */
+
+ else if (method & LIO_IO_ALISTIO) {
+#ifdef CRAY
+ request.li_opcode = LO_WRITE;
+ request.li_fildes = fd;
+ request.li_buf = buffer;
+ request.li_nbyte = size;
+ request.li_status = &status;
+ request.li_signo = sig;
+ request.li_nstride = 0;
+ request.li_filstride = 0;
+ request.li_memstride = 0;
+
+ listio_cmd=LC_START;
+ io_type="listio(2) async write";
+
+ sprintf(Lio_SysCall,
+ "listio(LC_START, &req, 1) LO_WRITE, fd:%d, nbyte:%d",
+ fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ sigoff();
+ if (listio(listio_cmd, &request, 1) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ sigon();
+ return -errno;
+ }
+#endif
+#if defined (sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ aiocbp.aio_lio_opcode = LIO_WRITE;
+ listio_cmd=LIO_NOWAIT;
+ io_type="lio_listio(3) async write";
+
+ sprintf(Lio_SysCall,
+ "lio_listio(LIO_NOWAIT, aiolist, 1, NULL) LIO_WRITE, fd:%d, nbyte:%d",
+ fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ if (sig)
+ sighold( sig );
+ if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ if (sig)
+ sigrelse( sig );
+ return -errno;
+ }
+#endif
+ }/* LIO_IO_ALISTIO */
+
+#ifndef CRAY
+ else if (method & LIO_IO_SYNCV) {
+ io_type="writev(2)";
+
+ sprintf(Lio_SysCall,
+ "writev(%d, &iov, 1) nbyte:%d", fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+ if ((ret = writev(fd, &iov, 1)) == -1) {
+ sprintf(Errormsg, "%s/%d writev(%d, iov, 1) nbyte:%d ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, errno, strerror(errno));
+ return -errno;
+ }
+
+ if (ret != size) {
+ sprintf(Errormsg,
+ "%s/%d writev(%d, iov, 1) nbyte:%d returned=%d",
+ __FILE__, __LINE__,
+ fd, size, ret);
+ }
+ else if (Debug_level > 1)
+ printf("DEBUG %s/%d: writev completed without error (ret %d)\n",
+ __FILE__, __LINE__, ret);
+
+ return ret;
+ } /* LIO_IO_SYNCV */
+#endif
+
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ else if (method & LIO_IO_SYNCP) {
+ io_type="pwrite(2)";
+
+ sprintf(Lio_SysCall,
+ "pwrite(%d, buf, %d, %lld)", fd, size, (long long)poffset);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+ if ((ret = pwrite(fd, buffer, size, poffset)) == -1) {
+ sprintf(Errormsg, "%s/%d pwrite(%d, buf, %d, %lld) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, (long long)poffset, errno, strerror(errno));
+ return -errno;
+ }
+
+ if (ret != size) {
+ sprintf(Errormsg,
+ "%s/%d pwrite(%d, buf, %d, %lld) returned=%d",
+ __FILE__, __LINE__,
+ fd, size, (long long)poffset, ret);
+ }
+ else if (Debug_level > 1)
+ printf("DEBUG %s/%d: pwrite completed without error (ret %d)\n",
+ __FILE__, __LINE__, ret);
+
+ return ret;
+ } /* LIO_IO_SYNCP */
+#endif
+
+ else {
+ printf("DEBUG %s/%d: No I/O method chosen\n", __FILE__, __LINE__ );
+ return -1;
+ }
+
+ /*
+ * wait for async io to complete.
+ */
+#ifdef CRAY
+ ret=lio_wait4asyncio(method, fd, statptr);
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ ret=lio_wait4asyncio(method, fd, &aiocbp);
+#endif
+
+ /*
+ * If there was an error waiting for async i/o to complete,
+ * return the error value (errno) to the caller.
+ * Note: Errormsg should already have been updated.
+ */
+ if (ret < 0) {
+ return ret;
+ }
+
+ /*
+ * If i/o was not waited for (may not have been completed at this time),
+ * return the size that was requested.
+ */
+ if (ret == 1)
+ return size;
+
+ /*
+ * check that async io was successful.
+ * Note: if the there was an system call failure, -errno
+ * was returned and Errormsg should already have been updated.
+ * If amount i/o was different than size, Errormsg should already
+ * have been updated but the actual i/o size if returned.
+ */
+
+#ifdef CRAY
+ ret=lio_check_asyncio(io_type, size, &status);
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ ret=lio_check_asyncio(io_type, size, &aiocbp, method);
+#endif
+
+ return ret;
+} /* end of lio_write_buffer */
+
+/***********************************************************************
+ * Generic read function
+ * This function can be used to do a read using read(2), reada(2),
+ * aio_read(3), readv(2), pread(2),
+ * or single stride listio(2)/lio_listio(3).
+ * By setting the desired bits in the method
+ * bitmask, the caller can control the type of read and the wait method
+ * that will be used. If no io type bits are set, read will be used.
+ *
+ * If async io was attempted and no wait method bits are set then the
+ * wait method is: recall(2) for reada(2) and listio(2); aio_suspend(3) for
+ * aio_read(3) and lio_listio(3).
+ *
+ * If multiple wait methods are specified,
+ * only one wait method will be used. The order is predetermined.
+ *
+ * If the call specifies a signal and one of the two signal wait methods,
+ * a signal handler for the signal is set. This will reset an already
+ * set handler for this signal.
+ *
+ * If the LIO_RANDOM method bit is set, this function will randomly
+ * choose a io type and wait method from bits in the method argument.
+ *
+ * If an error is encountered, an error message will be generated
+ * in a internal static buffer. If errmsg is not NULL, it will
+ * be updated to point to the static buffer, allowing the caller
+ * to print the error message.
+ *
+ * Return Value
+ * If a system call fails, -errno is returned.
+ * If LIO_WAIT_NONE bit is set, the return value is the return value
+ * of the system call.
+ * If the io did not fail, the amount of data written is returned.
+ * If the size the system call say was written is different
+ * then what was asked to be written, errmsg is updated for
+ * this error condition. The return value is still the amount
+ * the system call says was written.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+int
+lio_read_buffer(fd, method, buffer, size, sig, errmsg, wrd)
+int fd; /* open file descriptor */
+int method; /* contains io type and wait method bitmask */
+char *buffer; /* pointer to buffer */
+int size; /* the size of the io */
+int sig; /* signal to use if async io */
+char **errmsg; /* char pointer that will be updated to point to err message */
+long wrd; /* to allow future features, use zero for now */
+{
+ int ret = 0; /* syscall return or used to get random method */
+ char *io_type; /* Holds string of type of io */
+ int listio_cmd; /* Holds the listio/lio_listio cmd */
+ int omethod = method;
+#ifdef CRAY
+ struct listreq request; /* Used when a listio is wanted */
+ struct iosw status, *statptr[1];
+#else
+ /* for linux or sgi */
+ struct iovec iov; /* iovec for readv(2) */
+#endif
+#ifdef sgi
+ aiocb_t aiocbp; /* POSIX aio control block */
+ aiocb_t *aiolist[1]; /* list of aio control blocks for lio_listio */
+ off64_t poffset; /* pread(2) offset */
+#endif
+#if defined (__linux__) && !defined(__UCLIBC__)
+ struct aiocb aiocbp; /* POSIX aio control block */
+ struct aiocb *aiolist[1]; /* list of aio control blocks for lio_listio */
+ off64_t poffset; /* pread(2) offset */
+#endif
+
+ /*
+ * If LIO_RANDOM bit specified, get new method randomly.
+ */
+ if (method & LIO_RANDOM) {
+ if (Debug_level > 3)
+ printf("DEBUG %s/%d: method mask to choose from: %#o\n", __FILE__, __LINE__, method );
+ method = lio_random_methods(method);
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: random chosen method %#o\n", __FILE__, __LINE__, method);
+ }
+
+ if (errmsg != NULL)
+ *errmsg = Errormsg;
+
+ Rec_signal=Received_signal; /* get the current number of signals received */
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ Rec_callback=Received_callback; /* get the current number of callbacks received */
+#endif
+
+#ifdef CRAY
+ memset(&status, 0x00, sizeof(struct iosw));
+ memset(&request, 0x00, sizeof(struct listreq));
+ statptr[0] = &status;
+#else
+ /* for linux or sgi */
+ memset(&iov, 0x00, sizeof(struct iovec));
+ iov.iov_base = buffer;
+ iov.iov_len = size;
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+#if defined(sgi)
+ memset(&aiocbp, 0x00, sizeof(aiocb_t));
+#else
+ memset(&aiocbp, 0x00, sizeof(struct aiocb));
+#endif
+ aiocbp.aio_fildes = fd;
+ aiocbp.aio_nbytes = size;
+ aiocbp.aio_buf = buffer;
+/* aiocbp.aio_offset = lseek( fd, 0, SEEK_CUR ); -- set below */
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_NONE;
+ aiocbp.aio_sigevent.sigev_signo = 0;
+#ifdef sgi
+ aiocbp.aio_sigevent.sigev_func = NULL;
+ aiocbp.aio_sigevent.sigev_value.sival_int = 0;
+#elif defined(__linux__) && !defined(__UCLIBC__)
+ aiocbp.aio_sigevent.sigev_notify_function = NULL;
+ aiocbp.aio_sigevent.sigev_notify_attributes = 0;
+#endif
+ aiolist[0] = &aiocbp;
+
+ if ((ret = lseek( fd, 0, SEEK_CUR )) == -1) {
+ ret = 0;
+ /* If there is an error and it is not ESPIPE then kick out the error.
+ * If the fd is a fifo then we have to make sure that
+ * lio_random_methods() didn't select pwrite/pread; if it did then
+ * switch to write/read.
+ */
+ if (errno == ESPIPE) {
+ if (method & LIO_IO_SYNCP) {
+ if (omethod & LIO_RANDOM) {
+ method &= ~LIO_IO_SYNCP;
+ method |= LIO_IO_SYNC;
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: random chosen method switched to %#o for fifo\n", __FILE__, __LINE__, method );
+ }
+ else if (Debug_level) {
+ printf("DEBUG %s/%d: pread will fail when it reads from a fifo\n",
+ __FILE__, __LINE__ );
+ }
+ }
+ /* else: let it ride */
+ }
+ else{
+ sprintf(Errormsg, "%s/%d lseek(fd=%d,0,SEEK_CUR) failed, errno=%d %s",
+ __FILE__, __LINE__, fd, errno, strerror(errno));
+ return -errno;
+ }
+ }
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ poffset = (off64_t)ret;
+#endif
+ aiocbp.aio_offset = ret;
+
+#endif
+
+ /*
+ * If the LIO_USE_SIGNAL bit is not set, only use the signal
+ * if the LIO_WAIT_SIGPAUSE or the LIO_WAIT_SIGACTIVE bits are set.
+ * Otherwise there is not necessarily a signal handler to trap
+ * the signal.
+ */
+ if (sig && !(method & LIO_USE_SIGNAL) &&
+ ! (method & LIO_WAIT_SIGTYPES) ) {
+
+ sig=0; /* ignore signal parameter */
+ }
+
+#if defined(sgi) || (defined(__linux__)&& !defined(__UCLIBC__))
+ if (sig && (method & LIO_WAIT_CBTYPES))
+ sig=0; /* ignore signal parameter */
+#endif
+
+ /*
+ * only setup signal hander if sig was specified and
+ * a sig wait method was specified.
+ * Doing this will change the handler for this signal. The
+ * old signal handler will not be restored.
+ *** restoring the signal handler could be added ***
+ */
+
+ if (sig && (method & LIO_WAIT_SIGTYPES)) {
+#ifdef CRAY
+ sigctl(SCTL_REG, sig, lio_async_signal_handler);
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
+ aiocbp.aio_sigevent.sigev_signo = sig;
+ sigset(sig, lio_async_signal_handler);
+#endif /* CRAY */
+ }
+#if defined(sgi)
+ else if (method & LIO_WAIT_CBTYPES) {
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_CALLBACK;
+ aiocbp.aio_sigevent.sigev_func = lio_async_callback_handler;
+ /* sival_int just has to be something that I can use
+ * to identify the callback, and "size" happens to be handy...
+ */
+ aiocbp.aio_sigevent.sigev_value.sival_int = size;
+ }
+#endif
+#if defined(__linux__) && !defined(__UCLIBC__)
+ else if (method & LIO_WAIT_CBTYPES) {
+ aiocbp.aio_sigevent.sigev_notify = SIGEV_THREAD;
+ aiocbp.aio_sigevent.sigev_notify_function = lio_async_callback_handler;
+ /* sival_int just has to be something that I can use
+ * to identify the callback, and "size" happens to be handy...
+ */
+ aiocbp.aio_sigevent.sigev_notify_attributes = (void*)(uintptr_t)size;
+ }
+#endif
+
+ /*
+ * Determine the system call that will be called and produce
+ * the string of the system call and place it in Lio_SysCall.
+ * Also update the io_type char pointer to give brief description
+ * of system call. Execute the system call and check for
+ * system call failure. If sync i/o, return the number of
+ * bytes written/read.
+ */
+
+ if ((method & LIO_IO_SYNC) || (method & (LIO_IO_TYPES | LIO_IO_ATYPES)) == 0) {
+ /*
+ * read(2) is used if LIO_IO_SYNC bit is set or not none
+ * of the LIO_IO_TYPES bits are set (default).
+ */
+
+ sprintf(Lio_SysCall,
+ "read(%d, buf, %d)", fd, size);
+ io_type="read";
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ while (1) {
+ if (((ret = read(fd, buffer, size)) == -1) && errno!=EINTR && errno!=EAGAIN) {
+ sprintf(Errormsg, "%s/%d read(%d, buf, %d) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, errno, strerror(errno));
+ return -errno;
+ }
+
+ if (ret==0) return 0;
+ if (ret!=-1) {
+ if (ret != size) {
+ sprintf(Errormsg,
+ "%s/%d read(%d, buf, %d) returned=%d",
+ __FILE__, __LINE__,
+ fd, size, ret);
+ size-=ret;
+ buffer+=ret;
+ }
+ else {
+ if (Debug_level > 1)
+ printf("DEBUG %s/%d: read completed without error (ret %d)\n",
+ __FILE__, __LINE__, ret);
+
+ return ret;
+ }
+ }
+ wait4sync_io(fd, 1);
+ }
+
+ }
+
+ else if (method & LIO_IO_ASYNC) {
+#ifdef CRAY
+ sprintf(Lio_SysCall,
+ "reada(%d, buf, %d, &status, %d)", fd, size, sig);
+ io_type="reada";
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ sigoff();
+ if ((ret = reada(fd, buffer, size, &status, sig)) == -1) {
+ sprintf(Errormsg,
+ "%s/%d reada(%d, buf, %d, &stat, %d) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, sig, errno, strerror(errno));
+ sigon();
+ return -errno;
+ }
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ sprintf(Lio_SysCall,
+ "aio_read(fildes=%d, buf, nbytes=%d, signo=%d)", fd, size, sig);
+ io_type="aio_read";
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ if (sig)
+ sighold( sig );
+ if ((ret = aio_read(&aiocbp)) == -1) {
+ sprintf(Errormsg,
+ "%s/%d aio_read(fildes=%d, buf, nbytes=%d, signo=%d) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, sig, errno, strerror(errno));
+ if (sig)
+ sigrelse( sig );
+ return -errno;
+ }
+#endif
+ } /* LIO_IO_ASYNC */
+
+ else if (method & LIO_IO_SLISTIO) {
+#ifdef CRAY
+ request.li_opcode = LO_READ;
+ request.li_fildes = fd;
+ request.li_buf = buffer;
+ request.li_nbyte = size;
+ request.li_status = &status;
+ request.li_signo = sig;
+ request.li_nstride = 0;
+ request.li_filstride = 0;
+ request.li_memstride = 0;
+
+ listio_cmd=LC_WAIT;
+ io_type="listio(2) sync read";
+
+ sprintf(Lio_SysCall,
+ "listio(LC_WAIT, &req, 1) LO_READ, fd:%d, nbyte:%d",
+ fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ sigoff();
+ if (listio(listio_cmd, &request, 1) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ sigon();
+ return -errno;
+ }
+
+ if (Debug_level > 1)
+ printf("DEBUG %s/%d: %s did not return -1\n",
+ __FILE__, __LINE__, Lio_SysCall);
+
+ ret=lio_check_asyncio(io_type, size, &status);
+ return ret;
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ aiocbp.aio_lio_opcode = LIO_READ;
+ listio_cmd=LIO_WAIT;
+ io_type="lio_listio(3) sync read";
+
+ sprintf(Lio_SysCall,
+ "lio_listio(LIO_WAIT, aiolist, 1, NULL) LIO_READ, fd:%d, nbyte:%d",
+ fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ if (sig)
+ sighold( sig );
+ if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ if (sig)
+ sigrelse( sig );
+ return -errno;
+ }
+
+ if (Debug_level > 1)
+ printf("DEBUG %s/%d: %s did not return -1\n",
+ __FILE__, __LINE__, Lio_SysCall);
+
+ ret=lio_check_asyncio(io_type, size, &aiocbp, method);
+ return ret;
+#endif
+ }/* LIO_IO_SLISTIO */
+
+ else if (method & LIO_IO_ALISTIO) {
+#ifdef CRAY
+ request.li_opcode = LO_READ;
+ request.li_fildes = fd;
+ request.li_buf = buffer;
+ request.li_nbyte = size;
+ request.li_status = &status;
+ request.li_signo = sig;
+ request.li_nstride = 0;
+ request.li_filstride = 0;
+ request.li_memstride = 0;
+
+ listio_cmd=LC_START;
+ io_type="listio(2) async read";
+
+ sprintf(Lio_SysCall,
+ "listio(LC_START, &req, 1) LO_READ, fd:%d, nbyte:%d",
+ fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ sigoff();
+ if (listio(listio_cmd, &request, 1) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ sigon();
+ return -errno;
+ }
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ aiocbp.aio_lio_opcode = LIO_READ;
+ listio_cmd=LIO_NOWAIT;
+ io_type="lio_listio(3) async read";
+
+ sprintf(Lio_SysCall,
+ "lio_listio(LIO_NOWAIT, aiolist, 1, NULL) LIO_READ, fd:%d, nbyte:%d",
+ fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+
+ if (sig)
+ sighold( sig );
+ if (lio_listio(listio_cmd, aiolist, 1, NULL) == -1) {
+ sprintf(Errormsg, "%s/%d %s failed, fd:%d, nbyte:%d errno=%d %s",
+ __FILE__, __LINE__,
+ Lio_SysCall, fd, size, errno, strerror(errno));
+ if (sig)
+ sigrelse( sig );
+ return -errno;
+ }
+#endif
+ } /* LIO_IO_ALISTIO */
+
+#ifndef CRAY
+ else if (method & LIO_IO_SYNCV) {
+ io_type="readv(2)";
+
+ sprintf(Lio_SysCall,
+ "readv(%d, &iov, 1) nbyte:%d", fd, size);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+ if ((ret = readv(fd, &iov, 1)) == -1) {
+ sprintf(Errormsg, "%s/%d readv(%d, iov, 1) nbyte:%d ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, errno, strerror(errno));
+ return -errno;
+ }
+
+ if (ret != size) {
+ sprintf(Errormsg,
+ "%s/%d readv(%d, iov, 1) nbyte:%d returned=%d",
+ __FILE__, __LINE__,
+ fd, size, ret);
+ }
+ else if (Debug_level > 1)
+ printf("DEBUG %s/%d: readv completed without error (ret %d)\n",
+ __FILE__, __LINE__, ret);
+
+ return ret;
+ } /* LIO_IO_SYNCV */
+#endif
+
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ else if (method & LIO_IO_SYNCP) {
+ io_type="pread(2)";
+
+ sprintf(Lio_SysCall,
+ "pread(%d, buf, %d, %lld)", fd, size, (long long)poffset);
+
+ if (Debug_level) {
+ printf("DEBUG %s/%d: %s\n", __FILE__, __LINE__, Lio_SysCall);
+ }
+ if ((ret = pread(fd, buffer, size, poffset)) == -1) {
+ sprintf(Errormsg, "%s/%d pread(%d, buf, %d, %lld) ret:-1, errno=%d %s",
+ __FILE__, __LINE__,
+ fd, size, (long long)poffset, errno, strerror(errno));
+ return -errno;
+ }
+
+ if (ret != size) {
+ sprintf(Errormsg,
+ "%s/%d pread(%d, buf, %d, %lld) returned=%d",
+ __FILE__, __LINE__,
+ fd, size, (long long)poffset, ret);
+ }
+ else if (Debug_level > 1)
+ printf("DEBUG %s/%d: pread completed without error (ret %d)\n",
+ __FILE__, __LINE__, ret);
+
+ return ret;
+ } /* LIO_IO_SYNCP */
+#endif
+
+ else {
+ printf("DEBUG %s/%d: No I/O method chosen\n", __FILE__, __LINE__ );
+ return -1;
+ }
+
+ /*
+ * wait for async io to complete.
+ * Note: Sync io should have returned prior to getting here.
+ */
+#ifdef CRAY
+ ret=lio_wait4asyncio(method, fd, statptr);
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ ret=lio_wait4asyncio(method, fd, &aiocbp);
+#endif
+
+ /*
+ * If there was an error waiting for async i/o to complete,
+ * return the error value (errno) to the caller.
+ * Note: Errormsg should already have been updated.
+ */
+ if (ret < 0) {
+ return ret;
+ }
+
+ /*
+ * If i/o was not waited for (may not have been completed at this time),
+ * return the size that was requested.
+ */
+ if (ret == 1)
+ return size;
+
+ /*
+ * check that async io was successful.
+ * Note: if the there was an system call failure, -errno
+ * was returned and Errormsg should already have been updated.
+ * If amount i/o was different than size, Errormsg should already
+ * have been updated but the actual i/o size if returned.
+ */
+
+#ifdef CRAY
+ ret=lio_check_asyncio(io_type, size, &status);
+#endif
+#if defined(sgi) || (defined(__linux__) && !defined(__UCLIBC__))
+ ret=lio_check_asyncio(io_type, size, &aiocbp, method);
+#endif
+
+ return ret;
+} /* end of lio_read_buffer */
+
+
+#if !defined(__sun) && !defined(__hpux) && !defined(_AIX)
+/***********************************************************************
+ * This function will check that async io was successful.
+ * It can also be used to check sync listio since it uses the
+ * same method.
+ *
+ * Return Values
+ * If status.sw_error is set, -status.sw_error is returned.
+ * Otherwise sw_count's field value is returned.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+#ifdef CRAY
+int lio_check_asyncio(char *io_type, int size, struct iosw *status)
+#elif defined(sgi)
+ int lio_check_asyncio(char *io_type, int size, aiocb_t *aiocbp, int method)
+#elif defined(__linux__) && !defined(__UCLIBC__)
+ int lio_check_asyncio(char *io_type, int size, struct aiocb *aiocbp, int method)
+{
+ int ret;
+
+#ifdef CRAY
+ if (status->sw_error) {
+ sprintf(Errormsg,
+ "%s/%d %s, sw_error set = %d %s, sw_count = %d",
+ __FILE__, __LINE__, io_type,
+ status->sw_error, strerror(status->sw_error), status->sw_count);
+ return -status->sw_error;
+ }
+ else if (status->sw_count != size) {
+ sprintf(Errormsg,
+ "%s/%d %s, sw_count not as expected(%d), but actual:%d",
+ __FILE__, __LINE__, io_type,
+ size, status->sw_count);
+ }
+ else if (Debug_level > 1) {
+ printf("DEBUG %s/%d: %s completed without error (sw_error == 0, sw_count == %d)\n",
+ __FILE__, __LINE__, io_type, status->sw_count);
+ }
+
+ return status->sw_count;
+
+#else
+
+ int cnt = 1;
+
+ /* The I/O may have been synchronous with signal completion. It doesn't
+ * make sense, but the combination could be generated. Release the
+ * completion signal here otherwise it'll hang around and bite us
+ * later.
+ */
+ if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
+ sigrelse( aiocbp->aio_sigevent.sigev_signo );
+
+ ret = aio_error( aiocbp );
+
+ while (ret == EINPROGRESS) {
+ ret = aio_error( aiocbp );
+ ++cnt;
+ }
+ if (cnt > 1) {
+ sprintf(Errormsg,
+ "%s/%d %s, aio_error had to loop on EINPROGRESS, cnt=%d; random method %#o; sigev_notify=%s",
+ __FILE__, __LINE__, io_type, cnt, method,
+ (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL ? "signal" :
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_NONE ? "none" :
+#ifdef SIGEV_CALLBACK
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_CALLBACK ? "callback" :
+#endif
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD ? "thread" :
+ "unknown") );
+ return -ret;
+ }
+
+ if (ret != 0) {
+ sprintf(Errormsg,
+ "%s/%d %s, aio_error = %d %s; random method %#o",
+ __FILE__, __LINE__, io_type,
+ ret, strerror(ret),
+ method );
+ return -ret;
+ }
+ ret = aio_return( aiocbp );
+ if (ret != size) {
+ sprintf(Errormsg,
+ "%s/%d %s, aio_return not as expected(%d), but actual:%d",
+ __FILE__, __LINE__, io_type,
+ size, ret);
+
+#ifdef BUG1_workaround
+ if (ret == 0) {
+ ret = size;
+ if (Debug_level > 1) {
+ printf("WARN %s/%d: %s completed with bug1_workaround (aio_error == 0, aio_return now == %d)\n",
+ __FILE__, __LINE__, io_type, ret);
+ }
+ }
+#endif /* BUG1_workaround */
+
+ }
+ else if (Debug_level > 1) {
+ printf("DEBUG %s/%d: %s completed without error (aio_error == 0, aio_return == %d)\n",
+ __FILE__, __LINE__, io_type, ret);
+ }
+
+ return ret;
+
+#endif
+} /* end of lio_check_asyncio */
+#endif
+
+/***********************************************************************
+ *
+ * This function will wait for async io to complete.
+ * If multiple wait methods are specified, the order is predetermined
+ * to LIO_WAIT_RECALL,
+ * LIO_WAIT_ACTIVE, LIO_WAIT_SIGPAUSE, LIO_WAIT_SIGACTIVE,
+ * then LIO_WAIT_NONE.
+ *
+ * If no wait method was specified the default wait method is: recall(2)
+ * or aio_suspend(3), as appropriate.
+ *
+ * Return Values
+ * <0: errno of failed recall
+ * 0 : async io was completed
+ * 1 : async was not waited for, io may not have completed.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+#ifdef CRAY
+int lio_wait4asyncio(int method, int fd, struct iosw **statptr)
+#elif defined(sgi)
+ int lio_wait4asyncio(int method, int fd, aiocb_t *aiocbp)
+#elif defined(__linux__) && !defined(__UCLIBC__)
+ int lio_wait4asyncio(int method, int fd, struct aiocb *aiocbp)
+{
+ int cnt;
+#ifdef sgi
+ int ret;
+ const aiocb_t *aioary[1];
+#endif
+#if defined(__linux__)&& !defined(__UCLIBC__)
+ int ret;
+ const struct aiocb *aioary[1];
+#endif
+
+ if ((method & LIO_WAIT_RECALL)
+#if defined(sgi) || (defined(__linux__)&& !defined(__UCLIBC__))
+ || (method & LIO_WAIT_CBSUSPEND)
+ || (method & LIO_WAIT_SIGSUSPEND)
+#endif
+ || ((method & LIO_WAIT_TYPES) == 0) ) {
+ /*
+ * If method has LIO_WAIT_RECALL bit set or method does
+ * not have any wait method bits set (default), use recall/aio_suspend.
+ */
+#ifdef CRAY
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: wait method : recall\n", __FILE__, __LINE__);
+ sigon();
+ if (recall(fd, 1, statptr)) {
+ sprintf(Errormsg, "%s/%d recall(%d, 1, stat) failed, errno:%d %s",
+ __FILE__, __LINE__,
+ fd, errno, strerror(errno));
+ return -errno;
+ }
+#else
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: wait method : aio_suspend, sigev_notify=%s\n", __FILE__, __LINE__,
+ (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL ? "signal" :
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_NONE ? "none" :
+#ifdef SIGEV_CALLBACK
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_CALLBACK ? "callback" :
+#endif
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD ? "thread" :
+ "unknown") );
+
+ aioary[0] = aiocbp;
+ ret = aio_suspend( aioary, 1, NULL );
+ if ((ret == -1) && (errno == EINTR)) {
+ if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) {
+ if (Debug_level > 2) {
+ printf("DEBUG %s/%d: aio_suspend received EINTR, sigev_notify=SIGEV_SIGNAL -- ok\n",
+ __FILE__, __LINE__ );
+ }
+ }
+ else {
+ sprintf(Errormsg, "%s/%d aio_suspend received EINTR, sigev_notify=%s, not ok\n",
+ __FILE__, __LINE__,
+ (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL ? "signal" :
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_NONE ? "none" :
+#ifdef SIGEV_CALLBACK
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_CALLBACK ? "callback" :
+#endif
+ aiocbp->aio_sigevent.sigev_notify == SIGEV_THREAD ? "thread" :
+ "unknown") );
+ return -errno;
+ }
+ }
+ else if (ret) {
+ sprintf(Errormsg, "%s/%d aio_suspend(fildes=%d, aioary, 1, NULL) failed, errno:%d %s",
+ __FILE__, __LINE__,
+ fd, errno, strerror(errno));
+ return -errno;
+ }
+#endif
+
+ } else if (method & LIO_WAIT_ACTIVE) {
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: wait method : active\n", __FILE__, __LINE__);
+#ifdef CRAY
+ sigon();
+ /*
+ * loop until sw_flag, sw_count or sw_error field elements
+ * change to non-zero.
+ */
+ cnt=0;
+ while ((*statptr)->sw_flag == 0 &&
+ (*statptr)->sw_count == 0 &&
+ (*statptr)->sw_error == 0 ) {
+ cnt++;
+ }
+#else
+ /* loop while aio_error() returns EINPROGRESS */
+ cnt=0;
+ while (1) {
+ ret = aio_error( aiocbp );
+ if ((ret == 0) || (ret != EINPROGRESS)) {
+ break;
+ }
+ ++cnt;
+ }
+
+#endif
+ if (Debug_level > 5 && cnt && (cnt % 50) == 0)
+ printf("DEBUG %s/%d: wait active cnt = %d\n",
+ __FILE__, __LINE__, cnt);
+
+ } else if (method & LIO_WAIT_SIGPAUSE) {
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: wait method : sigpause\n", __FILE__, __LINE__);
+#ifdef sgi
+ /* note: don't do the sigon() for CRAY in this case. why? -- roehrich 6/11/97 */
+ if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
+ sigrelse( aiocbp->aio_sigevent.sigev_signo );
+ else {
+ printf("DEBUG %s/%d: sigev_notify != SIGEV_SIGNAL\n", __FILE__, __LINE__ );
+ return -1;
+ }
+#endif
+ pause();
+
+ } else if (method & LIO_WAIT_SIGACTIVE) {
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: wait method : sigactive\n", __FILE__, __LINE__);
+#ifdef CRAY
+ sigon();
+#else
+ if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
+ sigrelse( aiocbp->aio_sigevent.sigev_signo );
+ else {
+ printf("DEBUG %s/%d: sigev_notify != SIGEV_SIGNAL\n", __FILE__, __LINE__ );
+ return -1;
+ }
+#endif
+ /* loop waiting for signal */
+ while (Received_signal == Rec_signal) {
+#ifdef CRAY
+ sigon();
+#else
+ sigrelse( aiocbp->aio_sigevent.sigev_signo );
+#endif
+ }
+
+ } else if (method & LIO_WAIT_NONE) {
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: wait method : none\n", __FILE__, __LINE__);
+ /* It's broken because the aiocb/iosw is an automatic variable in
+ * lio_{read,write}_buffer, so when the function returns and the
+ * I/O completes there will be nowhere to write the I/O status.
+ * It doesn't cause a problem on unicos--probably because of some
+ * compiler quirk, or an accident. It causes POSIX async I/O
+ * to core dump some threads. spr/pv 705909. 6/27/97 roehrich
+ */
+ sprintf(Errormsg, "%s/%d LIO_WAIT_NONE was selected (this is broken)\n",
+ __FILE__, __LINE__ );
+#ifdef CRAY
+ sigon();
+#endif
+/* return 1;*/
+ return -1;
+ }
+ else {
+ if (Debug_level > 2)
+ printf("DEBUG %s/%d: no wait method was chosen\n", __FILE__, __LINE__ );
+ return -1;
+ }
+
+ return 0;
+
+} /* end of lio_wait4asyncio */
+
+#endif /* ifndef linux */
+#endif
+
+#if UNIT_TEST
+/***********************************************************************
+ * The following code is provided as unit test.
+ * Just define add "-DUNIT_TEST=1" to the cc line.
+ *
+ * (rrl 04/96)
+ ***********************************************************************/
+struct unit_info_t {
+ int method;
+ int sig;
+ char *str;
+} Unit_info[] = {
+ { LIO_IO_SYNC, 0, "sync io" },
+ { LIO_IO_SYNCV, 0, "sync readv/writev" },
+ { LIO_IO_SYNCP, 0, "sync pread/pwrite" },
+ { LIO_IO_ASYNC, 0, "async io, def wait" },
+ { LIO_IO_SLISTIO, 0, "sync listio" },
+ { LIO_IO_ALISTIO, 0, "async listio, def wait" },
+ { LIO_IO_ASYNC|LIO_WAIT_ACTIVE, 0, "async active" },
+ { LIO_IO_ASYNC|LIO_WAIT_RECALL, 0, "async recall/suspend" },
+ { LIO_IO_ASYNC|LIO_WAIT_SIGPAUSE, SIGUSR1, "async sigpause" },
+ { LIO_IO_ASYNC|LIO_WAIT_SIGACTIVE, SIGUSR1, "async sigactive" },
+ { LIO_IO_ALISTIO|LIO_WAIT_ACTIVE, 0, "async listio active" },
+ { LIO_IO_ALISTIO|LIO_WAIT_RECALL, 0, "async listio recall" },
+ { LIO_IO_ALISTIO|LIO_WAIT_SIGACTIVE, SIGUSR1, "async listio sigactive" },
+ { LIO_IO_ALISTIO|LIO_WAIT_SIGPAUSE, SIGUSR1, "async listio sigpause" },
+ { LIO_IO_ASYNC, SIGUSR2, "async io, def wait, sigusr2" },
+ { LIO_IO_ALISTIO, SIGUSR2, "async listio, def wait, sigusr2" },
+};
+
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+ extern char *optarg;
+ extern int optind;
+
+ int fd;
+ char *err;
+ char buffer[4096];
+ int size=4096;
+ int ret;
+ int ind;
+ int iter=3;
+ int method;
+ int exit_status = 0;
+ int c;
+ int i;
+ char *symbols = NULL;
+ int die_on_err = 0;
+
+ while ((c = getopt(argc,argv,"s:di:")) != -1) {
+ switch(c) {
+ case 's': symbols = optarg; break;
+ case 'd': ++die_on_err; break;
+ case 'i': iter = atoi(optarg); break;
+ }
+ }
+
+ if ((fd=open("unit_test_file", O_CREAT|O_RDWR|O_TRUNC, 0777)) == -1) {
+ perror("open(unit_test_file, O_CREAT|O_RDWR|O_TRUNC, 0777) failed");
+ exit(1);
+ }
+
+ Debug_level=9;
+
+ if (symbols != NULL) {
+ if ((method=lio_parse_io_arg2(symbols, &err)) == -1) {
+ printf("lio_parse_io_arg2(%s, &err) failed, bad token starting at %s\n",
+ symbols, err);
+ if (die_on_err)
+ exit(1);
+ }
+ else
+ printf("lio_parse_io_arg2(%s, &err) returned %#o\n", symbols, method);
+
+ exit_status = 0;
+ for (ind=0; ind < iter; ind++) {
+ memset( buffer, 'A', 4096 );
+ if (lseek(fd, 0, 0) == -1) {
+ printf("lseek(fd,0,0), %d, failed, errno %d\n",
+ __LINE__, errno );
+ ++exit_status;
+ }
+ if ((ret=lio_write_buffer(fd, method, buffer,
+ size, SIGUSR1, &err, 0)) != size ) {
+ printf("lio_write_buffer returned -1, err = %s\n", err);
+ } else
+ printf("lio_write_buffer returned %d\n", ret);
+
+ memset( buffer, 'B', 4096 );
+ if (lseek(fd, 0, 0) == -1) {
+ printf("lseek(fd,0,0), %d, failed, errno %d\n",
+ __LINE__, errno );
+ ++exit_status;
+ }
+ if ((ret=lio_read_buffer(fd, method, buffer,
+ size, SIGUSR2, &err, 0)) != size ) {
+ printf("lio_read_buffer returned -1, err = %s\n", err);
+ } else
+ printf("lio_read_buffer returned %d\n", ret);
+
+ for (i = 0; i < 4096; ++i) {
+ if (buffer[i] != 'A') {
+ printf(" buffer[%d] = %d\n", i, buffer[i] );
+ ++exit_status;
+ break;
+ }
+ }
+
+ if (exit_status)
+ exit(exit_status);
+
+ }
+
+ unlink("unit_test_file");
+ exit(0);
+ }
+
+ for (ind=0; ind < sizeof(Unit_info)/sizeof(struct unit_info_t); ind++) {
+
+ printf("\n********* write %s ***************\n", Unit_info[ind].str);
+ if (lseek(fd, 0, 0) == -1) {
+ printf("lseek(fd,0,0), %d, failed, errno %d\n",
+ __LINE__, errno );
+ ++exit_status;
+ }
+
+ memset( buffer, 'A', 4096 );
+ if ((ret=lio_write_buffer(fd, Unit_info[ind].method, buffer,
+ size, Unit_info[ind].sig, &err, 0)) != size ) {
+ printf(">>>>> lio_write_buffer(fd,0%x,buffer,%d,%d,err,0) returned -1,\n err = %s\n",
+ Unit_info[ind].method, size, Unit_info[ind].sig, err);
+ ++exit_status;
+ if (die_on_err)
+ exit(exit_status);
+ } else{
+ printf("lio_write_buffer returned %d\n", ret);
+ }
+
+ printf("\n********* read %s ***************\n", Unit_info[ind].str);
+ if (lseek(fd, 0, 0) == -1) {
+ printf("lseek(fd,0,0), %d, failed, errno %d\n",
+ __LINE__, errno );
+ ++exit_status;
+ }
+ memset( buffer, 'B', 4096 );
+ if ((ret=lio_read_buffer(fd, Unit_info[ind].method, buffer,
+ size, Unit_info[ind].sig, &err, 0)) != size ) {
+ printf(">>>>> lio_read_buffer(fd,0%x,buffer,%d,%d,err,0) returned -1,\n err = %s\n",
+ Unit_info[ind].method, size, Unit_info[ind].sig, err);
+ ++exit_status;
+ if (die_on_err)
+ exit(exit_status);
+ } else {
+ printf("lio_read_buffer returned %d\n", ret);
+ }
+
+ for (i = 0; i < 4096; ++i) {
+ if (buffer[i] != 'A') {
+ printf(" buffer[%d] = %d\n", i, buffer[i] );
+ ++exit_status;
+ if (die_on_err)
+ exit(exit_status);
+ break;
+ }
+ }
+
+ fflush(stdout);
+ fflush(stderr);
+ sleep(1);
+
+ }
+
+ unlink("unit_test_file");
+
+ exit(exit_status);
+}
+#endif
diff --git a/ltp_framework/lib/tst_cwd_has_free.c b/ltp_framework/lib/tst_cwd_has_free.c
new file mode 100644
index 0000000..791df09
--- /dev/null
+++ b/ltp_framework/lib/tst_cwd_has_free.c
@@ -0,0 +1,22 @@
+/*
+ * AUTHOR
+ * Ricky Ng-Adam <rngadam@yahoo.com>, 2005-01-01
+ *
+ * DESCRIPTION
+ * Check if there is enough blocks to fill number of KiB specified
+ * If current directory has enough blocks, return 1
+ * If current directory has NOT enough blocks, return 0
+ *
+ *
+ */
+#include <sys/vfs.h>
+
+int
+tst_cwd_has_free(int required_kib)
+{
+ struct statfs sf;
+ statfs(".", &sf);
+
+ /* check that we have enough blocks to create swap file */
+ return ((float)sf.f_bfree)/(1024/sf.f_bsize) >= required_kib?1:0;
+} \ No newline at end of file
diff --git a/ltp_framework/lib/tst_is_cwd.c b/ltp_framework/lib/tst_is_cwd.c
new file mode 100644
index 0000000..636aaca
--- /dev/null
+++ b/ltp_framework/lib/tst_is_cwd.c
@@ -0,0 +1,52 @@
+/*
+ * Michal Simek <monstr@monstr.eu>, 2009-08-03 - ramfs
+ * Kumar Gala <galak@kernel.crashing.org>, 2007-11-14 - nfs
+ * Ricky Ng-Adam <rngadam@yahoo.com>, 2005-01-01 - tmpfs
+ *
+ * DESCRIPTION
+ * Check if current directory is on a tmpfs/nfs/ramfs filesystem
+ * If current directory is tmpfs/nfs/ramfs, return 1
+ * If current directory is NOT tmpfs/nfs/ramfs, return 0
+ */
+
+#include <sys/vfs.h>
+
+#define TMPFS_MAGIC 0x01021994 /* man 2 statfs */
+int tst_is_cwd_tmpfs(void)
+{
+ struct statfs sf;
+ statfs(".", &sf);
+
+ /* Verify that the file is not on a tmpfs (in-memory) filesystem */
+ return (sf.f_type == TMPFS_MAGIC);
+}
+
+#define NFS_MAGIC 0x6969 /* man 2 statfs */
+int tst_is_cwd_nfs(void)
+{
+ struct statfs sf;
+ statfs(".", &sf);
+
+ /* Verify that the file is not on a nfs filesystem */
+ return (sf.f_type == NFS_MAGIC);
+}
+
+#define V9FS_MAGIC 0x01021997 /* kernel-source/include/linux/magic.h */
+int tst_is_cwd_v9fs(void)
+{
+ struct statfs sf;
+ statfs(".", &sf);
+
+ /* Verify that the file is not on a nfs filesystem */
+ return (sf.f_type == V9FS_MAGIC);
+}
+
+#define RAMFS_MAGIC 0x858458f6
+int tst_is_cwd_ramfs(void)
+{
+ struct statfs sf;
+ statfs(".", &sf);
+
+ /* Verify that the file is not on a ramfs (in-memory) filesystem */
+ return (sf.f_type == RAMFS_MAGIC);
+}
diff --git a/ltp_framework/lib/tst_kvercmp.c b/ltp_framework/lib/tst_kvercmp.c
new file mode 100644
index 0000000..f132164
--- /dev/null
+++ b/ltp_framework/lib/tst_kvercmp.c
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2003
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ *
+ * AUTHOR
+ * Paul Larson <plars@linuxtestproject.org>
+ *
+ * DESCRIPTION
+ * Compare a given kernel version against the current kernel version.
+ * If they are the same - return 0
+ * If the argument is > current kernel version - return positive int
+ * If the argument is < current kernel version - return negative int
+ *
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+void get_kver(int *k1, int *k2, int *k3)
+{
+ struct utsname uval;
+ char *kver;
+ char *r1, *r2, *r3;
+#if !defined(linux)
+ extern char *strsep(); /* shut up some compilers */
+#endif
+
+ uname(&uval);
+ kver = uval.release;
+ r1 = strsep(&kver, ".");
+ r2 = strsep(&kver, ".");
+ r3 = strsep(&kver, ".");
+
+ *k1 = atoi(r1);
+ *k2 = atoi(r2);
+ *k3 = atoi(r3);
+}
+
+int tst_kvercmp(int r1, int r2, int r3) {
+ int a1, a2, a3;
+ int testver, currver;
+
+ get_kver(&a1, &a2, &a3);
+ testver = (r1 << 16) + (r2 << 8) + r3;
+ currver = (a1 << 16) + (a2 << 8) + a3;
+
+ return currver - testver;
+} \ No newline at end of file
diff --git a/ltp_framework/lib/tst_res.c b/ltp_framework/lib/tst_res.c
new file mode 100644
index 0000000..f958279
--- /dev/null
+++ b/ltp_framework/lib/tst_res.c
@@ -0,0 +1,812 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2009 Cyril Hrubis chrubis@suse.cz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+
+/* $Id: tst_res.c,v 1.14 2009/12/01 08:57:20 yaberauneya Exp $ */
+
+/**********************************************************
+ *
+ * OS Testing - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME :
+ * tst_res() - Print result message (include file contents)
+ * tst_resm() - Print result message
+ * tst_brk() - Print result message (include file contents)
+ * and break remaining test cases
+ * tst_brkm() - Print result message and break remaining test
+ * cases
+ * tst_flush() - Print any messages pending in the output stream
+ * tst_exit() - Exit test with a meaningful exit value.
+ * tst_environ() - Keep results coming to original stdout
+ *
+ * FUNCTION TITLE : Standard automated test result reporting mechanism
+ *
+ * SYNOPSIS:
+ * #include "test.h"
+ *
+ * void tst_res(ttype, fname, tmesg [,arg]...)
+ * int ttype;
+ * char *fname;
+ * char *tmesg;
+ *
+ * void tst_resm(ttype, tmesg [,arg]...)
+ * int ttype;
+ * char *tmesg;
+ *
+ * void tst_brk(ttype, fname, cleanup, tmesg, [,argv]...)
+ * int ttype;
+ * char *fname;
+ * void (*cleanup)();
+ * char *tmesg;
+ *
+ * void tst_brkm(ttype, cleanup, tmesg [,arg]...)
+ * int ttype;
+ * void (*cleanup)();
+ * char *tmesg;
+ *
+ * void tst_flush()
+ *
+ * void tst_exit()
+ *
+ * int tst_environ()
+ *
+ * AUTHOR : Kent Rogers (from Dave Fenner's original)
+ *
+ * CO-PILOT : Rich Logan
+ *
+ * DATE STARTED : 05/01/90 (rewritten 1/96)
+ *
+ * MAJOR CLEANUPS BY : Cyril Hrubis
+ *
+ * DESCRIPTION
+ * See the man page(s).
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include "test.h"
+#include "usctest.h"
+
+/* Break bad habits. */
+#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
+pid_t spawned_program_pid;
+#endif
+
+#define VERBOSE 1 /* flag values for the T_mode variable */
+#define NOPASS 3
+#define DISCARD 4
+
+#define MAXMESG 80 /* max length of internal messages */
+#define USERMESG 2048 /* max length of user message */
+#define TRUE 1
+#define FALSE 0
+
+/*
+ * EXPAND_VAR_ARGS - Expand the variable portion (arg_fmt) of a result
+ * message into the specified string.
+ *
+ * NOTE (garrcoop): arg_fmt _must_ be the last element in each function
+ * argument list that employs this.
+ */
+#define EXPAND_VAR_ARGS(buf, arg_fmt, buf_len) do {\
+ va_list ap; \
+ assert(arg_fmt != NULL); \
+ va_start(ap, arg_fmt); \
+ vsnprintf(buf, buf_len, arg_fmt, ap); \
+ va_end(ap); \
+ assert(strlen(buf) > 0); \
+} while (0)
+
+/*
+ * Define local function prototypes.
+ */
+static void check_env(void);
+static void tst_condense(int tnum, int ttype, char *tmesg);
+static void tst_print(char *tcid, int tnum, int ttype, char *tmesg);
+static void cat_file(char *filename);
+
+/*
+ * Define some static/global variables.
+ */
+static FILE *T_out = NULL; /* tst_res() output file descriptor */
+static char *File; /* file whose contents is part of result */
+static int T_exitval = 0; /* exit value used by tst_exit() */
+static int T_mode = VERBOSE; /* flag indicating print mode: VERBOSE, */
+ /* NOPASS, DISCARD */
+
+static char Warn_mesg[MAXMESG]; /* holds warning messages */
+
+/*
+ * These are used for condensing output when NOT in verbose mode.
+ */
+static int Buffered = FALSE; /* TRUE if condensed output is currently */
+ /* buffered (i.e. not yet printed) */
+static char *Last_tcid; /* previous test case id */
+static int Last_num; /* previous test case number */
+static int Last_type; /* previous test result type */
+static char *Last_mesg; /* previous test result message */
+
+
+/*
+ * These globals may be externed by the test.
+ */
+int Tst_count = 0; /* current count of test cases executed; NOTE: */
+ /* Tst_count may be externed by other programs */
+
+/*
+ * These globals must be defined in the test.
+ */
+extern char *TCID; /* Test case identifier from the test source */
+extern int TST_TOTAL; /* Total number of test cases from the test */
+ /* source */
+
+struct pair {
+ const char *name;
+ int val;
+};
+#define PAIR(def) [def] = { .name = #def, .val = def, },
+const char *pair_lookup(struct pair *pair, int pair_size, int idx)
+{
+ if (idx < 0 || idx >= pair_size || pair[idx].name == NULL)
+ return "???";
+ return pair[idx].name;
+}
+#define pair_lookup(pair, idx) pair_lookup(pair, ARRAY_SIZE(pair), idx)
+
+/*
+ * strttype() - convert a type result to the human readable string
+ */
+const char *strttype(int ttype)
+{
+ struct pair ttype_pairs[] = {
+ PAIR(TPASS)
+ PAIR(TFAIL)
+ PAIR(TBROK)
+ PAIR(TRETR)
+ PAIR(TCONF)
+ PAIR(TWARN)
+ PAIR(TINFO)
+ };
+ return pair_lookup(ttype_pairs, TTYPE_RESULT(ttype));
+}
+
+/*
+ * strerrnodef() - convert an errno value to its C define
+ */
+static const char *strerrnodef(int err)
+{
+ struct pair errno_pairs[] = {
+ PAIR(EPERM)
+ PAIR(ENOENT)
+ PAIR(ESRCH)
+ PAIR(EINTR)
+ PAIR(EIO)
+ PAIR(ENXIO)
+ PAIR(E2BIG)
+ PAIR(ENOEXEC)
+ PAIR(EBADF)
+ PAIR(ECHILD)
+ PAIR(EAGAIN)
+ PAIR(ENOMEM)
+ PAIR(EACCES)
+ PAIR(EFAULT)
+ PAIR(ENOTBLK)
+ PAIR(EBUSY)
+ PAIR(EEXIST)
+ PAIR(EXDEV)
+ PAIR(ENODEV)
+ PAIR(ENOTDIR)
+ PAIR(EISDIR)
+ PAIR(EINVAL)
+ PAIR(ENFILE)
+ PAIR(EMFILE)
+ PAIR(ENOTTY)
+ PAIR(ETXTBSY)
+ PAIR(EFBIG)
+ PAIR(ENOSPC)
+ PAIR(ESPIPE)
+ PAIR(EROFS)
+ PAIR(EMLINK)
+ PAIR(EPIPE)
+ PAIR(EDOM)
+ PAIR(ERANGE)
+ PAIR(ENAMETOOLONG)
+ };
+ return pair_lookup(errno_pairs, err);
+}
+
+/*
+ * tst_res() - Main result reporting function. Handle test information
+ * appropriately depending on output display mode. Call
+ * tst_condense() or tst_print() to actually print results.
+ * All result functions (tst_resm(), tst_brk(), etc.)
+ * eventually get here to print the results.
+ */
+void tst_res(int ttype, char *fname, char *arg_fmt, ...)
+{
+ char tmesg[USERMESG];
+ int ttype_result = TTYPE_RESULT(ttype);
+
+#if DEBUG
+ printf("IN tst_res; Tst_count = %d\n", Tst_count);
+ fflush(stdout);
+#endif
+
+ EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
+
+ /*
+ * Save the test result type by ORing ttype into the current exit
+ * value (used by tst_exit()).
+ */
+ T_exitval |= ttype_result;
+
+ /*
+ * Unless T_out has already been set by tst_environ(), make tst_res()
+ * output go to standard output.
+ */
+ if (T_out == NULL)
+ T_out = stdout;
+
+ /*
+ * Check TOUTPUT environment variable (if first time) and set T_mode
+ * flag.
+ */
+ check_env();
+
+ if (fname != NULL && access(fname, F_OK) == 0)
+ File = fname;
+
+ /*
+ * Set the test case number and print the results, depending on the
+ * display type.
+ */
+ if (ttype_result == TWARN || ttype_result == TINFO) {
+ tst_print(TCID, 0, ttype, tmesg);
+ } else {
+ if (Tst_count < 0)
+ tst_print(TCID, 0, TWARN,
+ "tst_res(): Tst_count < 0 is not valid");
+
+ /*
+ * Process each display type.
+ */
+ switch (T_mode) {
+ case DISCARD:
+ break;
+ case NOPASS: /* filtered by tst_print() */
+ tst_condense(Tst_count+1, ttype, tmesg);
+ break;
+ default: /* VERBOSE */
+ tst_print(TCID, Tst_count+1, ttype, tmesg);
+ break;
+ }
+
+ Tst_count++;
+ }
+
+}
+
+
+/*
+ * tst_condense() - Handle test cases in NOPASS mode (i.e.
+ * buffer the current result and print the last result
+ * if different than the current). If a file was
+ * specified, print the current result and do not
+ * buffer it.
+ */
+static void tst_condense(int tnum, int ttype, char *tmesg)
+{
+ char *file;
+ int ttype_result = TTYPE_RESULT(ttype);
+
+#if DEBUG
+ printf( "IN tst_condense: tcid = %s, tnum = %d, ttype = %d, "
+ "tmesg = %s\n",
+ TCID, tnum, ttype, tmesg);
+ fflush(stdout);
+#endif
+
+ /*
+ * If this result is the same as the previous result, return.
+ */
+ if (Buffered == TRUE) {
+ if (strcmp(Last_tcid, TCID) == 0 && Last_type == ttype_result &&
+ strcmp(Last_mesg, tmesg) == 0 && File == NULL)
+ return;
+
+ /*
+ * This result is different from the previous result. First,
+ * print the previous result.
+ */
+ file = File;
+ File = NULL;
+ tst_print(Last_tcid, Last_num, Last_type, Last_mesg);
+ free(Last_tcid);
+ free(Last_mesg);
+ File = file;
+ }
+
+ /*
+ * If a file was specified, print the current result since we have no
+ * way of retaining the file contents for comparing with future
+ * results. Otherwise, buffer the current result info for next time.
+ */
+ if (File != NULL) {
+ tst_print(TCID, tnum, ttype, tmesg);
+ Buffered = FALSE;
+ } else {
+ Last_tcid = (char *)malloc(strlen(TCID) + 1);
+ strcpy(Last_tcid, TCID);
+ Last_num = tnum;
+ Last_type = ttype_result;
+ Last_mesg = (char *)malloc(strlen(tmesg) + 1);
+ strcpy(Last_mesg, tmesg);
+ Buffered = TRUE;
+ }
+}
+
+
+/*
+ * tst_flush() - Print any messages pending because due to tst_condense,
+ * and flush T_out.
+ */
+void tst_flush(void)
+{
+#if DEBUG
+ printf("IN tst_flush\n");
+ fflush(stdout);
+#endif
+
+ /*
+ * Print out last line if in NOPASS mode.
+ */
+ if (Buffered == TRUE && T_mode == NOPASS) {
+ tst_print(Last_tcid, Last_num, Last_type, Last_mesg);
+ Buffered = FALSE;
+ }
+
+ fflush(T_out);
+}
+
+
+/*
+ * tst_print() - Print a line to the output stream.
+ */
+static void tst_print(char *tcid, int tnum, int ttype, char *tmesg)
+{
+ /*
+ * avoid unintended side effects from failures with fprintf when
+ * calling write(2), et all.
+ */
+ int err = errno;
+ const char *type;
+ int ttype_result = TTYPE_RESULT(ttype);
+
+#ifdef GARRETT_IS_A_PEDANTIC_BASTARD
+ /* Don't execute these APIs unless you have the same pid as main! */
+ if (spawned_program_pid != 0) {
+ /*
+ * Die quickly and noisily so people get the cluebat that the
+ * test needs to be fixed. These APIs should _not_ be called
+ * from forked processes because of the fact that it can confuse
+ * end-users with printouts, cleanup will potentially blow away
+ * directories and/or files still in use introducing
+ * non-determinism, etc.
+ *
+ * assert will not return (by design in accordance with POSIX
+ * 1003.1) if the assertion fails. Read abort(3) for more
+ * details. So don't worry about saving / restoring the signal
+ * handler, unless you have a buggy OS that you've hacked 15
+ * different ways to Sunday.
+ */
+ assert(spawned_program_pid == getpid());
+ }
+#endif
+
+#if DEBUG
+ printf("IN tst_print: tnum = %d, ttype = %d, tmesg = %s\n",
+ tnum, ttype, tmesg);
+ fflush(stdout);
+#endif
+
+ /*
+ * Save the test result type by ORing ttype into the current exit value
+ * (used by tst_exit()). This is already done in tst_res(), but is
+ * also done here to catch internal warnings. For internal warnings,
+ * tst_print() is called directly with a case of TWARN.
+ */
+ T_exitval |= ttype_result;
+
+ /*
+ * If output mode is DISCARD, or if the output mode is NOPASS and this
+ * result is not one of FAIL, BROK, or WARN, just return. This check
+ * is necessary even though we check for DISCARD mode inside of
+ * tst_res(), since occasionally we get to this point without going
+ * through tst_res() (e.g. internal TWARN messages).
+ */
+ if (T_mode == DISCARD || (T_mode == NOPASS && ttype_result != TFAIL &&
+ ttype_result != TBROK && ttype_result != TWARN))
+ return;
+
+ /*
+ * Build the result line and print it.
+ */
+ type = strttype(ttype);
+ if (T_mode == VERBOSE) {
+ fprintf(T_out, "%-8s %4d %s : %s", tcid, tnum, type, tmesg);
+ } else {
+ fprintf(T_out, "%-8s %4d %s : %s",
+ tcid, tnum, type, tmesg);
+ }
+ if (ttype & TERRNO) {
+ fprintf(T_out, ": errno=%s(%i): %s", strerrnodef(err),
+ err, strerror(err));
+ }
+ if (ttype & TTERRNO) {
+ fprintf(T_out, ": TEST_ERRNO=%s(%i): %s",
+ strerrnodef(TEST_ERRNO), (int)TEST_ERRNO,
+ strerror(TEST_ERRNO));
+ }
+ fprintf(T_out, "\n");
+
+ /*
+ * If tst_res() was called with a file, append file contents to the
+ * end of last printed result.
+ */
+ if (File != NULL)
+ cat_file(File);
+
+ File = NULL;
+}
+
+
+/*
+ * check_env() - Check the value of the environment variable TOUTPUT and
+ * set the global variable T_mode. The TOUTPUT environment
+ * variable should be set to "VERBOSE", "NOPASS", or "DISCARD".
+ * If TOUTPUT does not exist or is not set to a valid value, the
+ * default is "VERBOSE".
+ */
+static void check_env(void)
+{
+ static int first_time = 1;
+ char *value;
+
+#if DEBUG
+ printf("IN check_env\n");
+ fflush(stdout);
+#endif
+
+ if (!first_time)
+ return;
+
+ first_time = 0;
+
+ /* BTOUTPUT not defined, use default */
+ if ((value = getenv(TOUTPUT)) == NULL) {
+ T_mode = VERBOSE;
+ return;
+ }
+
+ if (strcmp(value, TOUT_NOPASS_S) == 0) {
+ T_mode = NOPASS;
+ return;
+ }
+
+ if (strcmp(value, TOUT_DISCARD_S) == 0) {
+ T_mode = DISCARD;
+ return;
+ }
+
+ /* default */
+ T_mode = VERBOSE;
+ return;
+}
+
+
+/*
+ * tst_exit() - Call exit() with the value T_exitval, set up by
+ * tst_res(). T_exitval has a bit set for most of the
+ * result types that were seen (including TPASS, TFAIL,
+ * TBROK, TWARN, TCONF). Also, print the last result (if
+ * necessary) before exiting.
+ */
+void tst_exit(void)
+{
+#if DEBUG
+ printf("IN tst_exit\n"); fflush(stdout);
+ fflush(stdout);
+#endif
+
+ /* Call tst_flush() flush any output in the buffer. */
+ tst_flush();
+
+ /* Mask out TRETR, TINFO, and TCONF results from the exit status. */
+ exit(T_exitval & ~(TRETR | TINFO | TCONF));
+}
+
+
+/*
+ * tst_environ() - Preserve the tst_res() output location, despite any
+ * changes to stdout.
+ */
+int tst_environ(void)
+{
+ if ((T_out = fdopen(dup(fileno(stdout)), "w")) == NULL)
+ return -1;
+ else
+ return 0;
+}
+
+
+/*
+ * Make tst_brk reentrant so that one can call the SAFE_* macros from within
+ * user-defined cleanup functions.
+ */
+static int tst_brk_entered = 0;
+
+/*
+ * tst_brk() - Fail or break current test case, and break the remaining
+ * tests cases.
+ */
+void tst_brk(int ttype, char *fname, void (*func)(void), char *arg_fmt, ...)
+{
+ char tmesg[USERMESG];
+ int ttype_result = TTYPE_RESULT(ttype);
+
+#if DEBUG
+ printf("IN tst_brk\n"); fflush(stdout);
+ fflush(stdout);
+#endif
+
+ EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
+
+ /*
+ * Only FAIL, BROK, CONF, and RETR are supported by tst_brk().
+ */
+ if (ttype_result != TFAIL && ttype_result != TBROK &&
+ ttype_result != TCONF && ttype_result != TRETR) {
+ sprintf(Warn_mesg, "%s: Invalid Type: %d. Using TBROK",
+ __func__, ttype_result);
+ tst_print(TCID, 0, TWARN, Warn_mesg);
+ /* Keep TERRNO, TTERRNO, etc. */
+ ttype = (ttype & ~ttype_result) | TBROK;
+ }
+
+ tst_res(ttype, fname, "%s", tmesg);
+ if (tst_brk_entered == 0) {
+ if (ttype_result == TCONF)
+ tst_res(ttype, NULL,
+ "Remaining cases not appropriate for "
+ "configuration");
+ else if (ttype_result == TRETR)
+ tst_res(ttype, NULL, "Remaining cases retired");
+ else if (ttype_result == TBROK)
+ tst_res(TBROK, NULL, "Remaining cases broken");
+ }
+
+ /*
+ * If no cleanup function was specified, just return to the caller.
+ * Otherwise call the specified function.
+ */
+ if (func != NULL) {
+ tst_brk_entered++;
+ (*func)();
+ tst_brk_entered--;
+ }
+ if (tst_brk_entered == 0)
+ tst_exit();
+
+}
+
+/*
+ * tst_resm() - Interface to tst_res(), with no filename.
+ */
+void tst_resm(int ttype, char *arg_fmt, ...)
+{
+ char tmesg[USERMESG];
+
+#if DEBUG
+ printf("IN tst_resm\n"); fflush(stdout);
+ fflush(stdout);
+#endif
+
+ EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
+
+ tst_res(ttype, NULL, "%s", tmesg);
+}
+
+
+/*
+ * tst_brkm() - Interface to tst_brk(), with no filename.
+ */
+void tst_brkm(int ttype, void (*func)(void), char *arg_fmt, ...)
+{
+ char tmesg[USERMESG];
+
+#if DEBUG
+ printf("IN tst_brkm\n"); fflush(stdout);
+ fflush(stdout);
+#endif
+
+ EXPAND_VAR_ARGS(tmesg, arg_fmt, USERMESG);
+
+ tst_brk(ttype, NULL, func, "%s", tmesg);
+}
+
+
+/*
+ * tst_require_root() - Test for root permissions and abort if not.
+ */
+void tst_require_root(void (*func)(void))
+{
+ if (geteuid() != 0)
+ tst_brkm(TCONF, func, "Test needs to be run as root");
+}
+
+
+/*
+ * cat_file() - Print the contents of a file to standard out.
+ */
+static void cat_file(char *filename)
+{
+ FILE *fp;
+ int b_read, b_written;
+ char buffer[BUFSIZ];
+
+#if DEBUG
+ printf("IN cat_file\n"); fflush(stdout);
+#endif
+
+ if ((fp = fopen(filename, "r")) == NULL) {
+ sprintf(Warn_mesg,
+ "tst_res(): fopen(%s, \"r\") failed; errno = %d: %s",
+ filename, errno, strerror(errno));
+ tst_print(TCID, 0, TWARN, Warn_mesg);
+ return;
+ }
+
+ errno = 0;
+
+ while ((b_read = fread(buffer, 1, BUFSIZ, fp)) != 0) {
+ if ((b_written = fwrite(buffer, 1, b_read, T_out)) != b_read) {
+ sprintf(Warn_mesg,
+ "tst_res(): While trying to cat \"%s\", "
+ "fwrite() wrote only %d of %d bytes",
+ filename, b_written, b_read);
+ tst_print(TCID, 0, TWARN, Warn_mesg);
+ break;
+ }
+ }
+
+ if (!feof(fp)) {
+ sprintf(Warn_mesg,
+ "tst_res(): While trying to cat \"%s\", fread() "
+ "failed, errno = %d: %s",
+ filename, errno, strerror(errno));
+ tst_print(TCID, 0, TWARN, Warn_mesg);
+ }
+
+ if (fclose(fp) != 0) {
+ sprintf(Warn_mesg,
+ "tst_res(): While trying to cat \"%s\", fclose() "
+ "failed, errno = %d: %s",
+ filename, errno, strerror(errno));
+ tst_print(TCID, 0, TWARN, Warn_mesg);
+ }
+}
+
+
+#ifdef UNIT_TEST
+/****************************************************************************
+ * Unit test code: Takes input from stdin and can make the following
+ * calls: tst_res(), tst_resm(), tst_brk(), tst_brkm(),
+ * tst_flush_buf(), tst_exit().
+ ****************************************************************************/
+int TST_TOTAL = 10;
+char *TCID = "TESTTCID";
+
+#define RES "tst_res.c UNIT TEST message; ttype = %d; contents of \"%s\":"
+#define RESM "tst_res.c UNIT TEST message; ttype = %d"
+
+int main(void)
+{
+ int ttype;
+ char chr;
+ char fname[MAXMESG];
+
+ printf("UNIT TEST of tst_res.c. Options for ttype:\n\
+ -1 : call tst_exit()\n\
+ -2 : call tst_flush()\n\
+ -3 : call tst_brk()\n\
+ -4 : call tst_res()\n\
+ %2i : call tst_res(TPASS, ...)\n\
+ %2i : call tst_res(TFAIL, ...)\n\
+ %2i : call tst_res(TBROK, ...)\n\
+ %2i : call tst_res(TWARN, ...)\n\
+ %2i : call tst_res(TRETR, ...)\n\
+ %2i : call tst_res(TINFO, ...)\n\
+ %2i : call tst_res(TCONF, ...)\n\n",
+ TPASS, TFAIL, TBROK, TWARN, TRETR, TINFO, TCONF);
+
+ while (1) {
+ printf("Enter ttype (-5,-4,-3,-2,-1,%i,%i,%i,%i,%i,%i,%i): ",
+ TPASS, TFAIL, TBROK, TWARN, TRETR, TINFO, TCONF);
+ scanf("%d%c", &ttype, &chr);
+
+ switch (ttype) {
+ case -1:
+ tst_exit();
+ break;
+
+ case -2:
+ tst_flush();
+ break;
+
+ case -3:
+ printf("Enter the current type (%i=FAIL, %i=BROK, %i=RETR, %i=CONF): ",
+ TFAIL, TBROK, TRETR, TCONF);
+ scanf("%d%c", &ttype, &chr);
+ printf("Enter file name (<cr> for none): ");
+ gets(fname);
+ if (strcmp(fname, "") == 0)
+ tst_brkm(ttype, tst_exit, RESM, ttype);
+ else
+ tst_brk(ttype, fname, tst_exit, RES, ttype, fname);
+ break;
+
+ case -4:
+ printf("Enter the current type (%i,%i,%i,%i,%i,%i,%i): ",
+ TPASS, TFAIL, TBROK, TWARN, TRETR, TINFO, TCONF);
+ scanf("%d%c", &ttype, &chr);
+ default:
+ printf("Enter file name (<cr> for none): ");
+ gets(fname);
+
+ if (strcmp(fname, "") == 0)
+ tst_resm(ttype, RESM, ttype);
+ else
+ tst_res(ttype, fname, RES, ttype, fname);
+ break;
+ }
+
+ }
+}
+
+#endif /* UNIT_TEST */
diff --git a/ltp_framework/lib/tst_sig.c b/ltp_framework/lib/tst_sig.c
new file mode 100644
index 0000000..53181bf
--- /dev/null
+++ b/ltp_framework/lib/tst_sig.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+/* $Id: tst_sig.c,v 1.13 2009/08/28 09:29:01 vapier Exp $ */
+
+/*****************************************************************************
+ OS Testing - Silicon Graphics, Inc.
+
+ FUNCTION IDENTIFIER : tst_sig Set up for unexpected signals.
+
+ AUTHOR : David D. Fenner
+
+ CO-PILOT : Bill Roske
+
+ DATE STARTED : 06/06/90
+
+ This module may be linked with c-modules requiring unexpected
+ signal handling. The parameters to tst_sig are as follows:
+
+ fork_flag - set to FORK or NOFORK depending upon whether the
+ calling program executes a fork() system call. It
+ is normally the case that the calling program treats
+ SIGCLD as an expected signal if fork() is being used.
+
+ handler - a pointer to the unexpected signal handler to
+ be executed after an unexpected signal has been
+ detected. If handler is set to DEF_HANDLER, a
+ default handler is used. This routine should be
+ declared as function returning an int.
+
+ cleanup - a pointer to a cleanup routine to be executed
+ by the unexpected signal handler before tst_exit is
+ called. This parameter is set to NULL if no cleanup
+ routine is required. An external variable, T_cleanup
+ is set so that other user-defined handlers have
+ access to the cleanup routine. This routine should be
+ declared as returning type void.
+
+***************************************************************************/
+
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include "test.h"
+
+#define MAXMESG 150 /* size of mesg string sent to tst_res */
+
+void (*T_cleanup) (); /* pointer to cleanup function */
+
+/****************************************************************************
+ * STD_COPIES is defined in parse_opts.c but is externed here in order to
+ * test whether SIGCHILD should be ignored or not.
+ ***************************************************************************/
+extern int STD_COPIES;
+
+static void def_handler(); /* default signal handler */
+static void (*tst_setup_signal(int, void (*)(int))) (int);
+
+/****************************************************************************
+ * tst_sig() : set-up to catch unexpected signals. fork_flag is set to NOFORK
+ * if SIGCLD is to be an "unexpected signal", otherwise it is set to
+ * FORK. cleanup points to a cleanup routine to be executed before
+ * tst_exit is called (cleanup is set to NULL if no cleanup is desired).
+ * handler is a pointer to the signal handling routine (if handler is
+ * set to NULL, a default handler is used).
+ ***************************************************************************/
+
+void tst_sig(int fork_flag, void (*handler) (), void (*cleanup) ())
+{
+ int sig;
+#ifdef _SC_SIGRT_MIN
+ long sigrtmin, sigrtmax;
+#endif
+
+ /*
+ * save T_cleanup and handler function pointers
+ */
+ T_cleanup = cleanup; /* used by default handler */
+
+ if (handler == DEF_HANDLER) {
+ /* use default handler */
+ handler = def_handler;
+ }
+#ifdef _SC_SIGRT_MIN
+ sigrtmin = sysconf(_SC_SIGRT_MIN);
+ sigrtmax = sysconf(_SC_SIGRT_MAX);
+#endif
+
+ /*
+ * now loop through all signals and set the handlers
+ */
+
+ for (sig = 1; sig < NSIG; sig++) {
+ /*
+ * SIGKILL is never unexpected.
+ * SIGCLD is only unexpected when
+ * no forking is being done.
+ * SIGINFO is used for file quotas and should be expected
+ */
+
+#ifdef _SC_SIGRT_MIN
+ if (sig >= sigrtmin && sig <= sigrtmax)
+ continue;
+#endif
+
+ switch (sig) {
+ case SIGKILL:
+ case SIGSTOP:
+ case SIGCONT:
+#if !defined(_SC_SIGRT_MIN) && defined(__SIGRTMIN) && defined(__SIGRTMAX)
+ /* Ignore all real-time signals */
+ case __SIGRTMIN:
+ case __SIGRTMIN + 1:
+ case __SIGRTMIN + 2:
+ case __SIGRTMIN + 3:
+ case __SIGRTMIN + 4:
+ case __SIGRTMIN + 5:
+ case __SIGRTMIN + 6:
+ case __SIGRTMIN + 7:
+ case __SIGRTMIN + 8:
+ case __SIGRTMIN + 9:
+ case __SIGRTMIN + 10:
+ case __SIGRTMIN + 11:
+ case __SIGRTMIN + 12:
+ case __SIGRTMIN + 13:
+ case __SIGRTMIN + 14:
+ case __SIGRTMIN + 15:
+/* __SIGRTMIN is 37 on HPPA rather than 32 *
+ * as on i386, etc. */
+#if !defined(__hppa__)
+ case __SIGRTMAX - 15:
+ case __SIGRTMAX - 14:
+ case __SIGRTMAX - 13:
+ case __SIGRTMAX - 12:
+ case __SIGRTMAX - 11:
+#endif
+ case __SIGRTMAX - 10:
+ case __SIGRTMAX - 9:
+ case __SIGRTMAX - 8:
+ case __SIGRTMAX - 7:
+ case __SIGRTMAX - 6:
+ case __SIGRTMAX - 5:
+ case __SIGRTMAX - 4:
+ case __SIGRTMAX - 3:
+ case __SIGRTMAX - 2:
+ case __SIGRTMAX - 1:
+ case __SIGRTMAX:
+#endif
+#ifdef CRAY
+ case SIGINFO:
+ case SIGRECOVERY: /* allow chkpnt/restart */
+#endif /* CRAY */
+
+#ifdef SIGSWAP
+ case SIGSWAP:
+#endif /* SIGSWAP */
+
+#ifdef SIGCKPT
+ case SIGCKPT:
+#endif
+#ifdef SIGRESTART
+ case SIGRESTART:
+#endif
+ /*
+ * pthread-private signals SIGPTINTR and SIGPTRESCHED.
+ * Setting a handler for these signals is disallowed when
+ * the binary is linked against libpthread.
+ */
+#ifdef SIGPTINTR
+ case SIGPTINTR:
+#endif /* SIGPTINTR */
+#ifdef SIGPTRESCHED
+ case SIGPTRESCHED:
+#endif /* SIGPTRESCHED */
+#ifdef _SIGRESERVE
+ case _SIGRESERVE:
+#endif
+#ifdef _SIGDIL
+ case _SIGDIL:
+#endif
+#ifdef _SIGCANCEL
+ case _SIGCANCEL:
+#endif
+#ifdef _SIGGFAULT
+ case _SIGGFAULT:
+#endif
+ break;
+
+ case SIGCLD:
+ if (fork_flag == FORK || STD_COPIES > 1)
+ continue;
+
+ default:
+ if (tst_setup_signal(sig, handler) == SIG_ERR)
+ tst_resm(TWARN|TERRNO,
+ "signal failed for signal %d", sig);
+ break;
+ }
+#ifdef __sgi
+ /* On irix (07/96), signal() fails when signo is 33 or higher */
+ if (sig + 1 >= 33)
+ break;
+#endif /* __sgi */
+
+ } /* endfor */
+}
+
+/****************************************************************************
+ * def_handler() : default signal handler that is invoked when
+ * an unexpected signal is caught.
+ ***************************************************************************/
+
+static void def_handler(int sig)
+{
+ /*
+ * Break remaining test cases, do any cleanup, then exit
+ */
+ tst_brkm(TBROK, T_cleanup,
+ "unexpected signal %d received (pid = %d).", sig, getpid());
+}
+
+/*
+ * tst_setup_signal - A function like signal(), but we have
+ * control over its personality.
+ */
+static void (*tst_setup_signal(int sig, void (*handler) (int))) (int)
+{
+ struct sigaction my_act, old_act;
+ int ret;
+
+ my_act.sa_handler = handler;
+ my_act.sa_flags = SA_RESTART;
+ sigemptyset(&my_act.sa_mask);
+
+ ret = sigaction(sig, &my_act, &old_act);
+
+ if (ret == 0)
+ return old_act.sa_handler;
+ else
+ return SIG_ERR;
+} \ No newline at end of file
diff --git a/ltp_framework/lib/tst_tmpdir.c b/ltp_framework/lib/tst_tmpdir.c
new file mode 100644
index 0000000..d112e3e
--- /dev/null
+++ b/ltp_framework/lib/tst_tmpdir.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+
+/* $Id: tst_tmpdir.c,v 1.14 2009/07/20 10:59:32 vapier Exp $ */
+
+/**********************************************************
+ *
+ * OS Testing - Silicon Graphics, Inc.
+ *
+ * FUNCTION NAME : tst_tmpdir, tst_rmdir
+ *
+ * FUNCTION TITLE : Create/remove a testing temp dir
+ *
+ * SYNOPSIS:
+ * void tst_tmpdir();
+ * void tst_rmdir();
+ *
+ * AUTHOR : Dave Fenner
+ *
+ * INITIAL RELEASE : UNICOS 8.0
+ *
+ * DESCRIPTION
+ * tst_tmpdir() is used to create a unique, temporary testing
+ * directory, and make it the current working directory.
+ * tst_rmdir() is used to remove the directory created by
+ * tst_tmpdir().
+ *
+ * Setting the env variable "TDIRECTORY" will override the creation
+ * of a new temp dir. The directory specified by TDIRECTORY will
+ * be used as the temporary directory, and no removal will be done
+ * in tst_rmdir().
+ *
+ * RETURN VALUE
+ * Neither tst_tmpdir() or tst_rmdir() has a return value.
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <errno.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "test.h"
+#include "rmobj.h"
+
+/*
+ * Define some useful macros.
+ */
+#define DIR_MODE (S_IRWXU|S_IRWXG|S_IRWXO)
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+/*
+ * Define function prototypes.
+ */
+static void tmpdir_cleanup(void);
+
+/*
+ * Define global variables.
+ */
+extern char *TCID; /* defined/initialized in main() */
+static char *TESTDIR = NULL; /* the directory created */
+
+/*
+ * Return a copy of the test temp directory as seen by LTP. This is for
+ * path-oriented tests like chroot, etc, that may munge the path a bit.
+ *
+ * FREE VARIABLE AFTER USE IF IT IS REUSED!
+ */
+char *
+get_tst_tmpdir(void)
+{
+ /* Smack the user for calling things out of order. */
+ if (TESTDIR == NULL)
+ tst_brkm(TBROK, NULL, "you must call tst_tmpdir() first");
+ return strdup(TESTDIR);
+}
+
+/*
+ * tst_tmpdir() - Create a unique temporary directory and chdir() to it.
+ * It expects the caller to have defined/initialized the
+ * TCID/TST_TOTAL global variables. The TESTDIR global
+ * variable will be set to the directory that gets used
+ * as the testing directory.
+ *
+ * NOTE: This function must be called BEFORE any activity
+ * that would require CLEANUP. If tst_tmpdir() fails, it
+ * cleans up afer itself and calls tst_exit() (i.e. does
+ * not return).
+ */
+void tst_tmpdir(void)
+{
+ char template[PATH_MAX];
+ int no_cleanup = 0; /* !0 means TDIRECTORY env var was set */
+ char *env_tmpdir; /* temporary storage for TMPDIR env var */
+ /* This is an AWFUL hack to figure out if mkdtemp() is available */
+#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2,2)
+#define HAVE_MKDTEMP
+#endif
+
+ /*
+ * If the TDIRECTORY env variable is not set, a temp dir will be
+ * created.
+ */
+ if ((TESTDIR = getenv(TDIRECTORY)) != NULL) {
+ /*
+ * The TDIRECTORY env. variable is set, so no temp dir is created.
+ */
+ if (mkdir(TESTDIR, DIR_MODE) == -1 && errno != EEXIST) {
+ tst_brkm(TBROK, NULL, "mkdir(%s, %o) failed",
+ TESTDIR, DIR_MODE);
+ }
+ /*
+ * Try to create the directory if it does not exist already;
+ * user might forget to create one before exporting TDIRECTORY.
+ */
+ no_cleanup++;
+#if UNIT_TEST
+ printf("TDIRECTORY env var is set\n");
+#endif
+ } else {
+ /*
+ * Create a template for the temporary directory. Use the
+ * environment variable TMPDIR if it is available, otherwise
+ * use our default TEMPDIR.
+ */
+ if ((env_tmpdir = getenv("TMPDIR"))) {
+ snprintf(template, PATH_MAX, "%s/%.3sXXXXXX", env_tmpdir, TCID);
+ } else {
+ snprintf(template, PATH_MAX, "%s/%.3sXXXXXX", TEMPDIR, TCID);
+ }
+
+#ifdef HAVE_MKDTEMP
+ /* Make the temporary directory in one shot using mkdtemp. */
+ if (mkdtemp(template) == NULL)
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "%s: mkdtemp(%s) failed", __func__, template);
+ if ((TESTDIR = strdup(template)) == NULL) {
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "%s: strdup(%s) failed", __func__, template);
+ }
+#else
+ int tfd;
+
+ /* Make the template name, then the directory */
+ if ((tfd = mkstemp(template)) == -1)
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "%s: mkstemp(%s) failed", __func__, template);
+ if (close(tfd) == -1) {
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "%s: close() failed", __func__);
+ }
+ if (unlink(template) == -1) {
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "%s: unlink(%s) failed", __func__, template);
+ }
+ if ((TESTDIR = strdup(template)) == NULL) {
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "%s: strdup(%s) failed", __func__, template);
+ }
+ if (mkdir(TESTDIR, DIR_MODE)) {
+ /*
+ * If we start failing with EEXIST, wrap this section in
+ * a loop so we can try again.
+ *
+ * XXX (garrcoop): why? Hacking around broken
+ * filesystems should not be done.
+ */
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "%s: mkdir(%s, %#o) failed",
+ __func__, TESTDIR, DIR_MODE);
+ }
+#endif
+
+ if (chown(TESTDIR, -1, getgid()) == -1)
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "chown(%s, -1, %d) failed", TESTDIR, getgid());
+ if (chmod(TESTDIR, DIR_MODE) == -1)
+ tst_brkm(TBROK|TERRNO, tmpdir_cleanup,
+ "chmod(%s, %#o) failed", TESTDIR, DIR_MODE);
+ }
+
+#if UNIT_TEST
+ printf("TESTDIR = %s\n", TESTDIR);
+#endif
+
+ /*
+ * Change to the temporary directory. If the chdir() fails, issue
+ * TBROK messages for all test cases, attempt to remove the
+ * directory (if it was created), and exit. If the removal also
+ * fails, also issue a TWARN message.
+ */
+ if (chdir(TESTDIR) == -1) {
+ tst_brkm(TBROK|TERRNO, NULL, "%s: chdir(%s) failed",
+ __func__, TESTDIR);
+
+ /* Try to remove the directory */
+ if (!no_cleanup && rmdir(TESTDIR) == -1) {
+ tst_resm(TWARN|TERRNO, "%s: rmdir(%s) failed",
+ __func__, TESTDIR);
+ }
+
+ tmpdir_cleanup();
+ }
+
+#if UNIT_TEST
+ printf("CWD is %s\n", getcwd(NULL, PATH_MAX));
+#endif
+
+} /* tst_tmpdir() */
+
+
+/*
+ *
+ * tst_rmdir() - Recursively remove the temporary directory created by
+ * tst_tmpdir(). This function is intended ONLY as a
+ * companion to tst_tmpdir(). If the TDIRECTORY
+ * environment variable is set, no cleanup will be
+ * attempted.
+ */
+void tst_rmdir(void)
+{
+ struct stat buf1;
+ struct stat buf2;
+ char current_dir[PATH_MAX];
+ char *errmsg;
+ char *parent_dir;
+ char *tdirectory;
+
+ /*
+ * If the TDIRECTORY env variable is set, this indicates that no
+ * temp dir was created by tst_tmpdir(). Thus no cleanup will be
+ * necessary.
+ */
+ if ((tdirectory = getenv(TDIRECTORY)) != NULL) {
+#if UNIT_TEST
+ printf("\"TDIRECORY\" env variable is set; no cleanup was performed\n");
+#endif
+ return;
+ }
+
+ /*
+ * Check that TESTDIR is not NULL.
+ */
+ if (TESTDIR == NULL) {
+ tst_resm(TWARN,
+ "%s: TESTDIR was NULL; no removal attempted", __func__);
+ return;
+ }
+
+ if ((parent_dir = malloc(PATH_MAX)) == NULL) {
+ /* Make sure that we exit quickly and noisily. */
+ tst_brkm(TBROK|TERRNO, NULL,
+ "%s: malloc(%d) failed", __func__, PATH_MAX);
+ }
+
+ /*
+ * Check that the value of TESTDIR is not "*" or "/". These could
+ * have disastrous effects in a test run by root.
+ */
+ /* XXX: a temp directory that's '/' seems stupid and dangerous anyways. */
+ if (stat(TESTDIR, &buf1) == 0 && stat("/", &buf2) == 0 &&
+ buf1.st_ino == buf2.st_ino) {
+ tst_resm(TWARN, "%s: will not remove /", __func__);
+ return;
+ }
+
+ /*
+ * XXX: this just reeks of bad programming; all shell characters should
+ * be escaped in invocations of rm(1)/rmdir(1).
+ */
+ if (strchr(TESTDIR, '*') != NULL) {
+ tst_resm(TWARN, "%s: will not remove *", __func__);
+ return;
+ }
+
+ /*
+ * Get the directory name of TESTDIR. If TESTDIR is a relative path,
+ * get full path.
+ */
+ if (TESTDIR[0] != '/') {
+ if (getcwd(current_dir, PATH_MAX) == NULL)
+ strncpy(parent_dir, TESTDIR, sizeof(parent_dir));
+ else
+ sprintf(parent_dir, "%s/%s", current_dir, TESTDIR);
+ } else {
+ strcpy(parent_dir, TESTDIR);
+ }
+ if ((parent_dir = dirname(parent_dir)) == NULL) {
+ tst_resm(TWARN|TERRNO, "%s: dirname failed", __func__);
+ return;
+ }
+
+ /*
+ * Change directory to parent_dir (The dir above TESTDIR).
+ */
+ if (chdir(parent_dir) != 0) {
+ tst_resm(TWARN|TERRNO,
+ "%s: chdir(%s) failed\nAttempting to remove temp dir "
+ "anyway",
+ __func__, parent_dir);
+ }
+
+ /*
+ * Attempt to remove the "TESTDIR" directory, using rmobj().
+ */
+ if (rmobj(TESTDIR, &errmsg) == -1)
+ tst_resm(TWARN, "%s: rmobj(%s) failed: %s",
+ __func__, TESTDIR, errmsg);
+
+} /* tst_rmdir() */
+
+
+/*
+ * tmpdir_cleanup(void) - This function is used when tst_tmpdir()
+ * encounters an error, and must cleanup and exit.
+ * It prints a warning message via tst_resm(), and
+ * then calls tst_exit().
+ */
+static void
+tmpdir_cleanup(void)
+{
+ tst_brkm(TWARN, NULL,
+ "%s: no user cleanup function called before exiting", __func__);
+}
+
+
+#ifdef UNIT_TEST
+/****************************************************************************
+ * Unit test code: Takes input from stdin and can make the following
+ * calls: tst_tmpdir(), tst_rmdir().
+ ****************************************************************************/
+extern int TST_TOTAL; /* defined/initialized in main() */
+
+int TST_TOTAL = 10;
+char *TCID = "TESTTCID";
+
+main()
+{
+ int option;
+ char *chrptr;
+
+ printf("UNIT TEST of tst_tmpdir.c. Options to try:\n\
+ -1 : call tst_exit()\n\
+ 0 : call tst_tmpdir()\n\
+ 1 : call tst_rmdir()\n\n");
+
+ while (1) {
+ printf("Enter options (-1, 0, 1): ");
+ (void)scanf("%d%c", &option, &chrptr);
+
+ switch (option) {
+ case -1:
+ tst_exit();
+ break;
+
+ case 0:
+ tst_tmpdir();
+ break;
+
+ case 1:
+ tst_rmdir();
+ break;
+ } /* switch() */
+ } /* while () */
+}
+#endif /* UNIT_TEST */
diff --git a/ltp_framework/lib/write_log.c b/ltp_framework/lib/write_log.c
new file mode 100644
index 0000000..ef560e7
--- /dev/null
+++ b/ltp_framework/lib/write_log.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+/*
+ * This module contains code for logging writes to files, and for
+ * perusing the resultant logfile. The main intent of all this is
+ * to provide a 'write history' of a file which can be examined to
+ * judge the state of a file (ie. whether it is corrupted or not) based
+ * on the write activity.
+ *
+ * The main abstractions available to the user are the wlog_file, and
+ * the wlog_rec. A wlog_file is a handle encapsulating a write logfile.
+ * It is initialized with the wlog_open() function. This handle is
+ * then passed to the various wlog_xxx() functions to provide transparent
+ * access to the write logfile.
+ *
+ * The wlog_rec datatype is a structure which contains all the information
+ * about a file write. Examples include the file name, offset, length,
+ * pattern, etc. In addition there is a bit which is cleared/set based
+ * on whether or not the write has been confirmed as complete. This
+ * allows the write logfile to contain information on writes which have
+ * been initiated, but not yet completed (as in async io).
+ *
+ * There is also a function to scan a write logfile in reverse order.
+ *
+ * NOTE: For target file analysis based on a write logfile, the
+ * assumption is made that the file being written to is
+ * locked from simultaneous access, so that the order of
+ * write completion is predictable. This is an issue when
+ * more than 1 process is trying to write data to the same
+ * target file simultaneously.
+ *
+ * The history file created is a collection of variable length records
+ * described by scruct wlog_rec_disk in write_log.h. See that module for
+ * the layout of the data on disk.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "write_log.h"
+
+#ifndef BSIZE
+#ifdef DEV_BSIZE
+#define BSIZE DEV_BSIZE
+#else
+#define BSIZE BBSIZE
+#endif
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 255
+/*#define PATH_MAX pathconf("/", _PC_PATH_MAX)*/
+#endif
+
+char Wlog_Error_String[256];
+
+#if __STDC__
+static int wlog_rec_pack(struct wlog_rec *wrec, char *buf, int flag);
+static int wlog_rec_unpack(struct wlog_rec *wrec, char *buf);
+#else
+static int wlog_rec_pack();
+static int wlog_rec_unpack();
+#endif
+
+/*
+ * Initialize a write logfile. wfile is a wlog_file structure that has
+ * the w_file field filled in. The rest of the information in the
+ * structure is initialized by the routine.
+ *
+ * The trunc flag is used to indicate whether or not the logfile should
+ * be truncated if it currently exists. If it is non-zero, the file will
+ * be truncated, otherwise it will be appended to.
+ *
+ * The mode argument is the [absolute] mode which the file will be
+ * given if it does not exist. This mode is not affected by your process
+ * umask.
+ */
+
+int
+wlog_open(wfile, trunc, mode)
+struct wlog_file *wfile;
+int trunc;
+int mode;
+{
+ int omask, oflags;
+
+ if (trunc)
+ trunc = O_TRUNC;
+
+ omask = umask(0);
+
+ /*
+ * Open 1 file descriptor as O_APPEND
+ */
+
+ oflags = O_WRONLY | O_APPEND | O_CREAT | trunc;
+ wfile->w_afd =
+ open(wfile->w_file, oflags, mode);
+ umask(omask);
+
+ if (wfile->w_afd == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not open write_log - open(%s, %#o, %#o) failed: %s\n",
+ wfile->w_file, oflags, mode, strerror(errno));
+ return -1;
+ }
+
+ /*
+ * Open the next fd as a random access descriptor
+ */
+
+ oflags = O_RDWR;
+ if ((wfile->w_rfd = open(wfile->w_file, oflags)) == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not open write log - open(%s, %#o) failed: %s\n",
+ wfile->w_file, oflags, strerror(errno));
+ close(wfile->w_afd);
+ wfile->w_afd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Release all resources associated with a wlog_file structure allocated
+ * with the wlog_open() call.
+ */
+
+int
+wlog_close(wfile)
+struct wlog_file *wfile;
+{
+ close(wfile->w_afd);
+ close(wfile->w_rfd);
+ return 0;
+}
+
+/*
+ * Write a wlog_rec structure to a write logfile. Offset is used to
+ * control where the record will be written. If offset is < 0, the
+ * record will be appended to the end of the logfile. Otherwise, the
+ * record which exists at the indicated offset will be overlayed. This
+ * is so that we can record writes which are outstanding (with the w_done
+ * bit in wrec cleared), but not completed, and then later update the
+ * logfile when the write request completes (as with async io). When
+ * offset is >= 0, only the fixed length portion of the record is
+ * rewritten. See text in write_log.h for details on the format of an
+ * on-disk record.
+ *
+ * The return value of the function is the byte offset in the logfile
+ * where the record begins.
+ *
+ * Note: It is the callers responsibility to make sure that the offset
+ * parameter 'points' to a valid record location when a record is to be
+ * overlayed. This is guarenteed by saving the return value of a previous
+ * call to wlog_record_write() which wrote the record to be overlayed.
+ *
+ * Note2: The on-disk version of the wlog_rec is MUCH different than
+ * the user version. Don't expect to od the logfile and see data formatted
+ * as it is in the wlog_rec structure. Considerable data packing takes
+ * place before the record is written.
+ */
+
+int
+wlog_record_write(wfile, wrec, offset)
+struct wlog_file *wfile;
+struct wlog_rec *wrec;
+long offset;
+{
+ int reclen;
+ char wbuf[WLOG_REC_MAX_SIZE + 2];
+
+ /*
+ * If offset is -1, we append the record at the end of file
+ *
+ * Otherwise, we overlay wrec at the file offset indicated and assume
+ * that the caller passed us the correct offset. We do not record the
+ * fname in this case.
+ */
+
+ reclen = wlog_rec_pack(wrec, wbuf, (offset < 0));
+
+ if (offset < 0) {
+ /*
+ * Since we're writing a complete new record, we must also tack
+ * its length onto the end so that wlog_scan_backward() will work.
+ * Length is asumed to fit into 2 bytes.
+ */
+
+ wbuf[reclen] = reclen / 256;
+ wbuf[reclen+1] = reclen % 256;
+ reclen += 2;
+
+ if (write(wfile->w_afd, wbuf, reclen) == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not write log - write(%s, %s, %d) failed: %s\n",
+ wfile->w_file, wbuf, reclen, strerror(errno));
+ return -1;
+ } else {
+ offset = lseek(wfile->w_afd, 0, SEEK_CUR) - reclen;
+ if (offset == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not reposition file pointer - lseek(%s, 0, SEEK_CUR) failed: %s\n",
+ wfile->w_file, strerror(errno));
+ return -1;
+ }
+ }
+ } else {
+ if ((lseek(wfile->w_rfd, offset, SEEK_SET)) == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not reposition file pointer - lseek(%s, %ld, SEEK_SET) failed: %s\n",
+ wfile->w_file, offset, strerror(errno));
+ return -1;
+ } else {
+ if ((write(wfile->w_rfd, wbuf, reclen)) == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not write log - write(%s, %s, %d) failed: %s\n",
+ wfile->w_file, wbuf, reclen, strerror(errno));
+ return -1;
+ }
+ }
+ }
+
+ return offset;
+}
+
+/*
+ * Function to scan a logfile in reverse order. Wfile is a valid
+ * wlog_file structure initialized by wlog_open(). nrecs is the number
+ * of records to scan (all records are scanned if nrecs is 0). func is
+ * a user-supplied function to call for each record found. The function
+ * will be passed a single parameter - a wlog_rec structure .
+ */
+
+int
+wlog_scan_backward(wfile, nrecs, func, data)
+struct wlog_file *wfile;
+int nrecs;
+int (*func)();
+long data;
+{
+ int fd, leftover, nbytes, offset, recnum, reclen, rval;
+ char buf[BSIZE*32], *bufend, *cp, *bufstart;
+ char albuf[WLOG_REC_MAX_SIZE];
+ struct wlog_rec wrec;
+
+ fd = wfile->w_rfd;
+
+ /*
+ * Move to EOF. offset will always hold the current file offset
+ */
+
+ if ((lseek(fd, 0, SEEK_END)) == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not reposition file pointer - lseek(%s, 0, SEEK_END) failed: %s\n",
+ wfile->w_file, strerror(errno));
+ return -1;
+ }
+ offset = lseek(fd, 0, SEEK_CUR);
+ if ((offset == -1)) {
+ sprintf(Wlog_Error_String,
+ "Could not reposition file pointer - lseek(%s, 0, SEEK_CUR) failed: %s\n",
+ wfile->w_file, strerror(errno));
+ return -1;
+ }
+
+ bufend = buf + sizeof(buf);
+ bufstart = buf;
+
+ recnum = 0;
+ leftover = 0;
+ while ((!nrecs || recnum < nrecs) && offset > 0) {
+ /*
+ * Check for beginning of file - if there aren't enough bytes
+ * remaining to fill buf, adjust bufstart.
+ */
+
+ if ((unsigned int)offset + leftover < sizeof(buf)) {
+ bufstart = bufend - (offset + leftover);
+ offset = 0;
+ } else {
+ offset -= sizeof(buf) - leftover;
+ }
+
+ /*
+ * Move to the proper file offset, and read into buf
+ */
+ if ((lseek(fd, offset, SEEK_SET)) ==-1) {
+ sprintf(Wlog_Error_String,
+ "Could not reposition file pointer - lseek(%s, %d, SEEK_SET) failed: %s\n",
+ wfile->w_file, offset, strerror(errno));
+ return -1;
+ }
+
+ nbytes = read(fd, bufstart, bufend - bufstart - leftover);
+
+ if (nbytes == -1) {
+ sprintf(Wlog_Error_String,
+ "Could not read history file at offset %d - read(%d, %p, %d) failed: %s\n",
+ offset, fd, bufstart,
+ (int)(bufend - bufstart - leftover), strerror(errno));
+ return -1;
+ }
+
+ cp = bufend;
+ leftover = 0;
+
+ while (cp >= bufstart) {
+
+ /*
+ * If cp-bufstart is not large enough to hold a piece
+ * of record length information, copy remainder to end
+ * of buf and continue reading the file.
+ */
+
+ if (cp - bufstart < 2) {
+ leftover = cp - bufstart;
+ memcpy(bufend - leftover, bufstart, leftover);
+ break;
+ }
+
+ /*
+ * Extract the record length. We must do it this way
+ * instead of casting cp to an int because cp might
+ * not be word aligned.
+ */
+
+ reclen = (*(cp-2) * 256) + *(cp -1);
+
+ /*
+ * If cp-bufstart isn't large enough to hold a
+ * complete record, plus the length information, copy
+ * the leftover bytes to the end of buf and continue
+ * reading.
+ */
+
+ if (cp - bufstart < reclen + 2) {
+ leftover = cp - bufstart;
+ memcpy(bufend - leftover, bufstart, leftover);
+ break;
+ }
+
+ /*
+ * Adjust cp to point at the start of the record.
+ * Copy the record into wbuf so that it is word
+ * aligned and pass the record to the user supplied
+ * function.
+ */
+
+ cp -= reclen + 2;
+ memcpy(albuf, cp, reclen);
+
+ wlog_rec_unpack(&wrec, albuf);
+
+ /*
+ * Call the user supplied function -
+ * stop if instructed to.
+ */
+
+ if ((rval = (*func)(&wrec, data)) == WLOG_STOP_SCAN) {
+ break;
+ }
+
+ recnum++;
+
+ if (nrecs && recnum >= nrecs)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * The following 2 routines are used to pack and unpack the user
+ * visible wlog_rec structure to/from a character buffer which is
+ * stored or read from the write logfile. Any changes to either of
+ * these routines must be reflected in the other.
+ */
+
+static int
+wlog_rec_pack(wrec, buf, flag)
+struct wlog_rec *wrec;
+char *buf;
+int flag;
+{
+ char *file, *host, *pattern;
+ struct wlog_rec_disk *wrecd;
+
+ wrecd = (struct wlog_rec_disk *)buf;
+
+ wrecd->w_pid = (uint)wrec->w_pid;
+ wrecd->w_offset = (uint)wrec->w_offset;
+ wrecd->w_nbytes = (uint)wrec->w_nbytes;
+ wrecd->w_oflags = (uint)wrec->w_oflags;
+ wrecd->w_done = (uint)wrec->w_done;
+ wrecd->w_async = (uint)wrec->w_async;
+
+ wrecd->w_pathlen = (wrec->w_pathlen > 0) ? (uint)wrec->w_pathlen : 0;
+ wrecd->w_hostlen = (wrec->w_hostlen > 0) ? (uint)wrec->w_hostlen : 0;
+ wrecd->w_patternlen = (wrec->w_patternlen > 0) ? (uint)wrec->w_patternlen : 0;
+
+ /*
+ * If flag is true, we should also pack the variable length parts
+ * of the wlog_rec. By default, we only pack the fixed length
+ * parts.
+ */
+
+ if (flag) {
+ file = buf + sizeof(struct wlog_rec_disk);
+ host = file + wrecd->w_pathlen;
+ pattern = host + wrecd->w_hostlen;
+
+ if (wrecd->w_pathlen > 0)
+ memcpy(file, wrec->w_path, wrecd->w_pathlen);
+
+ if (wrecd->w_hostlen > 0)
+ memcpy(host, wrec->w_host, wrecd->w_hostlen);
+
+ if (wrecd->w_patternlen > 0)
+ memcpy(pattern, wrec->w_pattern, wrecd->w_patternlen);
+
+ return (sizeof(struct wlog_rec_disk) +
+ wrecd->w_pathlen + wrecd->w_hostlen + wrecd->w_patternlen);
+ } else {
+ return sizeof(struct wlog_rec_disk);
+ }
+}
+
+static int
+wlog_rec_unpack(wrec, buf)
+struct wlog_rec *wrec;
+char *buf;
+{
+ char *file, *host, *pattern;
+ struct wlog_rec_disk *wrecd;
+
+ memset((char *)wrec, 0x00, sizeof(struct wlog_rec));
+ wrecd = (struct wlog_rec_disk *)buf;
+
+ wrec->w_pid = wrecd->w_pid;
+ wrec->w_offset = wrecd->w_offset;
+ wrec->w_nbytes = wrecd->w_nbytes;
+ wrec->w_oflags = wrecd->w_oflags;
+ wrec->w_hostlen = wrecd->w_hostlen;
+ wrec->w_pathlen = wrecd->w_pathlen;
+ wrec->w_patternlen = wrecd->w_patternlen;
+ wrec->w_done = wrecd->w_done;
+ wrec->w_async = wrecd->w_async;
+
+ if (wrec->w_pathlen > 0) {
+ file = buf + sizeof(struct wlog_rec_disk);
+ memcpy(wrec->w_path, file, wrec->w_pathlen);
+ }
+
+ if (wrec->w_hostlen > 0) {
+ host = buf + sizeof(struct wlog_rec_disk) + wrec->w_pathlen;
+ memcpy(wrec->w_host, host, wrec->w_hostlen);
+ }
+
+ if (wrec->w_patternlen > 0) {
+ pattern = buf + sizeof(struct wlog_rec_disk) +
+ wrec->w_pathlen + wrec->w_hostlen;
+ memcpy(wrec->w_pattern, pattern, wrec->w_patternlen);
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/ltp_framework/runltp b/ltp_framework/runltp
new file mode 100755
index 0000000..65aea44
--- /dev/null
+++ b/ltp_framework/runltp
@@ -0,0 +1,1005 @@
+#!/bin/sh
+################################################################################
+## ##
+## Copyright (c) International Business Machines Corp., 2001 ##
+## ##
+## 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ##
+## ##
+################################################################################
+# File: runltp
+#
+# Description: This script can be used to the tests in the LTP test suite
+#
+# Authors: Manoj Iyer - manjo@mail.utexas.edu
+# Robbe Williamson - robbiew@us.ibm.com
+#
+# History: Oct 07 2003 - Modified - Manoj Iyer
+# - use functions
+# - clean up on script exit
+# - error checking etc.
+#
+# Oct 08 2003 - Modified - Manoj Iyer
+# - fixed bug in creating results directory
+# - all checks should be enlclosed in " " to avoid bash error
+# - exit with error if ltp-pan is not found in pan directory
+#
+# Jul 22 2007 - Modified - Ricardo Salveti de Araujo
+# - added support to put more then one file at CMDLINE (-f)
+# - added a new option, that the user can pass the address of
+# the command file, and it'll use wget to get it (-w)
+# - now -s does the grep at the selected command files (default,
+# -f or -w)
+#
+# Jul 23 2007 - Modified - Ricardo Salveti de Araujo
+# - added flag to get the command file that has all failed tests
+#
+# Sep 11 2007 - Modified - Subrata Modak
+# - added option to create Failed File if it is not an absolute path
+# - added option to create Output File if it is not an absolute path
+# - added option to create Failed File compulsory, even if user has not mentioned it
+#
+# Sep 14 2007 - Modified - Ricardo Salveti de Araujo
+# - cleaning and removing duplicated code
+#
+# Oct 27 2007 - Modified - Ricardo Salveti de Araujo and Subrata Modak
+# - better ways to integrate "ltp/tools/genload/stress" with "ltp/runltp"
+# Nov 24 2007 - Modified - Subrata Modak
+# - Added a new option to generate output in HTML format also. Also retaining
+# the original test format
+# Nov 28 2007 - Modified - Subrata Modak
+# - Added a new option to mail back LTP reports
+# May 19 2008 - Modified - Subrata Modak
+# - Added capability for default Log file generation
+# Aug 17 2009 - Modified - Subrata Modak
+# - Added Fault Injection generation Capability through -F Option
+#
+#################################################################################
+
+
+
+setup()
+{
+ sync
+ echo 3 > /proc/sys/vm/drop_caches
+ sync
+ echo 3 > /proc/sys/vm/drop_caches
+ sync
+ echo 3 > /proc/sys/vm/drop_caches
+
+ cd `dirname $0` || \
+ {
+ echo "FATAL: unable to change directory to $(dirname $0)"
+ exit 1
+ }
+ export LTPROOT=${PWD}
+ export TMPBASE="/tmp"
+ export PATH="${PATH}:${LTPROOT}/testcases/bin"
+ export BOARD=u8500
+ export MMC_MOUNTPOINT=/mnt/sdcard
+ export ONBOARD_EMMC_MOUNTPOINT=/mnt/onboardemmc
+ export ONBOARD_EMMC_NODE=/dev/mmcblk1p1
+
+ # various things required for some tests
+ mkdir -p /tmp /opt /proc /sys /proc /dev
+ mount -t proc proc /proc 2>/dev/null
+ mount -t sysfs nodev /sys 2>/dev/null
+
+ ln -s /dev /dev/misc 2>/dev/null
+ mdev -s 2>/dev/null
+ echo `which mdev` > /proc/sys/kernel/hotplug
+
+ touch /etc/hosts
+ [ -f /etc/hostid ] || echo 123 > /etc/hostid
+ mkdir -p /dev/shm && mount -t tmpfs nodev /dev/shm 2>/dev/null
+ ifconfig lo up
+
+
+ [ -d "$LTPROOT/testcases/bin" ] ||
+ {
+ echo "FATAL: LTP not installed correctly"
+ echo "INFO: Follow directions in INSTALL!"
+ exit 1
+ }
+
+ [ -e "$LTPROOT/bin/ltp-pan" ] ||
+ {
+ echo "FATAL: Test suite driver 'ltp-pan' not found"
+ echo "INFO: Follow directions in INSTALL!"
+ exit 1
+ }
+}
+
+version_of_ltp()
+{
+ cat "$LTPROOT/Version"
+ exit 0
+}
+
+usage()
+{
+ cat <<-EOF >&2
+
+ usage: ${0##*/} [ -a EMAIL_TO ] [ -c NUM_PROCS ] [ -C FAILCMDFILE ] [ -d TMPDIR ]
+ [ -D NUM_PROCS,NUM_FILES,NUM_BYTES,CLEAN_FLAG ] -e [ -f CMDFILES(,...) ] [ -g HTMLFILE]
+ [ -i NUM_PROCS ] [ -l LOGFILE ] [ -m NUM_PROCS,CHUNKS,BYTES,HANGUP_FLAG ]
+ -N -n [ -o OUTPUTFILE ] -p -q [ -r LTPROOT ] [ -s PATTERN ] [ -t DURATION ]
+ -v [ -w CMDFILEADDR ] [ -x INSTANCES ] [ -b DEVICE ] [-B DEVICE_FS_TYPE]
+ [ -F LOOPS,PERCENTAGE ]
+
+ -a EMAIL_TO EMAIL all your Reports to this E-mail Address
+ -c NUM_PROCS Run LTP under additional background CPU load
+ [NUM_PROCS = no. of processes creating the CPU Load by spinning over sqrt()
+ (Defaults to 1 when value)]
+ -C FAILCMDFILE Command file with all failed test cases.
+ -d TMPDIR Directory where temporary files will be created.
+ -D NUM_PROCS,NUM_FILES,NUM_BYTES,CLEAN_FLAG
+ Run LTP under additional background Load on Secondary Storage (Seperate by comma)
+ [NUM_PROCS = no. of processes creating Storage Load by spinning over write()]
+ [NUM_FILES = Write() to these many files (Defaults to 1 when value 0 or undefined)]
+ [NUM_BYTES = write these many bytes (defaults to 1GB, when value 0 or undefined)]
+ [CLEAN_FLAG = unlink file to which random data written, when value 1]
+ -e Prints the date of the current LTP release
+ -f CMDFILES Execute user defined list of testcases (separate with ',')
+ -F LOOPS,PERCENTAGE Induce PERCENTAGE Fault in the Kernel Subsystems, and, run each test for LOOPS loop
+ -g HTMLFILE Create an additional HTML output format
+ -h Help. Prints all available options.
+ -i NUM_PROCS Run LTP under additional background Load on IO Bus
+ [NUM_PROCS = no. of processes creating IO Bus Load by spinning over sync()]
+ -K DMESG_LOG_DIR
+ Log Kernel messages generated for each test cases inside this directory
+ -l LOGFILE Log results of test in a logfile.
+ -m NUM_PROCS,CHUNKS,BYTES,HANGUP_FLAG
+ Run LTP under additional background Load on Main memory (Seperate by comma)
+ [NUM_PROCS = no. of processes creating main Memory Load by spinning over malloc()]
+ [CHUNKS = malloc these many chunks (default is 1 when value 0 or undefined)]
+ [BYTES = malloc CHUNKS of BYTES bytes (default is 256MB when value 0 or undefined) ]
+ [HANGUP_FLAG = hang in a sleep loop after memory allocated, when value 1]
+ -M CHECK_TYPE
+ [CHECK_TYPE=1 => Full Memory Leak Check tracing children as well]
+ [CHECK_TYPE=2 => Thread Concurrency Check tracing children as well]
+ [CHECK_TYPE=3 => Full Memory Leak & Thread Concurrency Check tracing children as well]
+ -N Run all the networking tests.
+ -n Run LTP with network traffic in background.
+ -o OUTPUTFILE Redirect test output to a file.
+ -p Human readable format logfiles.
+ -q Print less verbose output to screen.
+ -r LTPROOT Fully qualified path where testsuite is installed.
+ -s PATTERN Only run test cases which match PATTERN.
+ -S SKIPFILE Skip tests specified in SKIPFILE
+ -t DURATION Execute the testsuite for given duration. Examples:
+ -t 60s = 60 seconds
+ -t 45m = 45 minutes
+ -t 24h = 24 hours
+ -t 2d = 2 days
+ -T REPETITION Execute the testsuite for REPETITION no. of times
+ -w CMDFILEADDR Uses wget to get the user's list of testcases.
+ -x INSTANCES Run multiple instances of this testsuite.
+ -b DEVICE Some tests require an unmounted block device
+ to run correctly.
+ -B DEVICE_FS_TYPE The file system of test block devices.
+
+
+ example: ${0##*/} -c 2 -i 2 -m 2,4,10240,1 -D 2,10,10240,1 -p -q -l /tmp/result-log.$$ -o /tmp/result-output.$$ -C /tmp/result-failed.$$ -d ${PWD}
+
+
+ EOF
+exit 0
+}
+
+main()
+{
+ local CMDFILES=""
+ local PRETTY_PRT=""
+ local ALT_DIR_OUT=0
+ local ALT_DIR_RES=0
+ local ALT_HTML_OUT=0
+ local ALT_EMAIL_OUT=0
+ local ALT_DMESG_OUT=0
+ local RUN_NETEST=0
+ local RUN_REPEATED=0
+ local QUIET_MODE=""
+ local NETPIPE=0
+ local GENLOAD=0
+ local MEMSIZE=0
+ local DURATION=""
+ local CMDFILEADDR=""
+ local FAILCMDFILE=""
+ local INJECT_KERNEL_FAULT=""
+ local INJECT_KERNEL_FAULT_PERCENTAGE=""
+ local INJECT_FAULT_LOOPS_PER_TEST=""
+ local VALGRIND_CHECK=""
+ local VALGRIND_CHECK_TYPE=""
+ local LOGFILE_NAME=""
+ local LOGFILE=""
+ local OUTPUTFILE_NAME=""
+ local OUTPUTFILE=""
+ local HTMLFILE_NAME=""
+ local HTMLFILE=""
+ local DMESG_DIR=""
+ local EMAIL_TO=""
+ local TAG_RESTRICT_STRING=""
+ local PAN_COMMAND=""
+ local DEFAULT_FILE_NAME_GENERATION_TIME=`date +"%Y_%b_%d-%Hh_%Mm_%Ss"`
+
+ local scenfile=
+
+ version_date=`head -n 1 $LTPROOT/ChangeLog`
+ kernel_version=`uname -r`
+
+ while getopts a:c:C:d:D:f:F:ehi:K:g:l:m:M:Nno:pqr:s:S:t:T:w:x:b:B: arg
+ do case $arg in
+ a) EMAIL_TO=$OPTARG
+ ALT_EMAIL_OUT=1;;
+ c)
+ NUM_PROCS=$(($OPTARG))
+ if [ "$NUM_PROCS" -eq 0 ]; then
+ # User Did not Define the Value ,or, User Defined Zero,
+ # hence, prevent from creating infinite processes
+ NUM_PROCS=1
+ fi
+ $LTPROOT/testcases/bin/genload --cpu $NUM_PROCS >/dev/null 2>&1 &
+ GENLOAD=1 ;;
+
+ C)
+ case $OPTARG in
+ /*)
+ FAILCMDFILE="-C $OPTARG" ;;
+ *)
+ FAILCMDFILE="-C $LTPROOT/output/$OPTARG"
+ ALT_DIR_OUT=1 ;;
+ esac ;;
+
+ d) # convert the user path to absolute path.
+ export TMPBASE=`cd \`dirname ${OPTARG}\`; pwd`/`basename ${OPTARG}` ;;
+
+ D) NUM_PROCS=1; NUM_FILES=1; NUM_BYTES=$((1024 * 1024 * 1024)); CLEAN_FLAG=0
+ ARGUMENT_LIST=$OPTARG
+ TOTAL_ARGUMENTS=1
+ for ARGUMENT in `echo "$ARGUMENT_LIST" | tr ',' ' '`
+ do
+ case $TOTAL_ARGUMENTS in
+ 1) NUM_PROCS="$ARGUMENT" ;;
+ 2) NUM_FILES="$ARGUMENT" ;;
+ 3) NUM_BYTES="$ARGUMENT" ;;
+ 4) CLEAN_FLAG="$ARGUMENT" ;;
+ esac
+ TOTAL_ARGUMENTS=`expr $TOTAL_ARGUMENTS + 1`
+ done
+ # just to get the default values if the user passed 0
+ if [ "$NUM_PROCS" -eq 0 ]; then
+ NUM_PROCS=1
+ fi
+ if [ "$NUM_FILES" -eq 0 ]; then
+ NUM_FILES=1
+ fi
+ if [ "$NUM_BYTES" -eq 0 ]; then
+ NUM_BYTES=$((1024 * 1024 * 1024))
+ fi
+ if [ "$CLEAN_FLAG" -ne 1 ]; then
+ CLEAN_FLAG=0
+ fi
+ if [ "$CLEAN_FLAG" -eq 1 ]; then
+ # Do not unlink file in this case
+ $LTPROOT/testcases/bin/genload --hdd $NUM_PROCS --hdd-files \
+ $NUM_FILES --hdd-bytes $NUM_BYTES >/dev/null 2>&1 &
+ else
+ # Cleanup otherwise
+ $LTPROOT/testcases/bin/genload --hdd $NUM_PROCS --hdd-files \
+ $NUM_FILES --hdd-bytes $NUM_BYTES --hdd-noclean >/dev/null 2>&1 &
+ fi
+ GENLOAD=1;;
+
+ e) # Print out the version of LTP
+ version_of_ltp
+ ;;
+ f) # Execute user defined set of testcases.
+ # Can be more then one file, just separate it with ',', like:
+ # -f nfs,commands,/tmp/testfile
+ CMDFILES=$OPTARG;;
+ F) INJECT_KERNEL_FAULT=1
+ #Seperate out the NO_OF_LOOPS & FAULT_PERCENTAGE
+ INJECT_FAULT_LOOPS_PER_TEST=`echo $OPTARG |cut -d',' -f1 | tr -d '\n' | tr -d ' '`
+ INJECT_KERNEL_FAULT_PERCENTAGE=`echo $OPTARG |cut -d',' -f2 | tr -d '\n' | tr -d ' '`
+ if [ ! $INJECT_FAULT_LOOPS_PER_TEST ]; then
+ echo "Loops not properly defined. Resorting to default 5..."
+ export INJECT_FAULT_LOOPS_PER_TEST=5
+ fi
+ if [ ! $INJECT_KERNEL_FAULT_PERCENTAGE ]; then
+ echo "Fault Persentage not properly defined. Resorting to default 10..."
+ export INJECT_KERNEL_FAULT_PERCENTAGE=10
+ fi;;
+ g) HTMLFILE_NAME="$OPTARG"
+ case $OPTARG in
+ /*)
+ HTMLFILE="$OPTARG";;
+ *)
+ HTMLFILE="$LTPROOT/output/$OPTARG";;
+ esac
+ ALT_DIR_OUT=1
+ ALT_HTML_OUT=1;;
+ h) usage;;
+
+ i)
+ NUM_PROCS=$(($OPTARG))
+ if [ "$NUM_PROCS" -eq 0 ]; then
+ # User Did not Define the Value ,or, User Defined Zero,
+ # hence, prevent from creating infinite processes
+ NUM_PROCS=1
+ fi
+ $LTPROOT/testcases/bin/genload --io $NUM_PROCS >/dev/null 2>&1 &
+ GENLOAD=1 ;;
+
+ K)
+ case $OPTARG in
+ /*)
+ DMESG_DIR="$OPTARG-dmesg-output-`echo $$-``date +%X | tr -d ' '`";;
+ *)
+ DMESG_DIR="$LTPROOT/output/$OPTARG-dmesg-output-`echo $$-``date +%X | tr -d ' '`";;
+ esac
+ mkdir -p $DMESG_DIR
+ ALT_DMESG_OUT=1;;
+ l)
+ LOGFILE_NAME="$OPTARG"
+ case $OPTARG in
+ /*)
+ LOGFILE="-l $OPTARG" ;;
+ *)
+ LOGFILE="-l $LTPROOT/results/$OPTARG"
+ ALT_DIR_RES=1 ;;
+ esac ;;
+
+ m) NUM_PROCS=1; CHUNKS=1; BYTES=$((256 * 1024 * 1024)); HANGUP_FLAG=0
+ ARGUMENT_LIST=$OPTARG
+ TOTAL_ARGUMENTS=1
+ for ARGUMENT in `echo "$ARGUMENT_LIST" | tr ',' ' '`
+ do
+ case $TOTAL_ARGUMENTS in
+ 1) NUM_PROCS="$ARGUMENT" ;;
+ 2) CHUNKS="$ARGUMENT" ;;
+ 3) BYTES="$ARGUMENT" ;;
+ 4) HANGUP_FLAG="$ARGUMENT" ;;
+ esac
+ TOTAL_ARGUMENTS=`expr $TOTAL_ARGUMENTS + 1`
+ done
+ # just to get the default values if the user passed 0
+ if [ "$NUM_PROCS" -eq 0 ]; then
+ NUM_PROCS=1
+ fi
+ if [ "$CHUNKS" -eq 0 ]; then
+ CHUNKS=1
+ fi
+ if [ "$BYTES" -eq 0 ]; then
+ BYTES=$((256 * 1024 * 1024))
+ fi
+ if [ "$HANGUP_FLAG" -ne 1 ]; then
+ HANGUP_FLAG=0
+ fi
+ if [ "$HANGUP_FLAG" -eq 1 ]; then
+ # Hang in a Sleep loop after memory allocated
+ $LTPROOT/testcases/bin/genload --vm $NUM_PROCS --vm-chunks \
+ $CHUNKS --vm-bytes $BYTES --vm-hang >/dev/null 2>&1 &
+ else
+ # Otherwise Do not Hangup
+ $LTPROOT/testcases/bin/genload --vm $NUM_PROCS --vm-chunks \
+ $CHUNKS --vm-bytes $BYTES >/dev/null 2>&1 &
+ fi
+ GENLOAD=1;;
+ M)
+ VALGRIND_CHECK=1
+ VALGRIND_CHECK_TYPE="$OPTARG";;
+
+ N) RUN_NETEST=1;;
+
+ n)
+ $LTPROOT/testcases/bin/netpipe.sh
+ NETPIPE=1;;
+
+ o) OUTPUTFILE_NAME="$OPTARG"
+ case $OPTARG in
+ /*)
+ OUTPUTFILE="-o $OPTARG";;
+ *)
+ OUTPUTFILE="-o $LTPROOT/output/$OPTARG"
+ ALT_DIR_OUT=1 ;;
+ esac ;;
+
+ p) PRETTY_PRT=" -p ";;
+
+ q) QUIET_MODE=" -q ";;
+
+ r) LTPROOT=$OPTARG;;
+
+ s) TAG_RESTRICT_STRING=$OPTARG;;
+
+ S) case $OPTARG in
+ /*)
+ SKIPFILE=$OPTARG;;
+ *)
+ SKIPFILE="$LTPROOT/$OPTARG";;
+ esac ;;
+
+ t) # In case you want to specify the time
+ # to run from the command line
+ # (2m = two minutes, 2h = two hours, etc)
+ DURATION="-t $OPTARG" ;;
+
+ T) # In case you want the testcases to runsequentially RUN_REPEATED times
+ RUN_REPEATED=$OPTARG;;
+
+ w) CMDFILEADDR=$OPTARG;;
+
+ x) # number of ltp's to run
+ cat <<-EOF >&1
+ WARNING: The use of -x can cause unpredictable failures, as a
+ result of concurrently running multiple tests designed
+ to be ran exclusively.
+ Pausing for 10 seconds..."
+ EOF
+ sleep 10
+ INSTANCES="-x $OPTARG";;
+ b) DEVICE=$OPTARG;;
+ B) DEVICE_FS_TYPE=$OPTARG;;
+ \?) usage;;
+ esac
+ done
+
+ ## It would be nice to create a default log file even if the user has not mentioned
+ if [ ! "$LOGFILE" ]; then ## User has not mentioned about Log File name
+ LOGFILE_NAME=$DEFAULT_FILE_NAME_GENERATION_TIME
+ LOGFILE="-l $LTPROOT/results/LTP_RUN_ON-$LOGFILE_NAME.log"
+ ALT_DIR_RES=1
+ PRETTY_PRT=" -p "
+ fi
+
+ ## It would be nice if a Failed File is compulsorily created (gives User better Idea of Tests that failed)
+
+ if [ ! "$FAILCMDFILE" ]; then ## User has not mentioned about Failed File name
+ ALT_DIR_OUT=1
+ if [ ! "$OUTPUTFILE" ]; then ## User has not mentioned about Output File name either
+ if [ ! "$LOGFILE" ]; then ## User has not mentioned about Log File name either
+ FAILED_FILE_NAME=$DEFAULT_FILE_NAME_GENERATION_TIME
+ FAILCMDFILE="-C $LTPROOT/output/LTP_RUN_ON-$FAILED_FILE_NAME.failed"
+ else ## User Fortunately wanted a log file,
+ FAILED_FILE_NAME=`basename $LOGFILE_NAME` ## Extract log file name and use it to construct Failed file name
+ FAILCMDFILE="-C $LTPROOT/output/LTP_RUN_ON-$FAILED_FILE_NAME.failed"
+ fi
+ else ## User Fortunately wanted a Output file
+ FAILED_FILE_NAME=`basename $OUTPUTFILE_NAME` ## Extract output file name and use it to construct Failed file name
+ FAILCMDFILE="-C $LTPROOT/output/LTP_RUN_ON-$FAILED_FILE_NAME.failed"
+ fi
+ fi
+
+ if [ "$ALT_HTML_OUT" -eq 1 ] ; then ## User wants the HTML version of the output
+ QUIET_MODE="" ## Suppressing this guy as it will prevent generation of proper output
+ ## which the HTML parser will require
+ if [ ! "$OUTPUTFILE" ]; then ## User has not mentioned about the Outputfile name, then we need to definitely generate one
+ OUTPUTFILE_NAME=$DEFAULT_FILE_NAME_GENERATION_TIME
+ OUTPUTFILE="-o $LTPROOT/output/LTP_RUN_ON-$OUTPUTFILE_NAME.output"
+ ALT_DIR_OUT=1
+ if [ ! "$HTMLFILE" ] ; then ## User has not mentioned HTML File name, We need to create one
+ HTMLFILE_NAME=`basename $OUTPUTFILE_NAME`
+ HTMLFILE="$LTPROOT/output/$HTMLFILE_NAME.html"
+ fi
+ fi
+ fi
+
+ # If we need, create the output directory
+ [ "$ALT_DIR_OUT" -eq 1 ] && \
+ {
+ [ ! -d $LTPROOT/output ] && \
+ {
+ echo "INFO: creating $LTPROOT/output directory"
+ mkdir -p $LTPROOT/output || \
+ {
+ echo "ERROR: failed to create $LTPROOT/output"
+ exit 1
+ }
+ }
+ }
+ # If we need, create the results directory
+ [ "$ALT_DIR_RES" -eq 1 ] && \
+ {
+ echo "INFO: creating $LTPROOT/results directory"
+ [ ! -d $LTPROOT/results ] && \
+ {
+ mkdir -p $LTPROOT/results || \
+ {
+ echo "ERROR: failed to create $LTPROOT/results"
+ exit 1
+ }
+ }
+ }
+
+ # Added -m 777 for tests that call tst_tmpdir() and try to
+ # write to it as user nobody
+ mkdir -m 777 -p $TMPBASE || \
+ {
+ echo "FATAL: Unable to make temporary directory $TMPBASE"
+ exit 1
+ }
+ # use mktemp to create "safe" temporary directories
+ export TMPTEMPLATE="${TMPBASE}/ltp-XXXXXXXXXX"
+ TMP=`mktemp -d $TMPTEMPLATE` || \
+ {
+ echo "FATAL: Unable to make temporary directory: $TMP"
+ exit 1
+ }
+ export TMP
+ # To be invoked by tst_tmpdir()
+ # write to it as user nobody
+ export TMPDIR=$TMP
+
+ chmod 777 $TMP || \
+ {
+ echo "unable to chmod 777 $TMP ... aborting"
+ exit 1
+ }
+
+ cd $TMP || \
+ {
+ echo "could not cd ${TMP} ... exiting"
+ exit 1
+ }
+
+ [ -n "$INSTANCES" ] && \
+ {
+ INSTANCES="$INSTANCES -O ${TMP}"
+ }
+
+ [ "$RUN_NETEST" -eq 1 ] && \
+ {
+ [ -z "$RHOST" ] || [ -z "$PASSWD" ] && \
+ {
+ [ -z "$RHOST" ] && \
+ {
+ echo \
+ "INFO: Enter RHOST = 'name of the remote host machine'"
+ echo -n "-> "
+ read RHOST
+ }
+
+ [ -z "$PASSWD" ] && \
+ {
+ echo " "
+ echo \
+ "INFO: Enter PASSWD = 'root passwd of the remote host machine'"
+ echo -n "-> "
+ read PASSWD
+ }
+ export RHOST=$RHOST
+ export PASSWD=$PASSWD
+ echo "WARNING: security of $RHOST may be compromised"
+ }
+ }
+
+ # If user does not provide a command file select a default set of testcases
+ # to execute.
+ if [ -z "$CMDFILES" ] && [ -z "$CMDFILEADDR" ]
+ then
+ cat <<-EOF >&1
+
+ INFO: no command files were provided. Will execute the following
+ runtest scenario files:
+
+`cat $LTPROOT/scenario_groups/default | tr '\012' ' '`
+
+ EOF
+
+ SCENARIO_LISTS="$LTPROOT/scenario_groups/default"
+ if [ "$RUN_NETEST" -eq 1 ]; then
+ SCENARIO_LISTS="$SCENARIO_LISTS $LTPROOT/scenario_groups/network"
+ fi
+
+ # DO NOT INDENT/DEDENT!
+ if [ -n "$SCENARIO_LISTS" ]; then
+ # Insurance to make sure that the first element in the pipe
+ # completed successfully.
+ cat_ok_sentinel=$TMP/cat_ok.$$
+ (cat $SCENARIO_LISTS && touch "$cat_ok_sentinel") | \
+ while read scenfile; do
+
+ scenfile=${LTPROOT}/runtest/$scenfile
+
+ # Skip over non-existent scenario files; things are
+ # robust enough now that the build will fail if these
+ # files don't exist.
+ [ -f "$scenfile" ] || continue
+
+ cat $scenfile >> "$TMP/alltests" || {
+ echo "FATAL: unable to append to command file"
+ rm -Rf "$TMP"
+ rm -f "$cat_ok_sentinel"
+ exit 1
+ }
+
+ done
+
+ rm -f "$cat_ok_sentinel"
+
+ fi
+ # ^^DO NOT INDENT/DEDENT!^^
+
+ fi
+
+ [ -n "$CMDFILES" ] && \
+ {
+ for scenfile in `echo "$CMDFILES" | tr ',' ' '`
+ do
+ [ -f "$scenfile" ] || scenfile="$LTPROOT/runtest/$scenfile"
+ cat "$scenfile" >> ${TMP}/alltests || \
+ {
+ echo "FATAL: unable to create command file"
+ rm -Rf "$TMP"
+ exit 1
+ }
+ done
+ }
+
+ [ -n "$CMDFILEADDR" ] && \
+ {
+ wget -q "${CMDFILEADDR}" -O ${TMP}/wgetcmdfile
+ if [ $? -ne 0 ]; then
+ echo "FATAL: error while getting the command file with wget (address $CMDFILEADDR)"
+ exit 1
+ fi
+ cat "${TMP}/wgetcmdfile" >> ${TMP}/alltests || \
+ {
+ echo "FATAL: unable to create command file"
+ exit 1
+ }
+ }
+
+ # The fsx-linux tests use the SCRATCHDEV environment variable as a location
+ # that can be reformatted and run on. Set SCRATCHDEV if you want to run
+ # these tests. As a safeguard, this is disabled.
+ unset SCRATCHDEV
+ [ -n "$SCRATCHDEV" ] && \
+ {
+ cat ${LTPROOT}/runtest/fsx >> ${TMP}/alltests ||
+ {
+ echo "FATAL: unable to create fsx-linux tests command file"
+ exit 1
+ }
+ }
+
+ # If enabled, execute only test cases that match the PATTERN
+ if [ -n "$TAG_RESTRICT_STRING" ]
+ then
+ mv -f ${TMP}/alltests ${TMP}/alltests.orig
+ grep $TAG_RESTRICT_STRING ${TMP}/alltests.orig > ${TMP}/alltests #Not worth checking return codes for this case
+ fi
+
+ # Blacklist or skip tests if a SKIPFILE was specified with -S
+ if [ -n "$SKIPFILE" ]
+ then
+ for file in $( cat $SKIPFILE ); do
+ sed -i "/^$file[ \t]/d" ${TMP}/alltests
+ done
+ fi
+
+ # check for required users and groups
+ ${LTPROOT}/IDcheck.sh &>/dev/null || \
+ {
+ echo "WARNING: required users and groups not present"
+ echo "WARNING: some test cases may fail"
+ }
+
+ # display versions of installed software
+ [ -z "$QUIET_MODE" ] && \
+ {
+ ${LTPROOT}/ver_linux || \
+ {
+ echo "WARNING: unable to display versions of software installed"
+ exit 1
+ }
+ }
+
+ if [ -n "$DEVICE" ]; then
+ sed -i "s|DEVICE|$DEVICE|" ${TMP}/alltests
+ else
+ echo "remove test cases which require the block device."
+ echo "You can specify it with option -b"
+ sed -i "/DEVICE/d" ${TMP}/alltests
+ fi
+
+ if [ $? -ne 0 ]; then
+ echo "FATAL: error during prcessing alltests file by sed"
+ exit 1
+ fi
+
+ if [ -n "$DEVICE" ]; then
+ mnt_pnt=`mktemp -d --tmpdir=${TMP} mnt_pnt.XXXXXX`
+ if [ -n "$DEVICE_FS_TYPE" ]; then
+ mount -t $DEVICE_FS_TYPE $DEVICE $mnt_pnt
+ else
+ mount $DEVICE $mnt_pnt
+ fi
+
+ if [ $? -ne 0 ]; then
+ echo "FATAL: can't mount block device $DEVICE."
+ exit 1
+ fi
+
+ if [ -z "$DEVICE_FS_TYPE" ]; then
+ DEVICE_FS_TYPE=`cat /proc/mounts | awk "{if (\\\$1 == \"$DEVICE\") print \\\$3; }"`
+ echo "determine file system $DEVICE_FS_TYPE on block device $DEVICE"
+ fi
+
+ umount $DEVICE
+ if [ $? -ne 0 ]; then
+ echo "FATAL: can't umount $DEVICE"
+ exit 1
+ fi
+ rm -rf $mnt_pnt
+ fi
+
+ if [ -n "$DEVICE" ]; then
+ sed -i "" -e "s|DEVICE_FS_TYPE|$DEVICE_FS_TYPE|" ${TMP}/alltests
+ fi
+
+ if [ $? -ne 0 ]; then
+ echo "FATAL: error during processing alltests file by sed"
+ exit 1
+ fi
+
+ if [ $RUN_REPEATED -gt 1 ]; then # You need to specify at least more than 1 sequential run, else it runs default
+ echo "PAN will run these test cases $RUN_REPEATED times....."
+ echo "Test Tags will be Prepended with ITERATION NO.s....."
+ inc=1
+ sed -e '/^$/ d' -e 's/^[ ,\t]*//' -e '/^#/ d' < ${TMP}/alltests > ${TMP}/alltests.temp ##This removes all newlines, leading spaces, tabs, #
+ sed 's/^[0-9,a-z,A-Z]*/'"$inc"'_ITERATION_&/' < ${TMP}/alltests.temp > ${TMP}/alltests ## .temp is kept as Base file
+ while [ $inc -lt $RUN_REPEATED ] ; do
+ inc=`expr $inc + 1`
+ sed 's/^[0-9,a-z,A-Z]*/'"$inc"'_ITERATION_&/' < ${TMP}/alltests.temp >> ${TMP}/alltests #Keep appending with Iteration No.s
+ done
+ fi
+
+ [ ! -z "$QUIET_MODE" ] && { echo "INFO: Test start time: $(date)" ; }
+ PAN_COMMAND="${LTPROOT}/bin/ltp-pan $QUIET_MODE -e -S $INSTANCES $DURATION -a $$ \
+ -n $$ $PRETTY_PRT -f ${TMP}/alltests $LOGFILE $OUTPUTFILE $FAILCMDFILE"
+ echo "COMMAND: $PAN_COMMAND"
+ if [ ! -z "$TAG_RESTRICT_STRING" ] ; then
+ echo "INFO: Restricted to $TAG_RESTRICT_STRING"
+ fi
+ #$PAN_COMMAND #Duplicated code here, because otherwise if we fail, only "PAN_COMMAND" gets output
+
+ ## Display the Output/Log/Failed/HTML file names here
+ echo -e "LOG File: \c"
+ echo $LOGFILE | cut -b4-
+
+ if [ "$OUTPUTFILE" ]; then
+ echo -e "OUTPUT File: \c"
+ echo $OUTPUTFILE | cut -b4-
+ fi
+
+ echo -e "FAILED COMMAND File: \c"
+ echo $FAILCMDFILE | cut -b4-
+
+ if [ "$HTMLFILE" ]; then
+ echo "HTML File: $HTMLFILE"
+ fi
+
+ echo "Running tests......."
+ test_start_time=$(date)
+
+ # User wants testing with Kernel Fault Injection
+ if [ $INJECT_KERNEL_FAULT ] ; then
+ #See if Debugfs is mounted, and
+ #Fault Injection Framework available through Debugfs
+ if [ -d "/sys/kernel/debug/fail_io_timeout" -o \
+ -d "/sys/kernel/debug/fail_make_request" -o \
+ -d "/sys/kernel/debug/fail_page_alloc" -o \
+ -d "/sys/kernel/debug/failslab" ]; then
+ #If atleast one of the Framework is available
+ #Go ahead to Inject Fault & Create required
+ #Command Files for LTP run
+ echo Running tests with Fault Injection Enabled in the Kernel...
+ ${LTPROOT}/bin/create_kernel_faults_in_loops_and_probability.pl\
+ ${TMP}/alltests $INJECT_FAULT_LOOPS_PER_TEST $INJECT_KERNEL_FAULT_PERCENTAGE > ${TMP}/alltests.tmp
+ cp ${TMP}/alltests.tmp ${TMP}/alltests
+ rm -rf ${TMP}/alltests.tmp
+ else
+ echo Fault Injection not enabled in the Kernel..
+ echo Running tests normally...
+ fi
+ fi
+
+ ## Valgrind Check will work only when Kernel Fault Injection is not expected,
+ ## We do not want to test Faults when valgrind is running
+ if [ $VALGRIND_CHECK ]; then
+ if [ ! $INJECT_KERNEL_FAULT ]; then
+ which valgrind || VALGRIND_CHECK_TYPE=XYZ
+ case $VALGRIND_CHECK_TYPE in
+ 1)
+ ${LTPROOT}/bin/create_valgrind_check.pl ${TMP}/alltests 1 > ${TMP}/alltests.tmp
+ cp ${TMP}/alltests.tmp ${TMP}/alltests
+ rm -rf ${TMP}/alltests.tmp;;
+ 2)
+ ${LTPROOT}/bin/create_valgrind_check.pl ${TMP}/alltests 2 > ${TMP}/alltests.tmp
+ cp ${TMP}/alltests.tmp ${TMP}/alltests
+ rm -rf ${TMP}/alltests.tmp;;
+ 3)
+ ${LTPROOT}/bin/create_valgrind_check.pl ${TMP}/alltests 3 > ${TMP}/alltests.tmp
+ cp ${TMP}/alltests.tmp ${TMP}/alltests
+ rm -rf ${TMP}/alltests.tmp;;
+ *) echo "Invalid Memory Check Type, or, Valgrind is not available";;
+ esac
+ fi
+ fi
+
+ if [ $ALT_DMESG_OUT -eq 1 ] ; then
+ #We want to print dmesg output for each test,lets do the trick inside the script
+ echo Enabling dmesg output logging for each test...
+ ${LTPROOT}/bin/create_dmesg_entries_for_each_test.pl ${TMP}/alltests $DMESG_DIR > ${TMP}/alltests.tmp
+ cp ${TMP}/alltests.tmp ${TMP}/alltests
+ rm -rf ${TMP}/alltests.tmp
+ fi
+ # Some tests need to run inside the "bin" directory.
+ cd "${LTPROOT}/testcases/bin"
+ "${LTPROOT}/bin/ltp-pan" $QUIET_MODE -e -S $INSTANCES $DURATION -a $$ -n $$ $PRETTY_PRT -f ${TMP}/alltests $LOGFILE $OUTPUTFILE $FAILCMDFILE
+
+ if [ $? -eq 0 ]; then
+ echo "INFO: ltp-pan reported all tests PASS"
+ VALUE=0
+ export LTP_EXIT_VALUE=0;
+ else
+ echo "INFO: ltp-pan reported some tests FAIL"
+ VALUE=1
+ export LTP_EXIT_VALUE=1;
+ fi
+ cd ..
+ echo "LTP Version: $version_date"
+
+ if [ $OUTPUTFILE_NAME ]; then
+ cd "${LTPROOT}/output"
+ echo "Kernel Version: $kernel_version" >> $OUTPUTFILE_NAME
+ echo "LTP Version: $version_date" >> $OUTPUTFILE_NAME
+ cd ..
+ fi
+
+ # $DMESG_DIR is used to cache messages obtained from dmesg after a test run.
+ # Proactively reap all of the 0-byte files in $DMESG_DIR as they have zero value
+ # and only clutter up the filesystem.
+
+ if [ $ALT_DMESG_OUT -eq 1 ] ; then
+ if ! find "$DMESG_DIR" -size 0 -exec rm {} + ; then
+ echo "cd to $DMESG_DIR failed: $?"
+ fi
+ if [ -n "$(ls "$DMESG_DIR")" ] ; then
+ echo "Kernel messages were generated for LTP tests $version_date"
+ else
+ echo "No Kernel messages were generated for LTP tests $version_date"
+ fi
+ fi
+
+ if [ "$ALT_HTML_OUT" -eq 1 ] ; then #User wants the HTML output to be created, it then needs to be generated
+ export LTP_VERSION=$version_date
+ export TEST_START_TIME=$test_start_time
+ export TEST_END_TIME=$(date)
+ OUTPUT_DIRECTORY=`echo $OUTPUTFILE | cut -c4-`
+ LOGS_DIRECTORY="$LTPROOT/results"
+ export TEST_OUTPUT_DIRECTORY="$LTPROOT/output"
+ export TEST_LOGS_DIRECTORY=$LOGS_DIRECTORY
+ echo "Generating HTML Output.....!!"
+ ( perl $LTPROOT/bin/genhtml.pl $LTPROOT/bin/html_report_header.txt test_start test_end test_output execution_status $OUTPUT_DIRECTORY > $HTMLFILE; )
+ echo "Generated HTML Output.....!!"
+ echo "Location: $HTMLFILE";
+
+ fi
+
+ if [ "$ALT_EMAIL_OUT" -eq 1 ] ; then ## User wants reports to be e-mailed
+ if [ [ ! "$HTMLFILE_NAME" ] -o [ ! "$OUTPUTFILE_NAME" ] -o [ ! "$LOGFILE_NAME" ] ] ; then
+ ##User does not have output/logs/html-output, nothing to be mailed in this situation
+ echo "Nothing to be mailed here...."
+ else
+ TAR_FILE_NAME=LTP_RUN_$version_date$DEFAULT_FILE_NAME_GENERATION_TIME.tar
+ if [ "$HTMLFILE_NAME" ] ; then ## HTML file Exists
+ if [ "$ALT_HTML_OUT" -ne 1 ] ; then ## The HTML file path is absolute and not $LTPROOT/output
+ mkdir -p $LTPROOT/output ## We need to create this Directory
+ cp $HTMLFILE_NAME $LTPROOT/output/
+ fi
+ fi
+ if [ "$OUTPUTFILE_NAME" ] ; then ## Output file exists
+ if [ "$ALT_DIR_OUT" -ne 1 ] ; then ## The Output file path is absolute and not $LTPROOT/output
+ mkdir -p $LTPROOT/output ## We need to create this Directory
+ cp $OUTPUTFILE_NAME $LTPROOT/output/
+ fi
+ fi
+ if [ "$LOGFILE_NAME" ] ; then ## Log file exists
+ if [ "$ALT_DIR_RES" -ne 1 ] ; then ## The Log file path is absolute and not $LTPROOT/results
+ mkdir -p $LTPROOT/results ## We need to create this Directory
+ cp $LOGFILE_NAME $LTPROOT/results/
+ fi
+ fi
+ if [ -d $LTPROOT/output ] ; then
+ tar -cf ./$TAR_FILE_NAME $LTPROOT/output
+ if [ $? -eq 0 ]; then
+ echo "Created TAR File: ./$TAR_FILE_NAME successfully, added $LTPROOT/output"
+ else
+ echo "Cannot Create TAR File: ./$TAR_FILE_NAME for adding $LTPROOT/output"
+ fi
+ fi
+ if [ -d $LTPROOT/results ] ; then
+ tar -uf ./$TAR_FILE_NAME $LTPROOT/results
+ if [ $? -eq 0 ]; then
+ echo "Updated TAR File: ./$TAR_FILE_NAME successfully, added $LTPROOT/results"
+ else
+ echo "Cannot Update TAR File: ./$TAR_FILE_NAME for adding $LTPROOT/results"
+ fi
+ fi
+ if [ -e $LTPROOT/nohup.out ] ; then ## If User would have Chosen nohup to do ltprun
+ tar -uf ./$TAR_FILE_NAME $LTPROOT/nohup.out
+ if [ $? -eq 0 ]; then
+ echo "Updated TAR File: ./$TAR_FILE_NAME successfully, added $LTPROOT/nohup.out"
+ else
+ echo "Cannot Update TAR File: ./$TAR_FILE_NAME for adding $LTPROOT/nohup.out"
+ fi
+ fi
+ gzip ./$TAR_FILE_NAME ## gzip this guy
+ if [ $? -eq 0 ]; then
+ echo "Gunzipped TAR File: ./$TAR_FILE_NAME"
+ else
+ echo "Cannot Gunzip TAR File: ./$TAR_FILE_NAME"
+ fi
+ if [ -e /usr/bin/mutt ] ; then ## This is a better mail client than others
+ echo "Starting mailing reports to: $EMAIL_TO, file: ./$TAR_FILE_NAME.gz"
+ mutt -a ./$TAR_FILE_NAME.gz -s "LTP Reports on $test_start_time" $EMAIL_TO < /dev/null
+ if [ $? -eq 0 ]; then
+ echo "Reports Successfully mailed to: $EMAIL_TO"
+ else
+ echo "Reports cannot be mailed to: $EMAIL_TO"
+ fi
+ else ## Use our Ageold mail program
+ echo "Starting mailing reports to: $EMAIL_TO, file: ./$TAR_FILE_NAME.gz"
+ uuencode ./$TAR_FILE_NAME.gz $TAR_FILE_NAME.gz | mail $EMAIL_TO -s "LTP Reports on $test_start_time"
+ if [ $? -eq 0 ]; then
+ echo "Reports Successfully mailed to: $EMAIL_TO"
+ else
+ echo "Reports cannot be mailed to: $EMAIL_TO"
+ fi
+ fi
+ fi
+ fi
+
+ [ ! -z "$QUIET_MODE" ] && { echo "INFO: Test end time: $(date)" ; }
+
+ [ "$GENLOAD" -eq 1 ] && { killall -9 genload >/dev/null 2>&1; }
+ [ "$NETPIPE" -eq 1 ] && { killall -9 NPtcp >/dev/null 2>&1; }
+
+ [ "$ALT_DIR_OUT" -eq 1 ] || [ "$ALT_DIR_RES" -eq 1 ] && \
+ {
+ cat <<-EOF >&1
+
+ ###############################################################"
+
+ Done executing testcases."
+ LTP Version: $version_date
+ ###############################################################"
+
+ EOF
+ }
+ exit $VALUE
+}
+
+cleanup()
+{
+ rm -rf ${TMP}
+}
+
+trap "cleanup" 0
+setup
+main "$@"
+
+#vim: syntax=sh
diff --git a/ltp_framework/ver_linux b/ltp_framework/ver_linux
new file mode 100755
index 0000000..71cbb08
--- /dev/null
+++ b/ltp_framework/ver_linux
@@ -0,0 +1,89 @@
+#!/bin/sh
+# Before running this script please ensure that your PATH is
+# typical as you use for compilation/istallation. I use
+# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
+# differ on your system.
+#
+PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH
+echo 'If some fields are empty or look unusual you may have an old version.'
+echo 'Compare to the current minimal requirements in Documentation/Changes.'
+echo ' '
+
+cat /etc/*release 2> /dev/null
+if [ $? = 1 ]; then
+ echo '/etc/issue:'
+ cat /etc/issue 2> /dev/null
+fi
+
+uname -a
+echo ' '
+
+echo "Gnu C " `gcc --version 2>/dev/null | head -n 1`
+
+make --version 2>&1 | awk -F, '{print $1}' | awk \
+ '/GNU Make/{print "Gnu make ",$NF}'
+
+ld -v 2>&1 | awk -F\) '{print $1}' | awk \
+ '/BFD/{print "binutils ",$NF}'
+
+fdformat --version 2>&1 | awk -F\- '{print "util-linux ", $NF}'
+
+mount --version 2>&1 | awk -F\- '{print "mount ", $NF}'
+
+insmod -V 2>&1 | awk 'NR==1 {print "modutils ",$NF}'
+
+tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \
+'NR==1 {print "e2fsprogs ", $2}'
+
+reiserfsck 2>&1 | grep reiserfsprogs | awk \
+'NR==1{print "reiserfsprogs ", $NF}'
+
+cardmgr -V 2>&1| grep version | awk \
+'NR==1{print "pcmcia-cs ", $3}'
+
+pppd --version 2>&1| grep version | awk \
+'NR==1{print "PPP ", $3}'
+
+isdnctrl 2>&1 | grep version | awk \
+'NR==1{print "isdn4k-utils ", $NF}'
+
+ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed \
+-e 's/\.so$//' | awk -F'[.-]' '{print "Linux C Library " \
+$(NF-2)"."$(NF-1)"."$NF}'
+
+ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -n 1 | awk \
+'NR==1{print "Dynamic linker (ldd) ", $NF}'
+
+ls -l /usr/lib/lib{g,stdc}++.so 2>/dev/null | awk -F. \
+ '{print "Linux C++ Library " $4"."$5"."$6}'
+
+ps --version 2>&1 | awk 'NR==1{print "Procps ", $NF}'
+
+ifconfig --version 2>&1 | grep tools | awk \
+'NR==1{print "Net-tools ", $NF}'
+
+ip -V 2>&1 | awk \
+'NR==1{print "iproute2 ", $NF}'
+
+# Kbd needs 'loadkeys -h',
+loadkeys -h 2>&1 | awk \
+'(NR==1 && ($3 !~ /option/)) {print "Kbd ", $3}'
+
+# while console-tools needs 'loadkeys -V'.
+loadkeys -V 2>&1 | awk \
+'(NR==1 && ($2 ~ /console-tools/)) {print "Console-tools ", $3}'
+
+expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}'
+
+if [ -e /proc/modules ]; then
+ X=`cat /proc/modules | sed -e "s/ .*$//"`
+ echo "Modules Loaded "$X
+fi
+
+echo
+echo 'free reports:'
+free
+
+echo
+echo '/proc/cpuinfo'
+cat /proc/cpuinfo