mirror of
https://github.com/apache/nuttx-apps.git
synced 2025-10-22 07:31:51 +08:00
examples/sotest: Add a test for shared libraries.
This commit is contained in:
247
examples/sotest/sotest_main.c
Normal file
247
examples/sotest/sotest_main.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/****************************************************************************
|
||||
* examples/sotest/sotest_main.c
|
||||
*
|
||||
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <dllfcn.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/drivers/ramdisk.h>
|
||||
#include <nuttx/binfmt/symtab.h>
|
||||
|
||||
#include "lib/romfs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Check configuration. This is not all of the configuration settings that
|
||||
* are required -- only the more obvious.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_LIBC_DLLFCN
|
||||
# error "You must select CONFIG_LIBC_DLLFCN in your configuration file"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_FS_ROMFS
|
||||
# error "You must select CONFIG_FS_ROMFS in your configuration file"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DISABLE_MOUNTPOINT
|
||||
# error "You must not disable mountpoints via CONFIG_DISABLE_MOUNTPOINT in your configuration file"
|
||||
#endif
|
||||
|
||||
/* Describe the ROMFS file system */
|
||||
|
||||
#define SECTORSIZE 64
|
||||
#define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
|
||||
#define MOUNTPT "/mnt/romfs"
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_SOTEST_DEVMINOR
|
||||
# define CONFIG_EXAMPLES_SOTEST_DEVMINOR 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_SOTEST_DEVPATH
|
||||
# define CONFIG_EXAMPLES_SOTEST_DEVPATH "/dev/ram0"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Symbols from Auto-Generated Code
|
||||
****************************************************************************/
|
||||
|
||||
extern const struct symtab_s exports[];
|
||||
extern const int nexports;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sotest_main
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
int main(int argc, FAR char *argv[])
|
||||
#else
|
||||
int sotest_main(int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
FAR void *handle;
|
||||
CODE void (*testfunc)(FAR const char *msg);
|
||||
FAR const char *msg;
|
||||
int ret;
|
||||
|
||||
/* Set the shared library symbol table */
|
||||
|
||||
ret = dlsymtab((FAR struct symtab_s *)exports, nexports);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: dlsymtab failed: %d\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Create a ROM disk for the ROMFS filesystem */
|
||||
|
||||
printf("main: Registering romdisk at /dev/ram%d\n",
|
||||
CONFIG_EXAMPLES_SOTEST_DEVMINOR);
|
||||
|
||||
ret = romdisk_register(CONFIG_EXAMPLES_SOTEST_DEVMINOR,
|
||||
(FAR uint8_t *)romfs_img,
|
||||
NSECTORS(romfs_img_len), SECTORSIZE);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* This will happen naturally if we registered the ROM disk previously. */
|
||||
|
||||
if (ret != -EEXIST)
|
||||
{
|
||||
fprintf(stderr, "ERROR: romdisk_register failed: %d\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("main: ROM disk already registered\n");
|
||||
}
|
||||
|
||||
/* Mount the file system */
|
||||
|
||||
printf("main: Mounting ROMFS filesystem at target=%s with source=%s\n",
|
||||
MOUNTPT, CONFIG_EXAMPLES_SOTEST_DEVPATH);
|
||||
|
||||
ret = mount(CONFIG_EXAMPLES_SOTEST_DEVPATH, MOUNTPT, "romfs", MS_RDONLY, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: mount(%s,%s,romfs) failed: %s\n",
|
||||
CONFIG_EXAMPLES_SOTEST_DEVPATH, MOUNTPT, errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Install the test shared library */
|
||||
|
||||
handle = dlopen(MOUNTPT "/sotest", RTLD_NOW | RTLD_LOCAL);
|
||||
if (handle == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: dlopen failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Get symbols testfunc1 and msg1 */
|
||||
|
||||
testfunc = (CODE void (*)(FAR const char *))dlsym(handle, "testfunc1");
|
||||
if (testfunc == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to get symbol \"testfunc1\"\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
msg = (FAR const char *)dlsym(handle, "g_msg1");
|
||||
if (msg == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to get symbol \"g_msg1\"\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Execute testfunc1 */
|
||||
|
||||
testfunc(msg);
|
||||
|
||||
/* Get symbols testfunc2 and msg2 */
|
||||
|
||||
testfunc = (CODE void (*)(FAR const char *))dlsym(handle, "testfunc2");
|
||||
if (testfunc == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to get symbol \"testfunc2\"\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
msg = (FAR const char *)dlsym(handle, "g_msg2");
|
||||
if (msg == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to get symbol \"g_msg2\"\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Execute testfunc2 */
|
||||
|
||||
testfunc(msg);
|
||||
|
||||
/* Get symbols testfunc3 and msg3 */
|
||||
|
||||
testfunc = (CODE void (*)(FAR const char *))dlsym(handle, "testfunc3");
|
||||
if (testfunc == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to get symbol \"testfunc3\"\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
msg = (FAR const char *)dlsym(handle, "g_msg3");
|
||||
if (msg == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to get symbol \"g_msg3\"\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Execute testfunc3 */
|
||||
|
||||
testfunc(msg);
|
||||
|
||||
ret = dlclose(handle);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: rmmod failed: %d\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = umount(MOUNTPT);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: umount(%s) failed: %d\n",
|
||||
MOUNTPT, errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user