2 * The Road goes ever on and on
3 * Down from the door where it began.
5 * [Bilbo on p.35 of _The Lord of the Rings_, I/i: "A Long-Expected Party"]
6 * [Frodo on p.73 of _The Lord of the Rings_, I/iii: "Three Is Company"]
8 #define PERLIO_NOT_STDIO 0
9 #define PERL_IN_WIN32_PERLLIB_C
16 #ifdef PERL_IMPLICIT_SYS
19 #endif /* PERL_IMPLICIT_SYS */
22 /* Register any extra external extensions */
23 const char * const staticlinkmodules[] = {
25 /* other similar records will be included from "perllibst.h" */
27 #include "perllibst.h"
31 EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
32 /* other similar records will be included from "perllibst.h" */
34 #include "perllibst.h"
39 const char *file = __FILE__;
41 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
42 /* other similar records will be included from "perllibst.h" */
44 #include "perllibst.h"
47 #ifdef PERL_IMPLICIT_SYS
52 win32_checkTLS(PerlInterpreter *host_perl)
54 /* GCurThdId() is lightweight, but b/c of the ctrl-c/signals sometimes firing
55 in other random WinOS threads, that make the TIDs go out of sync.
56 This isn't always an error, although high chance of a SEGV in the next
57 couple milliseconds b/c of "Day 1 of Win32 port" Ctrl-C vs Perl bugs.
58 Google it for details. So this code, if TIDs don't match, do the full heavy
59 TlsGetValue() + misc fn calls. Then resync TIDs to keep this fast for
60 future calls to this fn. */
61 DWORD tid = GetCurrentThreadId();
62 if(tid != host_perl->Isys_intern.cur_tid) {
63 dTHX; /* heavyweight */
64 if (host_perl != my_perl) {
68 host_perl->Isys_intern.cur_tid = tid;
73 perl_get_host_info(struct IPerlMemInfo* perlMemInfo,
74 struct IPerlMemInfo* perlMemSharedInfo,
75 struct IPerlMemInfo* perlMemParseInfo,
76 struct IPerlEnvInfo* perlEnvInfo,
77 struct IPerlStdIOInfo* perlStdIOInfo,
78 struct IPerlLIOInfo* perlLIOInfo,
79 struct IPerlDirInfo* perlDirInfo,
80 struct IPerlSockInfo* perlSockInfo,
81 struct IPerlProcInfo* perlProcInfo)
84 Copy(&perlMem, &perlMemInfo->perlMemList, perlMemInfo->nCount, void*);
85 perlMemInfo->nCount = (sizeof(struct IPerlMem)/sizeof(void*));
87 if (perlMemSharedInfo) {
88 Copy(&perlMem, &perlMemSharedInfo->perlMemList, perlMemSharedInfo->nCount, void*);
89 perlMemSharedInfo->nCount = (sizeof(struct IPerlMem)/sizeof(void*));
91 if (perlMemParseInfo) {
92 Copy(&perlMem, &perlMemParseInfo->perlMemList, perlMemParseInfo->nCount, void*);
93 perlMemParseInfo->nCount = (sizeof(struct IPerlMem)/sizeof(void*));
96 Copy(&perlEnv, &perlEnvInfo->perlEnvList, perlEnvInfo->nCount, void*);
97 perlEnvInfo->nCount = (sizeof(struct IPerlEnv)/sizeof(void*));
100 Copy(&perlStdIO, &perlStdIOInfo->perlStdIOList, perlStdIOInfo->nCount, void*);
101 perlStdIOInfo->nCount = (sizeof(struct IPerlStdIO)/sizeof(void*));
104 Copy(&perlLIO, &perlLIOInfo->perlLIOList, perlLIOInfo->nCount, void*);
105 perlLIOInfo->nCount = (sizeof(struct IPerlLIO)/sizeof(void*));
108 Copy(&perlDir, &perlDirInfo->perlDirList, perlDirInfo->nCount, void*);
109 perlDirInfo->nCount = (sizeof(struct IPerlDir)/sizeof(void*));
112 Copy(&perlSock, &perlSockInfo->perlSockList, perlSockInfo->nCount, void*);
113 perlSockInfo->nCount = (sizeof(struct IPerlSock)/sizeof(void*));
116 Copy(&perlProc, &perlProcInfo->perlProcList, perlProcInfo->nCount, void*);
117 perlProcInfo->nCount = (sizeof(struct IPerlProc)/sizeof(void*));
121 EXTERN_C PerlInterpreter*
122 perl_alloc_override(const struct IPerlMem** ppMem, const struct IPerlMem** ppMemShared,
123 const struct IPerlMem** ppMemParse, const struct IPerlEnv** ppEnv,
124 const struct IPerlStdIO** ppStdIO, const struct IPerlLIO** ppLIO,
125 const struct IPerlDir** ppDir, const struct IPerlSock** ppSock,
126 const struct IPerlProc** ppProc)
128 PerlInterpreter *my_perl = NULL;
129 CPerlHost* pHost = new CPerlHost(ppMem, ppMemShared, ppMemParse, ppEnv,
130 ppStdIO, ppLIO, ppDir, ppSock, ppProc);
133 my_perl = perl_alloc_using(&pHost->m_pHostperlMem,
134 &pHost->m_pHostperlMemShared,
135 &pHost->m_pHostperlMemParse,
136 &pHost->m_pHostperlEnv,
137 &pHost->m_pHostperlStdIO,
138 &pHost->m_pHostperlLIO,
139 &pHost->m_pHostperlDir,
140 &pHost->m_pHostperlSock,
141 &pHost->m_pHostperlProc);
143 w32_internal_host = pHost;
144 pHost->host_perl = my_perl;
150 EXTERN_C PerlInterpreter*
153 PerlInterpreter* my_perl = NULL;
154 CPerlHost* pHost = new CPerlHost();
156 my_perl = perl_alloc_using(&pHost->m_pHostperlMem,
157 &pHost->m_pHostperlMemShared,
158 &pHost->m_pHostperlMemParse,
159 &pHost->m_pHostperlEnv,
160 &pHost->m_pHostperlStdIO,
161 &pHost->m_pHostperlLIO,
162 &pHost->m_pHostperlDir,
163 &pHost->m_pHostperlSock,
164 &pHost->m_pHostperlProc);
166 w32_internal_host = pHost;
167 pHost->host_perl = my_perl;
174 win32_delete_internal_host(void *h)
176 CPerlHost *host = (CPerlHost*)h;
180 #endif /* PERL_IMPLICIT_SYS */
182 EXTERN_C HANDLE w32_perldll_handle;
184 EXTERN_C DllExport int
185 RunPerl(int argc, char **argv, char **env)
188 PerlInterpreter *my_perl, *new_perl = NULL;
189 bool use_environ = (env == environ);
191 PERL_SYS_INIT(&argc,&argv);
193 if (!(my_perl = perl_alloc()))
195 perl_construct(my_perl);
196 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
197 PL_perl_destruct_level = 0;
199 /* PERL_SYS_INIT() may update the environment, e.g. via ansify_path().
200 * This may reallocate the RTL environment block. Therefore we need
201 * to make sure that `env` continues to have the same value as `environ`
202 * if we have been called this way. If we have been called with any
203 * other value for `env` then all environment munging by PERL_SYS_INIT()
204 * will be lost again.
209 if (!perl_parse(my_perl, xs_init, argc, argv, env)) {
210 #if defined(TOP_CLONE) && defined(USE_ITHREADS) /* XXXXXX testing */
211 new_perl = perl_clone(my_perl, 1);
212 (void) perl_run(new_perl);
213 PERL_SET_THX(my_perl);
215 (void) perl_run(my_perl);
219 exitstatus = perl_destruct(my_perl);
223 PERL_SET_THX(new_perl);
224 exitstatus = perl_destruct(new_perl);
235 set_w32_module_name(void);
242 EXTERN_C /* GCC in C++ mode mangles the name, otherwise */
245 DllMain(HINSTANCE hModule, /* DLL module handle */
246 DWORD fdwReason, /* reason called */
247 LPVOID lpvReserved) /* reserved */
250 /* The DLL is attaching to a process due to process
251 * initialization or a call to LoadLibrary.
253 case DLL_PROCESS_ATTACH:
254 DisableThreadLibraryCalls((HMODULE)hModule);
256 w32_perldll_handle = hModule;
257 set_w32_module_name();
260 /* The DLL is detaching from a process due to
261 * process termination or call to FreeLibrary.
263 case DLL_PROCESS_DETACH:
264 /* As long as we use TerminateProcess()/TerminateThread() etc. for mimicking kill()
265 anything here had better be harmless if:
266 A. Not called at all.
267 B. Called after memory allocation for Heap has been forcibly removed by OS.
268 PerlIO_cleanup() was done here but fails (B).
271 #if defined(USE_ITHREADS)
277 /* The attached process creates a new thread. */
278 case DLL_THREAD_ATTACH:
281 /* The thread of the attached process terminates. */
282 case DLL_THREAD_DETACH:
292 #if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
293 EXTERN_C PerlInterpreter *
294 perl_clone_host(PerlInterpreter* proto_perl, UV flags) {
297 h = new CPerlHost(*(CPerlHost*)PL_sys_intern.internal_host);
298 proto_perl = perl_clone_using(proto_perl, flags,
300 &h->m_pHostperlMemShared,
301 &h->m_pHostperlMemParse,
303 &h->m_pHostperlStdIO,
309 proto_perl->Isys_intern.internal_host = h;
310 h->host_perl = proto_perl;