⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 4510 bios,please see it carefully!and so on,no thanks
💻 C
📖 第 1 页 / 共 2 页
字号:
 *		will be the user entry point address, argp, envp, stdIn
 *		and stdOut.  vxWebsCgiEntry will convert argp to an argc
 *		argv pair to pass to the user entry, it will initialize the
 *		task environment with envp, it will open and redirect stdin
 *		and stdout to stdIn and stdOut, and	then it will call the
 *		user entry.
 *	6.	Return the taskSpawn return value.
 */

int websLaunchCgiProc(char_t *cgiPath, char_t **argp, char_t **envp,
					  char_t *stdIn, char_t *stdOut)
{
	SYM_TYPE	ptype;
	char_t		*p, *basename, *pEntry, *pname, *entryAddr, **pp;
	int			priority, rc, fd;

/*
 *	Determine the basename, which is without path or the extension.
 */
	if ((int)(p = gstrrchr(cgiPath, '/') + 1) == 1) {
		p = cgiPath;
	}
	basename = bstrdup(B_L, p);
	if ((p = gstrrchr(basename, '.')) != NULL) {
		*p = '\0';
	}

/*
 *	Unload the module, if it is already loaded.  Get the current task
 *	priority.
 */
	unld(cgiPath, 0);
	taskPriorityGet(taskIdSelf(), &priority);
	rc = fd = -1;

/*
 *	Set the entry point symbol name as described above.  Look for an already
 *	loaded entry point; if it exists, spawn the task accordingly.
 */
	for (pp = envp, pEntry = NULL; pp != NULL && *pp != NULL; pp++) {
		if (gstrncmp(*pp, T("cgientry="), 9) == 0) {
			pEntry = bstrdup(B_L, *pp + 9);
			break;
		}
	}
	if (pEntry == NULL) {
		fmtAlloc(&pEntry, LF_PATHSIZE, T("%s_%s"), basename, T("cgientry"));
	}

	entryAddr = 0;
	if (symFindByName(sysSymTbl, pEntry, &entryAddr, &ptype) == -1) {
		fmtAlloc(&pname, VALUE_MAX_STRING, T("_%s"), pEntry);
		symFindByName(sysSymTbl, pname, &entryAddr, &ptype);
		bfreeSafe(B_L, pname);
	}
	if (entryAddr != 0) {
		rc = taskSpawn(pEntry, priority, 0, 20000, (void *)vxWebsCgiEntry,
			(int)entryAddr, (int)argp, (int)envp, (int)stdIn, (int)stdOut,
			0, 0, 0, 0, 0);
		goto DONE;
	}

/*
 *	Try to load the module.
 */
	if ((fd = gopen(cgiPath, O_RDONLY | O_BINARY, 0666)) < 0 ||
		loadModule(fd, LOAD_GLOBAL_SYMBOLS) == NULL) {
		goto DONE;
	}
	if ((symFindByName(sysSymTbl, pEntry, &entryAddr, &ptype)) == -1) {
		fmtAlloc(&pname, VALUE_MAX_STRING, T("_%s"), pEntry);
		symFindByName(sysSymTbl, pname, &entryAddr, &ptype);
		bfreeSafe(B_L, pname);
	}
	if (entryAddr != 0) {
		rc = taskSpawn(pEntry, priority, 0, 20000, (void *)vxWebsCgiEntry,
			(int)entryAddr, (int)argp, (int)envp, (int)stdIn, (int)stdOut,
			0, 0, 0, 0, 0);
	}

DONE:
	if (fd != -1) {
		gclose(fd);
	}
	bfree(B_L, basename);
	bfree(B_L, pEntry);
	return rc;
}

/******************************************************************************/
/*
 *	This is the CGI process wrapper.  It will open and redirect stdin
 *	and stdout to stdIn and stdOut.  It converts argv to an argc, argv
 *	pair to pass to the user entry. It initializes the task environment
 *	with envp strings.  Then it will call the user entry. 
 */

