/* * Close a chared object */ int erts_sys_ddll_close2(void *handle, ErtsSysDdllError* err) { MODULE_ID mid = (MODULE_ID) handle; if (unld(mid, 0) < 0) { return ERL_DE_DYNAMIC_ERROR_OFFSET - ((int) ModuleNotUnloadable); } return ERL_DE_NO_ERROR; }
/* Launch the CGI process and return a handle to it. Process spawning is not supported in VxWorks. Instead, we spawn a "task". A major difference is that we have to know the entry point for the taskSpawn API. Also the module may have to be loaded before being executed; it may also be part of the OS image, in which case it cannot be loaded or unloaded. The following sequence is used: 1. If the module is already loaded, unload it from memory. 2. Search for a query string keyword=value pair in the environment variables where the keyword is cgientry. If found use its value as the the entry point name. If there is no such pair set the entry point name to the default: basename_cgientry, where basename is the name of the cgi file without the extension. Use the entry point name in a symbol table search for that name to use as the entry point address. If successful go to step 5. 3. Try to load the module into memory. If not successful error out. 4. If step 3 is successful repeat the entry point search from step 2. If the entry point exists, go to step 5. If it does not, error out. 5. Use taskSpawn to start a new task which uses vxWebsCgiEntry as its starting point. The five arguments to vxWebsCgiEntry 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. */ static int launchCgi(char *cgiPath, char **argp, char **envp, char *stdIn, char *stdOut) { SYM_TYPE ptype; char *p, *basename, *pEntry, *pname, *entryAddr, **pp; int priority, rc, fd; /* Determine the basename, which is without path or the extension. */ if ((int)(p = strrchr(cgiPath, '/') + 1) == 1) { p = cgiPath; } basename = sclone(p); if ((p = strrchr(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 (strncmp(*pp, "cgientry=", 9) == 0) { pEntry = sclone(*pp + 9); break; } } if (pEntry == NULL) { pEntry = sfmt("%s_%s", basename, "cgientry"); } entryAddr = 0; if (symFindByName(sysSymTbl, pEntry, &entryAddr, &ptype) == -1) { pname = sfmt("_%s", pEntry); symFindByName(sysSymTbl, pname, &entryAddr, &ptype); wfree(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 = open(cgiPath, O_RDONLY | O_BINARY, 0666)) < 0 || loadModule(fd, LOAD_GLOBAL_SYMBOLS) == NULL) { goto done; } if ((symFindByName(sysSymTbl, pEntry, &entryAddr, &ptype)) == -1) { pname = sfmt("_%s", pEntry); symFindByName(sysSymTbl, pname, &entryAddr, &ptype); wfree(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) { close(fd); } wfree(basename); wfree(pEntry); return rc; }
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; }