43d84c507b8f3b65f838c54d04467741f14bc1b7
[p5sagit/p5-mst-13.2.git] / win32 / perllib.c
1 /*
2  * "The Road goes ever on and on, down from the door where it began."
3  */
4
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8
9 #include "EXTERN.h"
10 #include "perl.h"
11 #include "XSUB.h"
12
13 #ifdef __cplusplus
14 }
15 #  define EXTERN_C extern "C"
16 #else
17 #  define EXTERN_C extern
18 #endif
19
20 static void xs_init _((void));
21
22 __declspec(dllexport) int
23 RunPerl(int argc, char **argv, char **env, void *iosubsystem)
24 {
25     int exitstatus;
26     PerlInterpreter *my_perl;
27     void *pOldIOSubsystem;
28
29     pOldIOSubsystem = SetIOSubSystem(iosubsystem);
30
31     PERL_SYS_INIT(&argc,&argv);
32
33     perl_init_i18nl10n(1);
34
35     if (!(my_perl = perl_alloc()))
36         return (1);
37     perl_construct( my_perl );
38     perl_destruct_level = 0;
39
40     exitstatus = perl_parse( my_perl, xs_init, argc, argv, env);
41     if (!exitstatus) {
42         exitstatus = perl_run( my_perl );
43     }
44
45     perl_destruct( my_perl );
46     perl_free( my_perl );
47
48     PERL_SYS_TERM();
49
50     SetIOSubSystem(pOldIOSubsystem);
51
52     return (exitstatus);
53 }
54
55 /* Register any extra external extensions */
56
57 char *staticlinkmodules[] = {
58     "DynaLoader",
59     NULL,
60 };
61
62 EXTERN_C void boot_DynaLoader _((CV* cv));
63
64 static
65 XS(w32_GetCurrentDirectory)
66 {
67  dXSARGS;
68  SV *sv = sv_newmortal();
69  /* Make one call with zero size - return value is required size */
70  DWORD len = GetCurrentDirectory((DWORD)0,NULL);
71  SvUPGRADE(sv,SVt_PV);
72  SvGROW(sv,len);
73  SvCUR(sv) = GetCurrentDirectory((DWORD) SvLEN(sv), SvPVX(sv));
74  /* 
75   * If result != 0 
76   *   then it worked, set PV valid, 
77   *   else leave it 'undef' 
78   */
79  if (SvCUR(sv))
80   SvPOK_on(sv);
81  EXTEND(sp,1);
82  ST(0) = sv;
83  XSRETURN(1);
84 }
85
86 static void
87 xs_init()
88 {
89     char *file = __FILE__;
90     dXSUB_SYS;
91     newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
92     newXS("Win32::GetCurrentDirectory", w32_GetCurrentDirectory, file);
93 }
94
95 extern HANDLE PerlDllHandle;
96
97 BOOL APIENTRY
98 DllMain(HANDLE hModule,         /* DLL module handle */
99         DWORD fdwReason,        /* reason called */
100         LPVOID lpvReserved)     /* reserved */
101
102     switch (fdwReason) {
103         /* The DLL is attaching to a process due to process
104          * initialization or a call to LoadLibrary.
105          */
106     case DLL_PROCESS_ATTACH:
107 /* #define DEFAULT_BINMODE */
108 #ifdef DEFAULT_BINMODE
109         _setmode( _fileno( stdin  ), _O_BINARY );
110         _setmode( _fileno( stdout ), _O_BINARY );
111         _setmode( _fileno( stderr ), _O_BINARY );
112         _fmode = _O_BINARY;
113 #endif
114         PerlDllHandle = hModule;
115         break;
116
117         /* The DLL is detaching from a process due to
118          * process termination or call to FreeLibrary.
119          */
120     case DLL_PROCESS_DETACH:
121         break;
122
123         /* The attached process creates a new thread. */
124     case DLL_THREAD_ATTACH:
125         break;
126
127         /* The thread of the attached process terminates. */
128     case DLL_THREAD_DETACH:
129         break;
130
131     default:
132         break;
133     }
134     return TRUE;
135 }