199 lines
4.9 KiB
C
199 lines
4.9 KiB
C
/**********************************************************************
|
|
*
|
|
* rtems shttpd management
|
|
*
|
|
* FILE NAME : rtems_shttpd.c
|
|
*
|
|
* AUTHOR : Steven Johnson
|
|
*
|
|
* DESCRIPTION : Defines the interface functions to the shttp daemon
|
|
*
|
|
* REVISION : $Id: compat_rtems.c,v 1.2 2006/11/12 03:29:17 infidel Exp $
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
**********************************************************************/
|
|
|
|
/**********************************************************************
|
|
* INCLUDED MODULES
|
|
**********************************************************************/
|
|
#include <rtems.h>
|
|
#include "defs.h"
|
|
|
|
#define MAX_WEB_BASE_PATH_LENGTH 256
|
|
#define MIN_SHTTPD_STACK (8*1024)
|
|
|
|
typedef struct RTEMS_HTTPD_ARGS {
|
|
rtems_shttpd_init init_callback;
|
|
rtems_shttpd_addpages addpages_callback;
|
|
char webroot[MAX_WEB_BASE_PATH_LENGTH];
|
|
} RTEMS_HTTPD_ARGS;
|
|
|
|
static int rtems_webserver_running = FALSE; //not running.
|
|
|
|
static rtems_task rtems_httpd_daemon(rtems_task_argument args )
|
|
{
|
|
RTEMS_HTTPD_ARGS *httpd_args = (RTEMS_HTTPD_ARGS*)args;
|
|
|
|
struct shttpd_ctx *ctx;
|
|
|
|
if (httpd_args != NULL)
|
|
if (httpd_args->init_callback != NULL)
|
|
httpd_args->init_callback();
|
|
|
|
/**************************************
|
|
* Initialize the web server
|
|
*/
|
|
/*
|
|
* Initialize SHTTPD context.
|
|
* Set WWW root to current WEB_ROOT_PATH.
|
|
*/
|
|
ctx = shttpd_init(NULL, "document_root", httpd_args->webroot, NULL);
|
|
|
|
if (httpd_args != NULL)
|
|
if (httpd_args->addpages_callback != NULL)
|
|
httpd_args->addpages_callback(ctx);
|
|
|
|
/* Finished with args, so free them */
|
|
if (httpd_args != NULL)
|
|
free(httpd_args);
|
|
|
|
/* Open listening socket */
|
|
shttpd_listen(ctx, 9000);
|
|
|
|
rtems_webserver_running = TRUE;
|
|
|
|
/* Serve connections infinitely until someone kills us */
|
|
while (rtems_webserver_running)
|
|
shttpd_poll(ctx, 1000);
|
|
|
|
/* Unreached, because we will be killed by a signal */
|
|
shttpd_fini(ctx);
|
|
|
|
rtems_task_delete( RTEMS_SELF );
|
|
}
|
|
|
|
rtems_status_code rtems_initialize_webserver(rtems_task_priority initial_priority,
|
|
rtems_unsigned32 stack_size,
|
|
rtems_mode initial_modes,
|
|
rtems_attribute attribute_set,
|
|
rtems_shttpd_init init_callback,
|
|
rtems_shttpd_addpages addpages_callback,
|
|
char *webroot
|
|
)
|
|
{
|
|
rtems_status_code sc;
|
|
rtems_id tid;
|
|
RTEMS_HTTPD_ARGS *args;
|
|
|
|
if (stack_size < MIN_SHTTPD_STACK)
|
|
stack_size = MIN_SHTTPD_STACK;
|
|
|
|
args = malloc(sizeof(RTEMS_HTTPD_ARGS));
|
|
|
|
if (args != NULL)
|
|
{
|
|
args->init_callback = init_callback;
|
|
args->addpages_callback = addpages_callback;
|
|
strncpy(args->webroot,webroot,MAX_WEB_BASE_PATH_LENGTH);
|
|
|
|
sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'),
|
|
initial_priority,
|
|
stack_size,
|
|
initial_modes,
|
|
attribute_set,
|
|
&tid);
|
|
|
|
if (sc == RTEMS_SUCCESSFUL)
|
|
{
|
|
sc = rtems_task_start(tid, rtems_httpd_daemon, (rtems_task_argument)args);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sc = RTEMS_NO_MEMORY;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
void rtems_terminate_webserver(void)
|
|
{
|
|
rtems_webserver_running = FALSE; //not running, so terminate
|
|
}
|
|
|
|
int rtems_webserver_ok(void)
|
|
{
|
|
return rtems_webserver_running;
|
|
}
|
|
|
|
void
|
|
set_close_on_exec(int fd)
|
|
{
|
|
// RTEMS Does not have a functional "execve"
|
|
// so technically this call does not do anything,
|
|
// but it doesnt hurt either.
|
|
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
|
|
}
|
|
|
|
int
|
|
my_stat(const char *path, struct stat *stp)
|
|
{
|
|
return (stat(path, stp));
|
|
}
|
|
|
|
int
|
|
my_open(const char *path, int flags, int mode)
|
|
{
|
|
return (open(path, flags, mode));
|
|
}
|
|
|
|
int
|
|
my_remove(const char *path)
|
|
{
|
|
return (remove(path));
|
|
}
|
|
|
|
int
|
|
my_rename(const char *path1, const char *path2)
|
|
{
|
|
return (rename(path1, path2));
|
|
}
|
|
|
|
int
|
|
my_mkdir(const char *path, int mode)
|
|
{
|
|
return (mkdir(path, mode));
|
|
}
|
|
|
|
char *
|
|
my_getcwd(char *buffer, int maxlen)
|
|
{
|
|
return (getcwd(buffer, maxlen));
|
|
}
|
|
|
|
int
|
|
set_non_blocking_mode(int fd)
|
|
{
|
|
int ret = -1;
|
|
int flags;
|
|
|
|
if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
|
|
DBG(("nonblock: fcntl(F_GETFL): %d", ERRNO));
|
|
} else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
|
|
DBG(("nonblock: fcntl(F_SETFL): %d", ERRNO));
|
|
} else {
|
|
ret = 0; /* Success */
|
|
}
|
|
|
|
return (ret);
|
|
}
|
|
|
|
#if !defined(NO_CGI)
|
|
int
|
|
spawn_process(struct conn *c, const char *prog, char *envblk, char **envp)
|
|
{
|
|
return (-1); // RTEMS does not have subprocess support as standard.
|
|
}
|
|
#endif
|