void vxWebsCgiEntry(void *entryAddr(int argc, char_t **argv),
					char_t **argp, char_t **envp,
					char_t *stdIn, char_t *stdOut)
{
	char_t	**p;
	int		argc, taskId, fdin, fdout;

/*
 *	Open the stdIn and stdOut files and redirect stdin and stdout
 *	to them.
 */
	taskId = taskIdSelf();
	if ((fdout = gopen(stdOut, O_RDWR | O_CREAT, 0666)) < 0 &&
		(fdout = creat(stdOut, O_RDWR)) < 0) {
			exit(0);
	}
	ioTaskStdSet(taskId, 1, fdout);

	if ((fdin = gopen(stdIn, O_RDONLY | O_CREAT, 0666)) < 0 &&
		(fdin = creat(stdIn, O_RDWR)) < 0) {
		printf("content-type: text/html\n\n"
				"Can not create CGI stdin to %s\n", stdIn);
		gclose(fdout);
		exit (0);
	}
	ioTaskStdSet(taskId, 0, fdin);
	
/*
 *	Count the number of entries in argv
 */
	for (argc = 0, p = argp; p != NULL && *p != NULL; p++, argc++) {
	}

/*
 *	Create a private envirnonment and copy the envp strings to it.
 */
	if (envPrivateCreate(taskId, -1) != OK) {
		printf("content-type: text/html\n\n"
				"Can not create CGI environment space\n");
		gclose(fdin);
		gclose(fdout);
		exit (0);
	}
	for (p = envp; p != NULL && *p != NULL; p++) {
		putenv(*p);
	}

/*
 *	Call the user entry.
 */
	(*entryAddr)(argc, argp);

/*
 *	The user code should return here for cleanup.
 */

	envPrivateDestroy(taskId);
	gclose(fdin);
	gclose(fdout);
	exit(0);
}

/******************************************************************************/
/*
 *	Check the CGI process.  Return 0 if it does not exist; non 0 if it does.
 */

int websCheckCgiProc(int handle)
{
	STATUS stat;
/*
 *	Verify the existence of a VxWorks task
 */
	stat = taskIdVerify(handle);

	if (stat == OK) {
		return 1;
	} else {
		return 0;
	}
}

/******************************************************************************/
/*
 *	Default error handler.  The developer should insert code to handle
 *	error messages in the desired manner.
 */
void defaultErrorHandler(int etype, char_t *msg)
{
#if 0
	write(1, msg, gstrlen(msg));
#endif
}

/******************************************************************************/
/*
 *	Trace log. Customize this function to log trace output
 */

void defaultTraceHandler(int level, char_t *buf)
{
/*
 *	The following code would write all trace regardless of level
 *	to stdout.
 */
#if 0
	if (buf) {
		write(1, buf, gstrlen(buf));
	}
#endif
}

/******************************************************************************/
/*
 *	Signal handler.  Process the terminate signals SIGTERM and SIGKILL.
 *	If the signal is SIGTERM, just set the flag so the next time
 *	through the event loop, the webserver will terminate itself cleanly.
 *	If the signal is SIGKILL, release the resources and exit immediately.
 */

static void websTermSigHandler(int signo)
{
	if (signo == SIGTERM) {
		finished = 1;
	} else if (signo == SIGKILL) {
#ifdef WEBS_SSL_SUPPORT
		websSSLClose();
#endif

#ifdef USER_MANAGEMENT_SUPPORT
		umClose();
#endif
		websCloseServer();
		websDefaultClose();
		socketClose();
		symSubClose();
#ifdef B_STATS
		memLeaks();
#endif
		bclose();
		exit(1);
	}
}

/******************************************************************************/
/*
 *	Get absolute path.  In VxWorks, functions like chdir, ioctl for mkdir
 *	and ioctl for rmdir, require an absolute path.  This function will
 *	take the path argument and convert it to an absolute path.  It is the
 *	caller's responsibility to deallocate the returned string. 
 */

static char_t *getAbsolutePath(char_t *path)
{
	char_t	*tail;
	char_t	*dev;

/*
 *	Determine if path is relative or absolute.  If relative, prepend
 *	the current working directory to the name.  Otherwise, use it.
 *	Note the getcwd call below must not be ggetcwd or else we go into
 *	an infinite loop
 */
	if (iosDevFind(path, &tail) != NULL && path != tail) {
		return bstrdup(B_L, path);
	}
	dev = balloc(B_L, LF_PATHSIZE);
	getcwd(dev, LF_PATHSIZE);
	strcat(dev, "/");
	strcat(dev, path);
	return dev;
}

/******************************************************************************/
/*
 *	Change default working directory.
 */

int vxchdir(char_t *dirname)
{
	int		rc;
	char_t	*path;

/*
 *	Get an absolute path name for the directory.
 */
	path = getAbsolutePath(dirname);

/*
 *	Now change the default working directory.  The chdir call
 *	below must not be replaced with gchdir or else an infinite
 *	loop will occur.
 */
	rc = chdir(path);
	bfree(B_L, path);
	return rc;
}

/******************************************************************************/
#ifdef B_STATS
static void memLeaks() 
{
	int		fd;

	if ((fd = gopen(T("leak.txt"), O_CREAT | O_TRUNC | O_WRONLY, 0644)) >= 0) {
		bstats(fd, printMemStats);
		close(fd);
	}
}

/******************************************************************************/
/*
 *	Print memory usage / leaks
 */

static void printMemStats(int handle, char_t *fmt, ...)
{
	va_list		args;
	char_t		buf[256];

	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	va_end(args);
	write(handle, buf, strlen(buf));
}
#endif

/******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -