Commit | Line | Data |
76e3520e |
1 | /* |
2 | |
3 | ipstdio.c |
4 | Interface for perl stdio functions |
5 | |
6 | */ |
7 | |
8 | #include "ipstdiowin.h" |
9 | #include <stdio.h> |
10 | |
11 | class CPerlStdIO : public IPerlStdIOWin |
12 | { |
13 | public: |
14 | CPerlStdIO() |
15 | { |
16 | pPerl = NULL; |
17 | pSock = NULL; |
18 | w32_platform = -1; |
565764a8 |
19 | ZeroMemory(bSocketTable, sizeof(bSocketTable)); |
76e3520e |
20 | }; |
21 | virtual PerlIO* Stdin(void); |
22 | virtual PerlIO* Stdout(void); |
23 | virtual PerlIO* Stderr(void); |
24 | virtual PerlIO* Open(const char *, const char *, int &err); |
25 | virtual int Close(PerlIO*, int &err); |
26 | virtual int Eof(PerlIO*, int &err); |
27 | virtual int Error(PerlIO*, int &err); |
28 | virtual void Clearerr(PerlIO*, int &err); |
29 | virtual int Getc(PerlIO*, int &err); |
30 | virtual char* GetBase(PerlIO *, int &err); |
31 | virtual int GetBufsiz(PerlIO *, int &err); |
32 | virtual int GetCnt(PerlIO *, int &err); |
33 | virtual char* GetPtr(PerlIO *, int &err); |
34 | virtual int Putc(PerlIO*, int, int &err); |
35 | virtual int Puts(PerlIO*, const char *, int &err); |
36 | virtual int Flush(PerlIO*, int &err); |
37 | virtual int Ungetc(PerlIO*,int, int &err); |
38 | virtual int Fileno(PerlIO*, int &err); |
39 | virtual PerlIO* Fdopen(int, const char *, int &err); |
565764a8 |
40 | virtual PerlIO* Reopen(const char*, const char*, PerlIO*, int &err); |
76e3520e |
41 | virtual SSize_t Read(PerlIO*,void *,Size_t, int &err); |
42 | virtual SSize_t Write(PerlIO*,const void *,Size_t, int &err); |
565764a8 |
43 | virtual void SetBuf(PerlIO *, char*, int &err); |
44 | virtual int SetVBuf(PerlIO *, char*, int, Size_t, int &err); |
76e3520e |
45 | virtual void SetCnt(PerlIO *, int, int &err); |
46 | virtual void SetPtrCnt(PerlIO *, char *, int, int& err); |
47 | virtual void Setlinebuf(PerlIO*, int &err); |
48 | virtual int Printf(PerlIO*, int &err, const char *,...); |
49 | virtual int Vprintf(PerlIO*, int &err, const char *, va_list); |
50 | virtual long Tell(PerlIO*, int &err); |
51 | virtual int Seek(PerlIO*, off_t, int, int &err); |
52 | virtual void Rewind(PerlIO*, int &err); |
53 | virtual PerlIO* Tmpfile(int &err); |
54 | virtual int Getpos(PerlIO*, Fpos_t *, int &err); |
55 | virtual int Setpos(PerlIO*, const Fpos_t *, int &err); |
56 | virtual void Init(int &err); |
57 | virtual void InitOSExtras(void* p); |
58 | virtual int OpenOSfhandle(long osfhandle, int flags); |
59 | virtual int GetOSfhandle(int filenum); |
60 | |
61 | void ShutDown(void); |
62 | |
63 | inline void SetPerlObj(CPerlObj *p) { pPerl = p; }; |
64 | inline void SetSockCtl(CPerlSock *p) { pSock = p; }; |
65 | protected: |
66 | inline int IsWin95(void) |
67 | { |
68 | return (os_id() == VER_PLATFORM_WIN32_WINDOWS); |
69 | }; |
70 | inline int IsWinNT(void) |
71 | { |
72 | return (os_id() == VER_PLATFORM_WIN32_NT); |
73 | }; |
74 | inline void AddToSocketTable(int fh) |
75 | { |
76 | if(fh < _NSTREAM_) |
77 | bSocketTable[fh] = TRUE; |
78 | }; |
79 | inline BOOL InSocketTable(int fh) |
80 | { |
81 | if(fh < _NSTREAM_) |
82 | return bSocketTable[fh]; |
83 | return FALSE; |
84 | }; |
85 | inline void RemoveFromSocketTable(int fh) |
86 | { |
87 | if(fh < _NSTREAM_) |
88 | bSocketTable[fh] = FALSE; |
89 | }; |
90 | DWORD os_id(void) |
91 | { |
92 | if((-1) == w32_platform) |
93 | { |
94 | OSVERSIONINFO osver; |
95 | |
96 | memset(&osver, 0, sizeof(OSVERSIONINFO)); |
97 | osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
98 | GetVersionEx(&osver); |
99 | w32_platform = osver.dwPlatformId; |
100 | } |
101 | return (w32_platform); |
102 | }; |
103 | |
104 | |
105 | CPerlObj *pPerl; |
106 | CPerlSock *pSock; |
107 | DWORD w32_platform; |
108 | BOOL bSocketTable[_NSTREAM_]; |
109 | }; |
110 | |
111 | void CPerlStdIO::ShutDown(void) |
112 | { |
113 | int i, err; |
114 | for(i = 0; i < _NSTREAM_; ++i) |
115 | { |
116 | if(InSocketTable(i)) |
117 | pSock->CloseSocket(i, err); |
118 | } |
119 | }; |
120 | |
121 | #ifdef _X86_ |
122 | extern "C" int __cdecl _alloc_osfhnd(void); |
123 | extern "C" int __cdecl _set_osfhnd(int fh, long value); |
124 | extern "C" void __cdecl _unlock(int); |
125 | |
126 | #if (_MSC_VER >= 1000) |
127 | typedef struct |
128 | { |
129 | long osfhnd; /* underlying OS file HANDLE */ |
130 | char osfile; /* attributes of file (e.g., open in text mode?) */ |
131 | char pipech; /* one char buffer for handles opened on pipes */ |
132 | } ioinfo; |
133 | extern "C" ioinfo * __pioinfo[]; |
134 | #define IOINFO_L2E 5 |
135 | #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) |
136 | #define _pioinfo(i) (__pioinfo[i >> IOINFO_L2E] + (i & (IOINFO_ARRAY_ELTS - 1))) |
137 | #define _osfile(i) (_pioinfo(i)->osfile) |
138 | #else |
139 | extern "C" extern char _osfile[]; |
140 | #endif // (_MSC_VER >= 1000) |
141 | |
142 | #define FOPEN 0x01 // file handle open |
143 | #define FAPPEND 0x20 // file handle opened O_APPEND |
144 | #define FDEV 0x40 // file handle refers to device |
145 | #define FTEXT 0x80 // file handle is in text mode |
146 | |
147 | #define _STREAM_LOCKS 26 // Table of stream locks |
148 | #define _LAST_STREAM_LOCK (_STREAM_LOCKS+_NSTREAM_-1) // Last stream lock |
149 | #define _FH_LOCKS (_LAST_STREAM_LOCK+1) // Table of fh locks |
150 | #endif // _X86_ |
151 | |
152 | int CPerlStdIO::OpenOSfhandle(long osfhandle, int flags) |
153 | { |
154 | int fh; |
155 | |
156 | #ifdef _X86_ |
157 | if(IsWin95()) |
158 | { |
159 | // all this is here to handle Win95's GetFileType bug. |
160 | char fileflags; // _osfile flags |
161 | |
162 | // copy relevant flags from second parameter |
163 | fileflags = FDEV; |
164 | |
165 | if(flags & _O_APPEND) |
166 | fileflags |= FAPPEND; |
167 | |
168 | if(flags & _O_TEXT) |
169 | fileflags |= FTEXT; |
170 | |
171 | // attempt to allocate a C Runtime file handle |
172 | if((fh = _alloc_osfhnd()) == -1) |
173 | { |
174 | errno = EMFILE; // too many open files |
175 | _doserrno = 0L; // not an OS error |
176 | return -1; // return error to caller |
177 | } |
178 | |
179 | // the file is open. now, set the info in _osfhnd array |
180 | _set_osfhnd(fh, osfhandle); |
181 | |
182 | fileflags |= FOPEN; // mark as open |
183 | |
184 | #if (_MSC_VER >= 1000) |
185 | _osfile(fh) = fileflags; // set osfile entry |
186 | #else |
187 | _osfile[fh] = fileflags; // set osfile entry |
188 | #endif |
189 | } |
190 | else |
191 | #endif // _X86_ |
192 | fh = _open_osfhandle(osfhandle, flags); |
193 | |
194 | if(fh >= 0) |
195 | AddToSocketTable(fh); |
196 | |
197 | return fh; // return handle |
198 | } |
199 | |
200 | int CPerlStdIO::GetOSfhandle(int filenum) |
201 | { |
202 | return _get_osfhandle(filenum); |
203 | } |
204 | |
205 | PerlIO* CPerlStdIO::Stdin(void) |
206 | { |
207 | return (PerlIO*)(&_iob[0]); |
208 | } |
209 | |
210 | PerlIO* CPerlStdIO::Stdout(void) |
211 | { |
212 | return (PerlIO*)(&_iob[1]); |
213 | } |
214 | |
215 | PerlIO* CPerlStdIO::Stderr(void) |
216 | { |
217 | return (PerlIO*)(&_iob[2]); |
218 | } |
219 | |
220 | PerlIO* CPerlStdIO::Open(const char *path, const char *mode, int &err) |
221 | { |
222 | PerlIO* ret = NULL; |
223 | if(*path != '\0') |
224 | { |
565764a8 |
225 | if(stricmp(path, "/dev/null") == 0) |
226 | ret = (PerlIO*)fopen("NUL", mode); |
227 | else |
228 | ret = (PerlIO*)fopen(path, mode); |
229 | |
76e3520e |
230 | if(errno) |
231 | err = errno; |
232 | } |
233 | else |
234 | err = EINVAL; |
235 | return ret; |
236 | } |
237 | |
238 | extern "C" int _free_osfhnd(int fh); |
239 | int CPerlStdIO::Close(PerlIO* pf, int &err) |
240 | { |
241 | int ret = 0, fileNo = fileno((FILE*)pf); |
242 | if(InSocketTable(fileNo)) |
243 | { |
244 | RemoveFromSocketTable(fileNo); |
245 | pSock->CloseSocket(fileNo, err); |
246 | _free_osfhnd(fileNo); |
247 | fclose((FILE*)pf); |
248 | } |
249 | else |
250 | ret = fclose((FILE*)pf); |
251 | |
252 | if(errno) |
253 | err = errno; |
254 | return ret; |
255 | } |
256 | |
257 | int CPerlStdIO::Eof(PerlIO* pf, int &err) |
258 | { |
259 | int ret = feof((FILE*)pf); |
260 | if(errno) |
261 | err = errno; |
262 | return ret; |
263 | } |
264 | |
265 | int CPerlStdIO::Error(PerlIO* pf, int &err) |
266 | { |
267 | int ret = ferror((FILE*)pf); |
268 | if(errno) |
269 | err = errno; |
270 | return ret; |
271 | } |
272 | |
273 | void CPerlStdIO::Clearerr(PerlIO* pf, int &err) |
274 | { |
275 | clearerr((FILE*)pf); |
276 | err = 0; |
277 | } |
278 | |
279 | int CPerlStdIO::Getc(PerlIO* pf, int &err) |
280 | { |
281 | int ret = fgetc((FILE*)pf); |
282 | if(errno) |
283 | err = errno; |
284 | return ret; |
285 | } |
286 | |
287 | int CPerlStdIO::Putc(PerlIO* pf, int c, int &err) |
288 | { |
289 | int ret = fputc(c, (FILE*)pf); |
290 | if(errno) |
291 | err = errno; |
292 | return ret; |
293 | } |
294 | |
295 | int CPerlStdIO::Puts(PerlIO* pf, const char *s, int &err) |
296 | { |
297 | int ret = fputs(s, (FILE*)pf); |
298 | if(errno) |
299 | err = errno; |
300 | return ret; |
301 | } |
302 | |
303 | int CPerlStdIO::Flush(PerlIO* pf, int &err) |
304 | { |
305 | int ret = fflush((FILE*)pf); |
306 | if(errno) |
307 | err = errno; |
308 | return ret; |
309 | } |
310 | |
311 | int CPerlStdIO::Ungetc(PerlIO* pf,int c, int &err) |
312 | { |
313 | int ret = ungetc(c, (FILE*)pf); |
314 | if(errno) |
315 | err = errno; |
316 | return ret; |
317 | } |
318 | |
319 | int CPerlStdIO::Fileno(PerlIO* pf, int &err) |
320 | { |
321 | int ret = fileno((FILE*)pf); |
322 | if(errno) |
323 | err = errno; |
324 | return ret; |
325 | } |
326 | |
327 | PerlIO* CPerlStdIO::Fdopen(int fh, const char *mode, int &err) |
328 | { |
329 | PerlIO* ret = (PerlIO*)fdopen(fh, mode); |
330 | if(errno) |
331 | err = errno; |
332 | return ret; |
333 | } |
334 | |
565764a8 |
335 | PerlIO* CPerlStdIO::Reopen(const char* filename, const char* mode, PerlIO* pf, int &err) |
336 | { |
337 | PerlIO* ret = (PerlIO*)freopen(filename, mode, (FILE*)pf); |
338 | if(errno) |
339 | err = errno; |
340 | return ret; |
341 | } |
342 | |
76e3520e |
343 | SSize_t CPerlStdIO::Read(PerlIO* pf, void * buffer, Size_t count, int &err) |
344 | { |
345 | size_t ret = fread(buffer, 1, count, (FILE*)pf); |
346 | if(errno) |
347 | err = errno; |
348 | return ret; |
349 | } |
350 | |
351 | SSize_t CPerlStdIO::Write(PerlIO* pf, const void * buffer, Size_t count, int &err) |
352 | { |
353 | size_t ret = fwrite(buffer, 1, count, (FILE*)pf); |
354 | if(errno) |
355 | err = errno; |
356 | return ret; |
357 | } |
358 | |
565764a8 |
359 | void CPerlStdIO::Setlinebuf(PerlIO*pf, int &err) |
76e3520e |
360 | { |
565764a8 |
361 | setvbuf((FILE*)pf, NULL, _IOLBF, 0); |
76e3520e |
362 | } |
363 | |
364 | int CPerlStdIO::Printf(PerlIO* pf, int &err, const char *format, ...) |
365 | { |
366 | va_list(arglist); |
367 | va_start(arglist, format); |
368 | int ret = Vprintf(pf, err, format, arglist); |
369 | if(errno) |
370 | err = errno; |
371 | return ret; |
372 | } |
373 | |
374 | int CPerlStdIO::Vprintf(PerlIO* pf, int &err, const char * format, va_list arg) |
375 | { |
376 | int ret = vfprintf((FILE*)pf, format, arg); |
377 | if(errno) |
378 | err = errno; |
379 | return ret; |
380 | } |
381 | |
382 | long CPerlStdIO::Tell(PerlIO* pf, int &err) |
383 | { |
384 | long ret = ftell((FILE*)pf); |
385 | if(errno) |
386 | err = errno; |
387 | return ret; |
388 | } |
389 | |
390 | int CPerlStdIO::Seek(PerlIO* pf, off_t offset, int origin, int &err) |
391 | { |
392 | int ret = fseek((FILE*)pf, offset, origin); |
393 | if(errno) |
394 | err = errno; |
395 | return ret; |
396 | } |
397 | |
398 | void CPerlStdIO::Rewind(PerlIO* pf, int &err) |
399 | { |
400 | rewind((FILE*)pf); |
401 | } |
402 | |
403 | PerlIO* CPerlStdIO::Tmpfile(int &err) |
404 | { |
405 | return (PerlIO*)tmpfile(); |
406 | } |
407 | |
408 | int CPerlStdIO::Getpos(PerlIO* pf, Fpos_t *p, int &err) |
409 | { |
410 | int ret = fgetpos((FILE*)pf, (fpos_t*)p); |
411 | if(errno) |
412 | err = errno; |
413 | return ret; |
414 | } |
415 | |
416 | int CPerlStdIO::Setpos(PerlIO* pf, const Fpos_t *p, int &err) |
417 | { |
418 | int ret = fsetpos((FILE*)pf, (fpos_t*)p); |
419 | if(errno) |
420 | err = errno; |
421 | return ret; |
422 | } |
423 | |
424 | char* CPerlStdIO::GetBase(PerlIO *pf, int &err) |
425 | { |
426 | return ((FILE*)pf)->_base; |
427 | } |
428 | |
429 | int CPerlStdIO::GetBufsiz(PerlIO *pf, int &err) |
430 | { |
431 | return ((FILE*)pf)->_bufsiz; |
432 | } |
433 | |
434 | int CPerlStdIO::GetCnt(PerlIO *pf, int &err) |
435 | { |
436 | return ((FILE*)pf)->_cnt; |
437 | } |
438 | |
439 | char* CPerlStdIO::GetPtr(PerlIO *pf, int &err) |
440 | { |
441 | return ((FILE*)pf)->_ptr; |
442 | } |
443 | |
565764a8 |
444 | void CPerlStdIO::SetBuf(PerlIO *pf, char* buffer, int &err) |
445 | { |
446 | setbuf((FILE*)pf, buffer); |
447 | } |
448 | |
449 | int CPerlStdIO::SetVBuf(PerlIO *pf, char* buffer, int type, Size_t size, int &err) |
450 | { |
451 | return setvbuf((FILE*)pf, buffer, type, size); |
452 | } |
453 | |
76e3520e |
454 | void CPerlStdIO::SetCnt(PerlIO *pf, int n, int &err) |
455 | { |
456 | ((FILE*)pf)->_cnt = n; |
457 | } |
458 | |
459 | void CPerlStdIO::SetPtrCnt(PerlIO *pf, char *ptr, int n, int& err) |
460 | { |
461 | ((FILE*)pf)->_ptr = ptr; |
462 | ((FILE*)pf)->_cnt = n; |
463 | } |
464 | |
465 | void CPerlStdIO::Init(int &err) |
466 | { |
467 | } |
468 | |
9d8a25dc |
469 | |
470 | static |
471 | XS(w32_GetCwd) |
472 | { |
473 | dXSARGS; |
474 | SV *sv = sv_newmortal(); |
475 | /* Make one call with zero size - return value is required size */ |
476 | DWORD len = GetCurrentDirectory((DWORD)0,NULL); |
477 | SvUPGRADE(sv,SVt_PV); |
478 | SvGROW(sv,len); |
479 | SvCUR(sv) = GetCurrentDirectory((DWORD) SvLEN(sv), SvPVX(sv)); |
480 | /* |
481 | * If result != 0 |
482 | * then it worked, set PV valid, |
483 | * else leave it 'undef' |
484 | */ |
485 | if (SvCUR(sv)) |
486 | SvPOK_on(sv); |
487 | EXTEND(sp,1); |
488 | ST(0) = sv; |
489 | XSRETURN(1); |
490 | } |
491 | |
492 | static |
493 | XS(w32_SetCwd) |
494 | { |
495 | dXSARGS; |
496 | if (items != 1) |
497 | croak("usage: Win32::SetCurrentDirectory($cwd)"); |
498 | if (SetCurrentDirectory(SvPV(ST(0),na))) |
499 | XSRETURN_YES; |
500 | |
501 | XSRETURN_NO; |
502 | } |
503 | |
504 | static |
505 | XS(w32_GetNextAvailDrive) |
506 | { |
507 | dXSARGS; |
508 | char ix = 'C'; |
509 | char root[] = "_:\\"; |
510 | while (ix <= 'Z') { |
511 | root[0] = ix++; |
512 | if (GetDriveType(root) == 1) { |
513 | root[2] = '\0'; |
514 | XSRETURN_PV(root); |
515 | } |
516 | } |
517 | XSRETURN_UNDEF; |
518 | } |
519 | |
520 | static |
521 | XS(w32_GetLastError) |
522 | { |
523 | dXSARGS; |
524 | XSRETURN_IV(GetLastError()); |
525 | } |
526 | |
527 | static |
528 | XS(w32_LoginName) |
529 | { |
530 | dXSARGS; |
531 | char szBuffer[128]; |
532 | DWORD size = sizeof(szBuffer); |
533 | if (GetUserName(szBuffer, &size)) { |
534 | /* size includes NULL */ |
535 | ST(0) = sv_2mortal(newSVpv(szBuffer,size-1)); |
536 | XSRETURN(1); |
537 | } |
538 | XSRETURN_UNDEF; |
539 | } |
540 | |
541 | static |
542 | XS(w32_NodeName) |
543 | { |
544 | dXSARGS; |
545 | char name[MAX_COMPUTERNAME_LENGTH+1]; |
546 | DWORD size = sizeof(name); |
547 | if (GetComputerName(name,&size)) { |
548 | /* size does NOT include NULL :-( */ |
549 | ST(0) = sv_2mortal(newSVpv(name,size)); |
550 | XSRETURN(1); |
551 | } |
552 | XSRETURN_UNDEF; |
553 | } |
554 | |
555 | |
556 | static |
557 | XS(w32_DomainName) |
558 | { |
559 | dXSARGS; |
560 | char name[256]; |
561 | DWORD size = sizeof(name); |
562 | if (GetUserName(name,&size)) { |
563 | char sid[1024]; |
564 | DWORD sidlen = sizeof(sid); |
565 | char dname[256]; |
566 | DWORD dnamelen = sizeof(dname); |
567 | SID_NAME_USE snu; |
568 | if (LookupAccountName(NULL, name, &sid, &sidlen, |
569 | dname, &dnamelen, &snu)) { |
570 | XSRETURN_PV(dname); /* all that for this */ |
571 | } |
572 | } |
573 | XSRETURN_UNDEF; |
574 | } |
575 | |
576 | static |
577 | XS(w32_FsType) |
578 | { |
579 | dXSARGS; |
580 | char fsname[256]; |
581 | DWORD flags, filecomplen; |
582 | if (GetVolumeInformation(NULL, NULL, 0, NULL, &filecomplen, |
583 | &flags, fsname, sizeof(fsname))) { |
584 | if (GIMME == G_ARRAY) { |
585 | XPUSHs(sv_2mortal(newSVpv(fsname,0))); |
586 | XPUSHs(sv_2mortal(newSViv(flags))); |
587 | XPUSHs(sv_2mortal(newSViv(filecomplen))); |
588 | PUTBACK; |
589 | return; |
590 | } |
591 | XSRETURN_PV(fsname); |
592 | } |
593 | XSRETURN_UNDEF; |
594 | } |
595 | |
596 | static |
597 | XS(w32_GetOSVersion) |
598 | { |
599 | dXSARGS; |
600 | OSVERSIONINFO osver; |
601 | |
602 | osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
603 | if (GetVersionEx(&osver)) { |
604 | XPUSHs(newSVpv(osver.szCSDVersion, 0)); |
605 | XPUSHs(newSViv(osver.dwMajorVersion)); |
606 | XPUSHs(newSViv(osver.dwMinorVersion)); |
607 | XPUSHs(newSViv(osver.dwBuildNumber)); |
608 | XPUSHs(newSViv(osver.dwPlatformId)); |
609 | PUTBACK; |
610 | return; |
611 | } |
612 | XSRETURN_UNDEF; |
613 | } |
614 | |
615 | static |
616 | XS(w32_IsWinNT) |
617 | { |
618 | dXSARGS; |
619 | OSVERSIONINFO osver; |
620 | memset(&osver, 0, sizeof(OSVERSIONINFO)); |
621 | osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
622 | GetVersionEx(&osver); |
623 | XSRETURN_IV(VER_PLATFORM_WIN32_NT == osver.dwPlatformId); |
624 | } |
625 | |
626 | static |
627 | XS(w32_IsWin95) |
628 | { |
629 | dXSARGS; |
630 | OSVERSIONINFO osver; |
631 | memset(&osver, 0, sizeof(OSVERSIONINFO)); |
632 | osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
633 | GetVersionEx(&osver); |
634 | XSRETURN_IV(VER_PLATFORM_WIN32_WINDOWS == osver.dwPlatformId); |
635 | } |
636 | |
637 | static |
638 | XS(w32_FormatMessage) |
639 | { |
640 | dXSARGS; |
641 | DWORD source = 0; |
642 | char msgbuf[1024]; |
643 | |
644 | if (items != 1) |
645 | croak("usage: Win32::FormatMessage($errno)"); |
646 | |
647 | if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, |
648 | &source, SvIV(ST(0)), 0, |
649 | msgbuf, sizeof(msgbuf)-1, NULL)) |
650 | XSRETURN_PV(msgbuf); |
651 | |
652 | XSRETURN_UNDEF; |
653 | } |
654 | |
655 | static |
656 | XS(w32_Spawn) |
657 | { |
658 | dXSARGS; |
659 | char *cmd, *args; |
660 | PROCESS_INFORMATION stProcInfo; |
661 | STARTUPINFO stStartInfo; |
662 | BOOL bSuccess = FALSE; |
663 | |
664 | if(items != 3) |
665 | croak("usage: Win32::Spawn($cmdName, $args, $PID)"); |
666 | |
667 | cmd = SvPV(ST(0),na); |
668 | args = SvPV(ST(1), na); |
669 | |
670 | memset(&stStartInfo, 0, sizeof(stStartInfo)); /* Clear the block */ |
671 | stStartInfo.cb = sizeof(stStartInfo); /* Set the structure size */ |
672 | stStartInfo.dwFlags = STARTF_USESHOWWINDOW; /* Enable wShowWindow control */ |
673 | stStartInfo.wShowWindow = SW_SHOWMINNOACTIVE; /* Start min (normal) */ |
674 | |
675 | if(CreateProcess( |
676 | cmd, /* Image path */ |
677 | args, /* Arguments for command line */ |
678 | NULL, /* Default process security */ |
679 | NULL, /* Default thread security */ |
680 | FALSE, /* Must be TRUE to use std handles */ |
681 | NORMAL_PRIORITY_CLASS, /* No special scheduling */ |
682 | NULL, /* Inherit our environment block */ |
683 | NULL, /* Inherit our currrent directory */ |
684 | &stStartInfo, /* -> Startup info */ |
685 | &stProcInfo)) /* <- Process info (if OK) */ |
686 | { |
687 | CloseHandle(stProcInfo.hThread);/* library source code does this. */ |
688 | sv_setiv(ST(2), stProcInfo.dwProcessId); |
689 | bSuccess = TRUE; |
690 | } |
691 | XSRETURN_IV(bSuccess); |
692 | } |
693 | |
694 | static |
695 | XS(w32_GetTickCount) |
696 | { |
697 | dXSARGS; |
698 | XSRETURN_IV(GetTickCount()); |
699 | } |
700 | |
701 | static |
702 | XS(w32_GetShortPathName) |
703 | { |
704 | dXSARGS; |
705 | SV *shortpath; |
706 | DWORD len; |
707 | |
708 | if(items != 1) |
709 | croak("usage: Win32::GetShortPathName($longPathName)"); |
710 | |
711 | shortpath = sv_mortalcopy(ST(0)); |
712 | SvUPGRADE(shortpath, SVt_PV); |
713 | /* src == target is allowed */ |
714 | do { |
715 | len = GetShortPathName(SvPVX(shortpath), |
716 | SvPVX(shortpath), |
717 | SvLEN(shortpath)); |
718 | } while (len >= SvLEN(shortpath) && sv_grow(shortpath,len+1)); |
719 | if (len) { |
720 | SvCUR_set(shortpath,len); |
721 | ST(0) = shortpath; |
722 | } |
723 | else |
724 | ST(0) = &sv_undef; |
725 | XSRETURN(1); |
726 | } |
727 | |
728 | |
76e3520e |
729 | void CPerlStdIO::InitOSExtras(void* p) |
730 | { |
9d8a25dc |
731 | char *file = __FILE__; |
732 | dXSUB_SYS; |
733 | |
734 | /* XXX should be removed after checking with Nick */ |
735 | newXS("Win32::GetCurrentDirectory", w32_GetCwd, file); |
736 | |
737 | /* these names are Activeware compatible */ |
738 | newXS("Win32::GetCwd", w32_GetCwd, file); |
739 | newXS("Win32::SetCwd", w32_SetCwd, file); |
740 | newXS("Win32::GetNextAvailDrive", w32_GetNextAvailDrive, file); |
741 | newXS("Win32::GetLastError", w32_GetLastError, file); |
742 | newXS("Win32::LoginName", w32_LoginName, file); |
743 | newXS("Win32::NodeName", w32_NodeName, file); |
744 | newXS("Win32::DomainName", w32_DomainName, file); |
745 | newXS("Win32::FsType", w32_FsType, file); |
746 | newXS("Win32::GetOSVersion", w32_GetOSVersion, file); |
747 | newXS("Win32::IsWinNT", w32_IsWinNT, file); |
748 | newXS("Win32::IsWin95", w32_IsWin95, file); |
749 | newXS("Win32::FormatMessage", w32_FormatMessage, file); |
750 | newXS("Win32::Spawn", w32_Spawn, file); |
751 | newXS("Win32::GetTickCount", w32_GetTickCount, file); |
752 | newXS("Win32::GetShortPathName", w32_GetShortPathName, file); |
753 | |
76e3520e |
754 | } |
755 | |
756 | |