/********************************************************************** * * rtems shttpd management * * FILE NAME : rtems_shttpd.c * * AUTHOR : Steven Johnson * * DESCRIPTION : Defines the interface functions to the shttp daemon * * REVISION : $Id$ * * COMMENTS : * **********************************************************************/ /********************************************************************** * INCLUDED MODULES **********************************************************************/ #include #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; unsigned int port; 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, httpd_args->port); 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, size_t stack_size, rtems_mode initial_modes, rtems_attribute attribute_set, rtems_shttpd_init init_callback, rtems_shttpd_addpages addpages_callback, char *webroot, unsigned int port ) { 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; args->port = port; 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); } #ifndef __rtems__ 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)); } #endif 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