提交 503534a5 编写于 作者: G goprife@gmail.com

remove uffs/sr/test code to reduce size of source

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2179 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 4bb93de5

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
SET (libapitest_server_SRCS
api_test.c
api_test.h
)
SET (libapitest_client_SRCS
api_test.c
api_test.h
api_test_client_wrapper.c
${uffs_SOURCE_DIR}/src/uffs/uffs_crc.c
)
IF (UNIX)
SET (libapitest_server_SRCS ${libapitest_server_SRCS} api_test_server_posix.c)
SET (libapitest_client_SRCS ${libapitest_client_SRCS} api_test_client_posix.c)
ENDIF()
IF (WIN32)
SET (libapitest_server_SRCS ${libapitest_server_SRCS} api_test_server_win32.c)
SET (libapitest_client_SRCS ${libapitest_client_SRCS} api_test_client_win32.c)
ENDIF()
SET (libapitest_sqlite3_SRCS
${libapitest_client_SRCS}
os_uffs.c
os_uffs.h
)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
ADD_LIBRARY(apitest_server STATIC ${libapitest_server_SRCS})
ADD_LIBRARY(apitest_client STATIC ${libapitest_client_SRCS})
IF (UNIX)
ADD_LIBRARY(apitest_sqlite3 SHARED ${libapitest_sqlite3_SRCS})
ENDIF()
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file api_srv.h
* \brief UFFS API test server definitions
* \author Ricky Zheng, created 16 Dec, 2011
*/
#include "uffs/uffs_types.h"
#include "uffs/uffs_fd.h"
#ifndef _UFFS_API_SRV_H_
#define _UFFS_API_SRV_H_
#define SRV_PORT 9018
#define UFFS_API_GET_VER_CMD 0
#define UFFS_API_OPEN_CMD 1
#define UFFS_API_CLOSE_CMD 2
#define UFFS_API_READ_CMD 3
#define UFFS_API_WRITE_CMD 4
#define UFFS_API_FLUSH_CMD 5
#define UFFS_API_SEEK_CMD 6
#define UFFS_API_TELL_CMD 7
#define UFFS_API_EOF_CMD 8
#define UFFS_API_RENAME_CMD 9
#define UFFS_API_REMOVE_CMD 10
#define UFFS_API_FTRUNCATE_CMD 11
#define UFFS_API_MKDIR_CMD 12
#define UFFS_API_RMDIR_CMD 13
#define UFFS_API_STAT_CMD 14
#define UFFS_API_LSTAT_CMD 15
#define UFFS_API_FSTAT_CMD 16
#define UFFS_API_OPEN_DIR_CMD 17
#define UFFS_API_CLOSE_DIR_CMD 18
#define UFFS_API_READ_DIR_CMD 19
#define UFFS_API_REWIND_DIR_CMD 20
#define UFFS_API_GET_ERR_CMD 21
#define UFFS_API_SET_ERR_CMD 22
#define UFFS_API_FORMAT_CMD 23
#define UFFS_API_SPACE_TOTAL_CMD 24
#define UFFS_API_SPACE_FREE_CMD 25
#define UFFS_API_SPACE_USED_CMD 26
#define UFFS_API_FLUSH_ALL_CMD 27
#define UFFS_API_CMD_LAST 27 // last test command id
#define UFFS_API_CMD(header) ((header)->cmd & 0xFF)
#define UFFS_API_ACK_BIT (1 << 31)
#define UFFS_API_MAX_PARAMS 8
struct uffs_ApiSrvMsgSt;
struct uffs_ApiSrvHeaderSt {
u32 cmd; // command
u32 data_len; // data length
u32 n_params; // parameter numbers
u32 param_size[UFFS_API_MAX_PARAMS]; // parameter list
u32 return_size[UFFS_API_MAX_PARAMS]; // return parameter list
u16 data_crc; // data CRC16
u16 header_crc; // header CRC16
};
struct uffs_ApiSrvIoSt {
int (*open)(void *addr);
int (*read)(int fd, void *buf, int len);
int (*write)(int fd, const void *buf, int len);
int (*close)(int fd);
void *addr;
};
struct uffs_ApiSt {
int (*uffs_version)(void);
int (*uffs_open)(const char *name, int oflag, ...);
int (*uffs_close)(int fd);
int (*uffs_read)(int fd, void *data, int len);
int (*uffs_write)(int fd, const void *data, int len);
int (*uffs_flush)(int fd);
long (*uffs_seek)(int fd, long offset, int origin);
long (*uffs_tell)(int fd);
int (*uffs_eof)(int fd);
int (*uffs_rename)(const char *old_name, const char *new_name);
int (*uffs_remove)(const char *name);
int (*uffs_ftruncate)(int fd, long remain);
int (*uffs_mkdir)(const char *name, ...);
int (*uffs_rmdir)(const char *name);
int (*uffs_stat)(const char *name, struct uffs_stat *buf);
int (*uffs_lstat)(const char *name, struct uffs_stat *buf);
int (*uffs_fstat)(int fd, struct uffs_stat *buf);
uffs_DIR * (*uffs_opendir)(const char *path);
int (*uffs_closedir)(uffs_DIR *dirp);
struct uffs_dirent * (*uffs_readdir)(uffs_DIR *dirp);
void (*uffs_rewinddir)(uffs_DIR *dirp);
int (*uffs_get_error)(void);
int (*uffs_set_error)(int err);
int (*uffs_format)(const char *mount_point);
long (*uffs_space_total)(const char *mount_point);
long (*uffs_space_used)(const char *mount_point);
long (*uffs_space_free)(const char *mount_point);
void (*uffs_flush_all)(const char *mount_point);
};
struct uffs_ApiSrvMsgSt {
struct uffs_ApiSrvHeaderSt header;
u8 *data;
};
int apisrv_setup_io(struct uffs_ApiSrvIoSt *io);
int apisrv_serve(int fd, struct uffs_ApiSt *api);
void apisrv_print_stat(void);
struct uffs_ApiSt * apisrv_get_client(void);
/* from api_test_server_{platform}.c */
int api_server_start(void);
/* from api_test_client_{platform}.c */
int api_client_init(const char *server_addr);
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file api_test_client_posix.c
* \brief API test client functions
* \author Ricky Zheng, created in 20 Dec, 2011
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include "uffs/uffs_fd.h"
#include "api_test.h"
static int _io_read(int fd, void *buf, int len)
{
return recv(fd, buf, len, MSG_WAITALL);
}
static int _io_write(int fd, const void *buf, int len)
{
return send(fd, buf, len, 0);
}
static int _io_open(void *addr)
{
int sock;
struct hostent *host;
struct sockaddr_in server_addr;
int port = SRV_PORT;
host = gethostbyname((const char *)addr);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Socket");
return -1;
}
if (getenv("UFFS_TEST_SRV_PORT")) {
port = atoi(getenv("UFFS_TEST_SRV_PORT"));
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
perror("Connect");
return -1;
}
return sock;
}
static int _io_close(int fd)
{
return close(fd);
}
static struct uffs_ApiSrvIoSt m_io = {
.open = _io_open,
.read = _io_read,
.write = _io_write,
.close = _io_close,
.addr = (void *)"127.0.0.1",
};
int api_client_init(const char *server_addr)
{
static char addr[128] = {0};
int ret = -1;
if (server_addr == NULL)
server_addr = getenv("UFFS_TEST_SRV_ADDR");
if (server_addr && strlen(server_addr) < sizeof(addr)) {
strcpy(addr, server_addr);
m_io.addr = (void *)addr;
}
ret = apisrv_setup_io(&m_io);
return ret;
}
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file api_test_client_win32.c
* \brief uffs API test client
* \author Ricky Zheng, 20 Dec 2011
*/
#include <stdlib.h>
#include <stdio.h>
#include "api_test.h"
int api_client_init(const char *server_addr)
{
printf("API test client not available on win32, stay tune ...\n");
return -1;
}
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file api_test_client_wrapper.c
* \brief API test client wrapper
* \author Ricky Zheng, created at 20 Dec, 2011
*/
#include "uffs/uffs_fd.h"
#include "api_test.h"
#define W(R, F, T, P) \
R F T \
{ \
return apisrv_get_client()->F P ; \
}
#define VW(F, T, P) \
void F T \
{ \
apisrv_get_client()->F P ; \
}
W(int, uffs_version, (), ())
W(int, uffs_open, (const char *name, int oflag, ...), (name, oflag))
W(int, uffs_close, (int fd), (fd))
W(int, uffs_read, (int fd, void *data, int len), (fd, data, len))
W(int, uffs_write, (int fd, const void *data, int len), (fd, data, len))
W(int, uffs_flush, (int fd), (fd))
W(long, uffs_seek, (int fd, long offset, int origin), (fd, offset, origin))
W(long, uffs_tell, (int fd), (fd))
W(int, uffs_eof, (int fd), (fd))
W(int, uffs_rename, (const char *oldname, const char *newname), (oldname, newname))
W(int, uffs_remove, (const char *name), (name))
W(int, uffs_ftruncate, (int fd, long remain), (fd, remain))
W(int, uffs_mkdir, (const char *name, ...), (name))
W(int, uffs_rmdir, (const char *name), (name))
W(int, uffs_stat, (const char *name, struct uffs_stat *buf), (name, buf))
W(int, uffs_lstat, (const char *name, struct uffs_stat *buf), (name, buf))
W(int, uffs_fstat, (int fd, struct uffs_stat *buf), (fd, buf))
W(uffs_DIR *, uffs_opendir, (const char *path), (path))
W(int, uffs_closedir, (uffs_DIR *dirp), (dirp))
W(struct uffs_dirent *, uffs_readdir, (uffs_DIR *dirp), (dirp))
VW(uffs_rewinddir, (uffs_DIR *dirp), (dirp))
W(int, uffs_get_error, (void), ())
W(int, uffs_set_error, (int err), (err))
W(int, uffs_format, (const char *mount), (mount))
W(long, uffs_space_total, (const char *mount), (mount))
W(long, uffs_space_used, (const char *mount), (mount))
W(long, uffs_space_free, (const char *mount), (mount))
VW(uffs_flush_all, (const char *mount), (mount))
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file api_test_server_posix.c
* \brief uffs API test server.
* \author Ricky Zheng
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include "uffs/uffs_os.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_mtb.h"
#include "uffs/uffs_crc.h"
#include "uffs/uffs_fd.h"
#include "uffs/uffs_version.h"
#include "api_test.h"
#define PFX NULL
#define BACKLOGS 100
#define WORKER_THREAD_NUM 10
#define WORKER_FIFO_SIZE 30
static pthread_mutex_t m_fifo_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t m_fifo_space_avail = PTHREAD_COND_INITIALIZER;
static pthread_cond_t m_fifo_fd_avail = PTHREAD_COND_INITIALIZER;
static int m_fifo[WORKER_FIFO_SIZE];
static int m_fifo_head = 0;
static int m_fifo_tail = 0;
static int m_thread_stat[WORKER_THREAD_NUM];
static void push_fifo(int fd)
{
pthread_mutex_lock(&m_fifo_lock);
if (((m_fifo_head + 1) % WORKER_FIFO_SIZE) != m_fifo_tail) {
m_fifo[m_fifo_head++] = fd;
m_fifo_head = m_fifo_head % WORKER_FIFO_SIZE;
pthread_cond_signal(&m_fifo_fd_avail);
}
else {
pthread_cond_wait(&m_fifo_space_avail, &m_fifo_lock);
}
pthread_mutex_unlock(&m_fifo_lock);
}
static int pop_fifo(void)
{
int fd = -1;
pthread_mutex_lock(&m_fifo_lock);
if (m_fifo_head == m_fifo_tail) {
pthread_cond_wait(&m_fifo_fd_avail, &m_fifo_lock);
}
else {
fd = m_fifo[m_fifo_tail++];
m_fifo_tail = m_fifo_tail % WORKER_FIFO_SIZE;
pthread_cond_signal(&m_fifo_space_avail);
}
pthread_mutex_unlock(&m_fifo_lock);
return fd;
}
static int _io_read(int fd, void *buf, int len)
{
return recv(fd, buf, len, MSG_WAITALL);
}
static int _io_write(int fd, const void *buf, int len)
{
return send(fd, buf, len, 0);
}
static int _io_close(int fd)
{
return close(fd);
}
static struct uffs_ApiSrvIoSt m_io = {
.read = _io_read,
.write = _io_write,
.close = _io_close,
};
static struct uffs_ApiSt m_api = {
uffs_version,
uffs_open,
uffs_close,
uffs_read,
uffs_write,
uffs_flush,
uffs_seek,
uffs_tell,
uffs_eof,
uffs_rename,
uffs_remove,
uffs_ftruncate,
uffs_mkdir,
uffs_rmdir,
uffs_stat,
uffs_lstat,
uffs_fstat,
uffs_opendir,
uffs_closedir,
uffs_readdir,
uffs_rewinddir,
uffs_get_error,
uffs_set_error,
uffs_format,
uffs_space_total,
uffs_space_used,
uffs_space_free,
uffs_flush_all,
};
static void * worker_thread_fn(void *param)
{
int fd;
size_t id;
id = (size_t)param;
while (1) {
fd = pop_fifo();
if (fd >= 0) {
apisrv_serve(fd, &m_api);
close(fd);
m_thread_stat[id]++;
}
}
return NULL;
}
static void create_worker_threads(void)
{
static pthread_t worker_threads[WORKER_THREAD_NUM];
int i;
for (i = 0; i < WORKER_THREAD_NUM; i++) {
pthread_create(&worker_threads[i], NULL, worker_thread_fn, (void *)((size_t)i));
}
}
static void print_worker_thread_stat(void)
{
int i;
printf("--- thread stat start ---\n");
for (i = 0; i < WORKER_THREAD_NUM; i++) {
printf("Thread %2d: %d\n", i, m_thread_stat[i]);
}
printf("--- thread stat end --\n");
}
static void *api_server_main_thread(void *param)
{
int srv_fd = -1, new_fd = -1;
struct sockaddr_in my_addr;
struct sockaddr_in peer_addr;
socklen_t sin_size;
int yes = 1;
int ret = 0;
int port = SRV_PORT;
srv_fd = socket(AF_INET, SOCK_STREAM, 0);
if (srv_fd < 0) {
perror("create srv socket error");
ret = -1;
goto ext;
}
if (getenv("UFFS_TEST_SRV_PORT")) {
port = atoi(getenv("UFFS_TEST_SRV_PORT"));
}
memset(&my_addr, 0, sizeof(struct sockaddr_in));
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(port); /* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 0.0.0.0 */
/* "Address already in use" error message */
ret = setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
if (ret < 0) {
perror("setsockopt() error");
goto ext;
}
ret = bind(srv_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
if (ret < 0) {
perror("Server-bind() error");
goto ext;
}
ret = listen(srv_fd, BACKLOGS);
if (ret < 0) {
perror("listen() error");
goto ext;
}
sin_size = sizeof(struct sockaddr_in);
apisrv_setup_io(&m_io);
create_worker_threads();
do {
new_fd = accept(srv_fd, (struct sockaddr *)&peer_addr, &sin_size);
if (new_fd >= 0) {
push_fifo(new_fd);
}
} while (ret >= 0);
ext:
if (srv_fd >= 0)
close(srv_fd);
return param;
}
int api_server_start(void)
{
static int started = 0;
pthread_t main_thread;
int ret = 0;
if (!started) {
started = 1;
ret = pthread_create(&main_thread, NULL, api_server_main_thread, NULL);
}
else {
apisrv_print_stat();
print_worker_thread_stat();
printf("apisrv already started.\n");
}
return ret;
}
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file api_test_server_win32.c
* \brief uffs API test server.
* \author Ricky Zheng
*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include "api_test.h"
#pragma comment(lib, "Ws2_32.lib")
#define BACKLOGS 10
static int _io_read(int fd, void *buf, int len)
{
return recv((SOCKET)fd, buf, len, 0);
}
static int _io_write(int fd, const void *buf, int len)
{
return send((SOCKET)fd, buf, len, 0);
}
static int _io_close(int fd)
{
closesocket((SOCKET)fd);
return 0;
}
static struct uffs_ApiSrvIoSt m_io = {
NULL, // open
_io_read,
_io_write,
_io_close,
};
static struct uffs_ApiSt m_api = {
uffs_version,
uffs_open,
uffs_close,
uffs_read,
uffs_write,
uffs_flush,
uffs_seek,
uffs_tell,
uffs_eof,
uffs_rename,
uffs_remove,
uffs_ftruncate,
uffs_mkdir,
uffs_rmdir,
uffs_stat,
uffs_lstat,
uffs_fstat,
uffs_opendir,
uffs_closedir,
uffs_readdir,
uffs_rewinddir,
uffs_get_error,
uffs_set_error,
uffs_format,
uffs_space_total,
uffs_space_used,
uffs_space_free,
uffs_flush_all,
};
int api_server_start(void)
{
int iResult;
int ret;
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
char port_buf[16];
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return -1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
sprintf_s(port_buf, sizeof(port_buf), "%d", SRV_PORT);
iResult = getaddrinfo("0.0.0.0", port_buf, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
ret = -1;
goto ext;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
ret = -1;
goto ext;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
ret = -1;
goto ext;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
ret = -1;
goto ext;
}
apisrv_setup_io(&m_io);
ret = -1;
do {
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
continue;
}
ret = apisrv_serve((int)ClientSocket, &m_api);
closesocket(ClientSocket);
} while (ret >= 0);
ext:
WSACleanup();
return ret;
}
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file os_uffs.c
* \brief This file is for interfacing UFFS to sqlite3 UNIX VFS, so that we
* can use sqlite3's test case to test out UFFS.
*
* \author Ricky Zheng, created at 22 Dec, 2011
*/
#define _GNU_SOURCE
#define _XOPEN_SOURCE 500
#include "uffs/uffs_types.h"
#include "uffs/uffs_fd.h"
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "api_test.h"
#if 1
#define DBG(args...) \
do { \
printf(args); \
fflush(stdout); \
} while(0)
#else
#define DBG(...) do{}while(0)
#endif
#define ASSERT(cond, fmt, ...) \
do { \
if (!(cond)) { \
printf("Assert (" #cond ") fail at %s:%s:%d: ", __FILE__, __FUNCTION__, __LINE__); \
printf(fmt, ## __VA_ARGS__); \
fflush(stdout); \
exit(1); \
} \
} while (0)
#define MAX_OPEN_FDS 50
struct fdmap_s {
int unix_fd;
int uffs_fd;
int bak_fd;
char name[256];
int valid;
};
static struct fdmap_s m_fdmap[MAX_OPEN_FDS];
static struct fdmap_s m_fdmap_ext[MAX_OPEN_FDS];
static pthread_mutex_t m_fdmap_mutex = PTHREAD_MUTEX_INITIALIZER;
#define LOCK() pthread_mutex_lock(&m_fdmap_mutex)
#define UNLOCK() pthread_mutex_unlock(&m_fdmap_mutex)
static const char * get_uffs_name(const char *unix_name)
{
const char *p = NULL;
if (unix_name) {
p = (char *)unix_name + strlen(unix_name) - 1;
for (; *p != '/' && p > unix_name; p--);
}
return p;
}
#define FOR_EACH_FD(s, map, p) \
for (p = &map[0], s = &map[MAX_OPEN_FDS]; p < s; p++) \
if (p->valid)
static void open_check_fd(int unix_fd, int uffs_fd, const char *unix_name)
{
int n = 0;
struct fdmap_s *s, *p;
LOCK();
FOR_EACH_FD(s, m_fdmap, p) {
if (p->unix_fd == unix_fd &&
strcmp(p->name, unix_name) == 0)
n++;
}
FOR_EACH_FD(s, m_fdmap_ext, p) {
if (p->unix_fd == unix_fd &&
strcmp(p->name, unix_name) == 0)
n++;
}
UNLOCK();
ASSERT(n == 1, "unix fd %d (name= %s) have %d entries\n", unix_fd, unix_name, n);
if (uffs_fd >= 0) {
n = 0;
LOCK();
FOR_EACH_FD(s, m_fdmap, p) {
if (p->uffs_fd == uffs_fd &&
strcmp(get_uffs_name(p->name), get_uffs_name(unix_name)) == 0)
n++;
}
UNLOCK();
ASSERT(n == 1, "uffs fd %d (name = %s) have %d entries\n", uffs_fd, get_uffs_name(unix_name), n);
}
}
static void unlink_check_fd(const char *unix_name)
{
struct fdmap_s *s, *p;
LOCK();
FOR_EACH_FD(s, m_fdmap, p) {
if (strcmp(p->name, unix_name) == 0) {
// there file already open ? close it ...
DBG("WARNING: unlink %s, but file is not closed ?\n", unix_name);
}
}
FOR_EACH_FD(s, m_fdmap_ext, p) {
if (strcmp(p->name, unix_name) == 0) {
DBG("WARNING: unlink %s, but file is not closed ?\n", unix_name);
}
}
UNLOCK();
}
// return 0 if not in skip table, else return non-zero.
static int check_skip_tbl(const char *path)
{
static const char *skip_tbl[] = {
"/dev/", "/var/", "/tmp/", "/proc/", "/usr/", "/lib/", "/opt/", "/bin/", NULL /* end */
};
int i = 0;
for (i = 0; skip_tbl[i] != NULL; i++) {
if (memcmp(path, skip_tbl[i], strlen(skip_tbl[i])) == 0)
return 1;
}
return 0;
}
static int unix2uffs(int unix_fd, int *uffs_fd, int *bak_fd)
{
int ret = -1;
struct fdmap_s *s, *p;
LOCK();
FOR_EACH_FD(s, m_fdmap, p) {
if (p->unix_fd == unix_fd) {
if (*uffs_fd)
*uffs_fd = p->uffs_fd;
if (bak_fd)
*bak_fd = p->bak_fd;
ret = 0;
break;
}
}
UNLOCK();
return ret;
}
static int push_newfd(const char *unix_name, int unix_fd, int uffs_fd, int bak_fd)
{
int ret = -1;
struct fdmap_s *p, *end;
if (unix_fd < 0)
return -1;
if (uffs_fd >= 0) {
p = &m_fdmap[0];
end = &m_fdmap[MAX_OPEN_FDS];
}
else {
p = &m_fdmap_ext[0];
end = &m_fdmap_ext[MAX_OPEN_FDS];
}
LOCK();
while (p < end) {
if (!p->valid) {
p->unix_fd = unix_fd;
p->uffs_fd = uffs_fd;
p->bak_fd = bak_fd;
strcpy(p->name, unix_name);
p->valid = 1;
ret = 0;
DBG("push_newfd(unix_fd = %d, uffs_fd = %d, bak_fd = %d)\n", unix_fd, uffs_fd, bak_fd);
break;
}
p++;
}
UNLOCK();
return ret;
}
static int remove_fd(int unix_fd)
{
int ret = -1;
struct fdmap_s *s, *p;
LOCK();
FOR_EACH_FD(s, m_fdmap, p) {
if (p->unix_fd == unix_fd) {
p->valid = 0;
ret = 0;
DBG("remove_fd(unix_fd = %d), uffs_fd = %d, bak_fd = %d\n", unix_fd, p->uffs_fd, p->bak_fd);
break;
}
}
if (ret != 0) {
FOR_EACH_FD(s, m_fdmap_ext, p) {
if (p->unix_fd == unix_fd) {
p->valid = 0;
ret = 0;
DBG("remove_fd(unix_fd = %d), no uffs_fd\n", unix_fd);
break;
}
}
}
UNLOCK();
return ret;
}
int os_open(const char *name, int flags, int mode)
{
int fd = -1;
int uffs_fd = -1, uffs_flags = 0;
int bak_fd = -1;
const char *p;
char bak_name[256] = {0};
fd = open(name, flags, mode);
if (check_skip_tbl(name) == 0 && fd >= 0) {
uffs_flags = 0;
if (flags & O_WRONLY) uffs_flags |= UO_WRONLY;
if (flags & O_RDWR) uffs_flags |= UO_RDWR;
if (flags & O_CREAT) uffs_flags |= UO_CREATE;
if (flags & O_TRUNC) uffs_flags |= UO_TRUNC;
if (flags & O_EXCL) uffs_flags |= UO_EXCL;
p = get_uffs_name(name);
uffs_fd = uffs_open(p, uffs_flags);
if (uffs_fd >= 0) {
sprintf(bak_name, "bak%s", p);
bak_fd = open(bak_name, flags, mode);
}
// sqlite3 testing script might delete test.db file outside the control of sqlite lib,
// so we need to detect that situation.
if ( /* strcmp(p, "/test.db") == 0 && */ uffs_fd >= 0 && (flags & O_CREAT)) {
ASSERT(bak_fd >= 0, "bak name = %s, bak fd = %d\n", bak_name, bak_fd);
struct stat sbuf;
if (fstat(fd, &sbuf) == 0 && sbuf.st_size == 0) {
// "test.db" file just been created, we should also do that on UFFS as well
uffs_ftruncate(uffs_fd, 0);
ftruncate(bak_fd, 0);
}
}
}
if (fd > 0) {
ASSERT(!push_newfd(name, fd, uffs_fd, bak_fd), "push_newfd(fd=%d, uffs_fd=%d, bak_fd=%d)\n", fd, uffs_fd, bak_fd);
open_check_fd(fd, uffs_fd, name);
}
DBG("open(name = \"%s\", flags = 0x%x, mode = 0x%x) = %d %s\n", name, flags, mode, fd, uffs_fd >= 0 ? "U" : "");
return fd;
}
int os_unlink(const char *name)
{
int ret = -1, uffs_ret = -1, bak_ret = -1;
const char *p = NULL;
char bak_name[256];
if (name) {
unlink_check_fd(name);
ret = unlink(name);
if (check_skip_tbl(name) == 0) {
p = get_uffs_name(name);
uffs_ret = uffs_remove(p);
sprintf(bak_name, "bak%s", p);
bak_ret = unlink(bak_name);
ASSERT(uffs_ret == ret && ret == bak_ret, "unlink(\"%s\"), unix return %d, uffs return %d, bak return %d\n", name, ret, uffs_ret, bak_ret);
}
}
DBG("unlink(name = \"%s\") = %d %s\n", name, ret, p ? "U" : "");
return ret;
}
int os_close(int fd)
{
int uffs_fd = -1, bak_fd = -1;
int ret = -1;
int x = -1;
if (fd >= 0) {
unix2uffs(fd, &uffs_fd, &bak_fd);
if (uffs_fd >= 0) {
uffs_close(uffs_fd);
}
if (bak_fd >= 0)
close(bak_fd);
x = remove_fd(fd);
//ASSERT(!x, "remove_fd(%d) failed.\n", fd);
ret = close(fd);
}
DBG("close(fd = %d) = %d %s\n", fd, ret, uffs_fd >= 0 ? "U" : "");
return ret;
}
int os_read(int fd, void *buf, int len)
{
int uffs_fd = -1, uffs_ret = -1, bak_fd = -1, bak_ret = -1;
int ret = -1;
void *uffs_buf = NULL;
void *bak_buf = NULL;
int i;
unsigned char a,b,c;
if (fd >= 0) {
unix2uffs(fd, &uffs_fd, &bak_fd);
if (uffs_fd >= 0) {
uffs_buf = malloc(len);
bak_buf = malloc(len);
ASSERT(uffs_buf != NULL || bak_buf == NULL, "malloc(%d) failed.\n", len);
uffs_ret = uffs_read(uffs_fd, uffs_buf, len);
bak_ret = read(bak_fd, bak_buf, len);
}
ret = read(fd, buf, len);
if (uffs_fd >= 0) {
ASSERT(ret == uffs_ret && uffs_ret == bak_ret, "read(fd=%d/%d/%d,buf,len=%d), unix return %d, uffs return %d, bak return %d\n", fd, uffs_fd, bak_fd, len, ret, uffs_ret, bak_ret);
//assert(memcmp(buf, uffs_buf, len) == 0);
if (ret > 0) {
if (memcmp(buf, uffs_buf, ret) != 0) {
DBG("ERR: read result different! from fd = %d/%d, len = %d, ret = %d\n", fd, uffs_fd, len, ret);
printf("\t POS unix uffs bak\n");
for (i = 0; i < len; i++) {
a = *(((char *)buf) + i);
b = *(((char *)uffs_buf) + i);
c = *(((char *)bak_buf) + i);
printf("\t0x%08d: 0x%02x 0x%02x 0x%02x%s\n", i, a, b, c, a == b && b == c ? "" : " <----");
}
fflush(stdout);
assert(0);
}
}
}
}
if (uffs_buf)
free(uffs_buf);
if (bak_buf)
free(bak_buf);
DBG("read(fd = %d, buf = {...}, len = %d) = %d %s\n", fd, len, ret, uffs_fd >= 0 ? "U" : "");
return ret;
}
int os_write(int fd, const void *buf, int len)
{
int uffs_fd = -1, uffs_ret = -1, bak_fd = -1, bak_ret = -1;
int ret = -1;
if (fd >= 0) {
unix2uffs(fd, &uffs_fd, &bak_fd);
if (uffs_fd >= 0) {
uffs_ret = uffs_write(uffs_fd, buf, len);
ASSERT(bak_fd >= 0, "uffs_fd = %d, bak_fd = %d\n", uffs_fd, bak_fd);
bak_ret = write(bak_fd, buf, len);
}
ret = write(fd, buf, len);
if (uffs_fd >= 0) {
ASSERT(ret == uffs_ret && ret == bak_ret, "write(fd=%d/%d/%d,buf,len=%d), unix return %d, uffs return %d, bak return %d\n", fd, uffs_fd, bak_fd, len, ret, uffs_ret, bak_ret);
}
}
DBG("write(fd = %d, buf = {...}, len = %d) = %d %s\n", fd, len, ret, uffs_fd >= 0 ? "U" : "");
return ret;
}
int os_lseek(int fd, long offset, int origin)
{
long ret = -1;
int uffs_fd = -1, bak_fd = -1;
long uffs_ret = -1L, bak_ret = -1L;
int uffs_origin = 0;
if (fd >= 0) {
unix2uffs(fd, &uffs_fd, &bak_fd);
if (uffs_fd >= 0) {
if (origin == SEEK_CUR)
uffs_origin = USEEK_CUR;
else if (origin == SEEK_SET)
uffs_origin = USEEK_SET;
else if (origin == SEEK_END)
uffs_origin = USEEK_END;
uffs_ret = uffs_seek(uffs_fd, offset, uffs_origin);
bak_ret = lseek(bak_fd, offset, origin);
}
ret = lseek(fd, offset, origin);
if (uffs_fd >= 0) {
ASSERT(ret == uffs_ret && ret == bak_ret, "lseek(fd=%d/%d/%d, offset=%ld, origin=%d), unix return %ld, uffs return %ld, bak return %ld\n", fd, uffs_fd, bak_fd, offset, origin, ret, uffs_ret, bak_ret);
}
}
DBG("lseek(fd = %d, offset = %ld, origin = %d) = %ld %s\n", fd, offset, origin, ret, uffs_fd >= 0 ? "U" : "");
return ret;
}
int os_pread(int fd, void *buf, int count, long offset)
{
DBG("pread(fd = %d, buf = {...}, count = %d, offset = %ld)\n", fd, count, offset);
assert(0);
return pread(fd, buf, count, offset);
}
int os_pwrite(int fd, const void *buf, int count, long offset)
{
DBG("pwrite(fd = %d, buf = {..}, count = %d, offset = %ld)\n", fd, count, offset);
assert(0);
return pwrite(fd, buf, count, offset);
}
int os_ftruncate(int fd, long length)
{
int uffs_fd = -1, uffs_ret = -1, bak_fd = -1, bak_ret = -1;
int ret = -1;
if (fd >= 0) {
unix2uffs(fd, &uffs_fd, &bak_fd);
ret = ftruncate(fd, length);
if (uffs_fd >= 0) {
uffs_ret = uffs_ftruncate(uffs_fd, length);
bak_ret = ftruncate(bak_fd, length);
ASSERT(ret == uffs_ret && ret == bak_ret,
"ftruncate(fd=%d/%d/%d, length=%ld), unix ret %d, uffs ret %d, bak ret %d\n",
fd, uffs_fd, bak_fd, length, ret, uffs_ret, bak_ret);
}
}
DBG("ftruncate(fd = %d, length = %ld) = %d %s\n", fd, length, ret, uffs_fd >= 0 ? "U" : "");
return ret;
}
int os_posix_fallocate(int fd, long offset, long len)
{
assert(0);
DBG("posix_fallocate(fd = %d, offset = %ld, len = %ld)\n", fd, offset, len);
return posix_fallocate(fd, offset, len);
}
int os_uffs_init(void)
{
static int inited = 0;
const char *apisrv_addr;
if (!inited) {
inited = 1;
memset(m_fdmap, 0, sizeof(m_fdmap));
memset(m_fdmap_ext, 0, sizeof(m_fdmap_ext));
mkdir("bak", 0777); // for mirroring UFFS
apisrv_addr = getenv("UFFS_TEST_SRV_ADDR");
if (apisrv_addr == NULL)
apisrv_addr = "127.0.0.1";
DBG("os_uffs_init() called, server addr: %s\n", apisrv_addr);
return api_client_init(apisrv_addr);
}
else
return 0;
}
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS 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
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file os_uffs.h
* \brief header file for interfacing to sqlite3
* \author Ricky Zheng, created at 22 Dec, 2011
*/
#ifndef _OS_UFFS_
#define _OS_UFFS_
int os_open(const char *name, int oflags, int mode);
int os_close(int fd);
#endif
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/test/api_test)
IF (UNIX)
SET(example_SRCS example.c)
SET(example2_SRCS example-2.c)
ADD_EXECUTABLE(example ${example_SRCS})
ADD_EXECUTABLE(example-2 ${example2_SRCS})
TARGET_LINK_LIBRARIES(example apitest_client)
TARGET_LINK_LIBRARIES(example-2 apitest_client)
ENDIF()
/*
* This is a APT test client example
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "uffs/uffs_fd.h"
#include "api_test.h"
int main(int argc, char *argv[])
{
int interval = 1000;
if (argc > 2) {
interval = atoi(argv[2]);
}
printf("Host: %s, Interval: %d\n", argv[1], interval);
if (api_client_init(argv[1]) == 0) {
while(1) {
uffs_flush_all("/");
usleep(interval * 1000);
}
}
else {
printf("init failed.\n");
}
return 0;
}
/*
* This is a APT test client example
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uffs/uffs_fd.h"
#include "api_test.h"
int main(int argc, char *argv[])
{
int version;
int fd;
char buf[128];
api_client_init("192.168.0.103");
version = uffs_version();
printf("Version: %08X\n", version);
fd = uffs_open("/test.txt", UO_RDWR|UO_CREATE);
if (fd < 0) {
printf("Can't create /test.txt\n");
return -1;
}
sprintf(buf, "Hello, this is test\n");
if (uffs_write(fd, buf, strlen(buf)) < 0) {
printf("call uffs_write failed\n");
}
else {
if (uffs_seek(fd, 7, USEEK_SET) != 7) {
printf("call uffs_seek failed\n");
}
else {
if (uffs_read(fd, buf, 4) != 4) {
printf("call uffs_read failed\n");
}
else {
if (memcmp(buf, "this", 4) != 0) {
printf("uffs_read content not matched\n");
}
else {
printf("everything is ok.\n");
}
}
}
}
if (uffs_close(fd) < 0) {
printf("uffs_close failed.\n");
}
return 0;
}
# $9 --- fd
# $8 --- counter, file content
evl $8 % 60
set 6 $1
evl $1 * 508
set 7 $1
echo --- testing n = $8 / $6, offset = $7 ---
t_seek $9 $7 s
! abort --- seek file failed ---
t_write $9 $8
! abort --- write file (n=$8) failed ---
t_seek $9 $7 s
! abort --- seek file failed ---
t_read $9 $8
! abort --- read file compare failed n=$8 ---
evl $8 + 1
set 8 $1
#rm /a
# * 10 t3 /a
t_open w /a
set 9 $1
echo --- test batch 1 ---
set 8 0
* 10 script _t1_sub1.ts
echo --- test batch 2 ---
set 8 32
* 10 script _t1_sub1.ts
echo --- test batch 3 ---
set 8 70
* 10 script _t1_sub1.ts
t_close $9
t_open cw /a
! abort --- create file /a failed.
set 9 $1
t_write_seq $9 1000
! abort
t_write_seq $9 100
! abort
t_write_seq $9 10
! abort
t_write_seq $9 1
! abort
t_seek $9 100
! abort
t_write_seq $9 1000
! abort
t_write_seq $9 100
! abort
t_write_seq $9 10
! abort
t_write_seq $9 1
! abort
t_seek $9 500
! abort
t_write_seq $9 1000
! abort
t_write_seq $9 100
! abort
t_write_seq $9 10
! abort
t_write_seq $9 1
! abort
t_seek $9 1500
! abort
t_write_seq $9 1000
! abort
t_write_seq $9 100
! abort
t_write_seq $9 10
! abort
t_write_seq $9 1
! abort
# check ...
t_seek $9 0
! abort
t_check_seq $9 1000
! abort
t_seek $9 1
! abort
t_check_seq $9 1000
! abort
t_seek $9 1000
! abort
t_check_seq $9 10
! abort
t_seek $9 100
! abort
t_check_seq $9 500
! abort
t_seek $9 2000
! abort
t_check_seq $9 100
! abort
t_close $9
echo -- test succ --
\ No newline at end of file
#
# test delete file/dir
#
rm /a
#####################################
echo == test normal delete ==
#####################################
t_open cw /a
! abort --- Can't create file /a ---
set 9 $1
t_write_seq $9 100
! abort --- write file failed ---
t_close $9
! abort --- close file failed ---
rm /a
! abort --- can't delete /a ---
###############################################
echo == test not delete if a file is opened ==
###############################################
t_open cw /a
! abort --- Can't create file /a ---
set 9 $1
t_write_seq $9 100
! abort --- write file failed ---
rm /a
# this should failed, save $?(-1) to $8.
set 8 $?
t_close $9
! abort --- fail to close file ---
test $8 == -1
! abort --- can delete a file in use ? ---
######################################
echo == test delete empty dir ==
######################################
rm /xx
mkdir /xx
! abort -- can't create /xx --
mkdir /xx/yy
! abort -- can't create /xx/yy --
rm /xx/yy
! abort -- can't delete /xx/yy ---
rm /xx
! abort -- can't delet /xx
#########################################
echo == test not delete non-empty dir ==
#########################################
mkdir /xx
t1 /xx/a.txt
rm /xx
test $? == -1
! abort --- delete a non-empty dir success ?? ---
rm /xx/a.txt
! abort --- can't delete /xx/a.txt ---
rm /xx
! abort --- can't delet /xx ---
echo ##################################
echo -------- ALL TEST SUCCESS --------
echo ##################################
rm /test_seek.bin
# create a new file
t_open wc /test_seek.bin
! abort ---- create file failed ----
set 9 $1 # opened fd => $9
# test seek and write
t_write $9 hello-world
! abort ---- write file failed ----
t_seek $9 5 s
! abort --- seek file to 5 failed ---
test $1 == 5
! abort --- file pointer is not 5 ---
t_write $9 &
! abort --- write '&' at position 5 failed ---
t_seek $9 0 s
! abort --- seek file to 0 failed
test $1 == 0
! abort -- file pointer not 0 ---
t_read $9 hello&world
! abort --- check file failed ---
# test seek in different options
t_seek $9 0 s
test $1 == 0
! abort -- file pointer seek to 0 s failed --
t_seek $9 100 s
test $1 == 100
! abort -- file pointer seek to 100 s failed --
t_seek $9 10 c
test $1 == 110
! abort -- file pointer seek to +10 c failed --
t_seek $9 -10 c
test $1 == 100
! abort -- file pointer seek to -10 c failed --
t_seek $9 0 e
test $1 == 11
! abort -- file pointer seek to 0 e failed --
t_seek $9 -1 e
test $1 == 10
! abort -- file pointer seek to -1 e failed --
t_seek $9 10 e
test $1 == 21
! abort -- file pointer seek to +10 e failed --
# now the file pointer is passed over the end of file,
# write to it will increase file size and filling 0 in the gap
t_write $9 a
test $? == 0
! abort -- file write to position passed over file length failed --
t_seek $9 0 e
test $1 == 22
! abort -- file new length not filling the gap --
t_close $9
! abort --- close file failed ---
echo === test seek success ===
#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite. Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically. But that does not work for everybody
# and in every situation. If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative. Create a copy of this file, edit the parameters
# below and type "make".
#
#### The directory where to find the mingw32ce tools
MINGW32CE = /opt/mingw32ce/bin
#### The target prefix of the mingw32ce tools
TARGET = arm-wince-mingw32ce
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = ../sqlite
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
USLEEP =
#USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
THREADSAFE = -DTHREADSAFE=1
#THREADSAFE = -DTHREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt # fdatasync on Solaris 8
TLIBS =
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1 -DSQLITE_OS_WIN=1 -D_WIN32_WCE=1
#OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
EXE = .exe
#EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
TCC = $(MINGW32CE)/$(TARGET)-gcc -O2
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#### Tools used to build a static library.
#
#AR = ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
AR = $(MINGW32CE)/$(TARGET)-ar cr
#RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
RANLIB = $(MINGW32CE)/$(TARGET)-ranlib
#MKSHLIB = gcc -shared
#SO = so
#SHPREFIX = lib
MKSHLIB = $(MINGW32CE)/$(TARGET)-gcc -shared
SO = dll
SHPREFIX =
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
TCLOBJ =
#TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk
#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite. Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically. But that does not work for everybody
# and in every situation. If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative. Create a copy of this file, edit the parameters
# below and type "make".
#
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = ../sqlite
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
#USLEEP =
USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
#THREADSAFE = -DTHREADSAFE=1
THREADSAFE = -DTHREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt # fdatasync on Solaris 8
TLIBS =
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1
OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
#EXE = .exe
EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#### Tools used to build a static library.
#
AR = ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
MKSHLIB = gcc -shared
SO = so
SHPREFIX = lib
# SO = dll
# SHPREFIX =
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
#TCLOBJ =
TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk
This directory contains source code to
SQLite: An Embeddable SQL Database Engine
To compile the project, first create a directory in which to place
the build products. It is recommended, but not required, that the
build directory be separate from the source directory. Cd into the
build directory and then from the build directory run the configure
script found at the root of the source tree. Then run "make".
For example:
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make ;# Run the makefile.
make install ;# (Optional) Install the build products
The configure script uses autoconf 2.61 and libtool. If the configure
script does not work out for you, there is a generic makefile named
"Makefile.linux-gcc" in the top directory of the source tree that you
can copy and edit to suit your needs. Comments on the generic makefile
show what changes are needed.
The linux binaries on the website are created using the generic makefile,
not the configure script. The windows binaries on the website are created
using MinGW32 configured as a cross-compiler running under Linux. For
details, see the ./publish.sh script at the top-level of the source tree.
The developers do not use teh configure script.
SQLite does not require TCL to run, but a TCL installation is required
by the makefiles. SQLite contains a lot of generated code and TCL is
used to do much of that code generation. The makefile also requires
AWK.
Contacts:
http://www.sqlite.org/
#!/usr/bin/awk
#
# This script appends additional token codes to the end of the
# parse.h file that lemon generates. These extra token codes are
# not used by the parser. But they are used by the tokenizer and/or
# the code generator.
#
#
BEGIN {
max = 0
}
/^#define TK_/ {
print $0
if( max<$3 ) max = $3
}
END {
printf "#define TK_%-29s %4d\n", "TO_TEXT", ++max
printf "#define TK_%-29s %4d\n", "TO_BLOB", ++max
printf "#define TK_%-29s %4d\n", "TO_NUMERIC", ++max
printf "#define TK_%-29s %4d\n", "TO_INT", ++max
printf "#define TK_%-29s %4d\n", "TO_REAL", ++max
printf "#define TK_%-29s %4d\n", "ISNOT", ++max
printf "#define TK_%-29s %4d\n", "END_OF_FILE", ++max
printf "#define TK_%-29s %4d\n", "ILLEGAL", ++max
printf "#define TK_%-29s %4d\n", "SPACE", ++max
printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max
printf "#define TK_%-29s %4d\n", "FUNCTION", ++max
printf "#define TK_%-29s %4d\n", "COLUMN", ++max
printf "#define TK_%-29s %4d\n", "AGG_FUNCTION", ++max
printf "#define TK_%-29s %4d\n", "AGG_COLUMN", ++max
printf "#define TK_%-29s %4d\n", "CONST_FUNC", ++max
printf "#define TK_%-29s %4d\n", "UMINUS", ++max
printf "#define TK_%-29s %4d\n", "UPLUS", ++max
}
Version loadable extensions to SQLite are found in subfolders
of this folder.
This folder contains source code to the first full-text search
extension for SQLite.
This folder contains source code to the second full-text search
extension for SQLite. While the API is the same, this version uses a
substantially different storage schema from fts1, so tables will need
to be rebuilt.
This folder contains source code to the second full-text search
extension for SQLite. While the API is the same, this version uses a
substantially different storage schema from fts1, so tables will need
to be rebuilt.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册