📄 main.c
字号:
* 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_STATSstatic 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 + -