X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fwin32.c;h=26cf26f8db407f4bd8e36ed8fb67497edd00a99c;hb=161b471ac314d8d6343f9f351e5fb9ef816168a8;hp=ceaca7ed194df5c3eaab4a1daafc8bbfedead04f;hpb=67fbe06e7fe7dfa95ec51821be9237cabdf281e2;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/win32.c b/win32/win32.c index ceaca7e..26cf26f 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -30,18 +30,12 @@ #include #include -#define CROAK croak -#define WARN warn - #define EXECF_EXEC 1 #define EXECF_SPAWN 2 #define EXECF_SPAWN_NOWAIT 3 static DWORD IdOS(void); -extern WIN32_IOSUBSYSTEM win32stdio; -static PWIN32_IOSUBSYSTEM pIOSubSystem = &win32stdio; - BOOL ProbeEnv = FALSE; DWORD Win32System = (DWORD)-1; char szShellPath[MAX_PATH+1]; @@ -60,23 +54,6 @@ IsWinNT(void) { return (IdOS() == VER_PLATFORM_WIN32_NT); } -void * -SetIOSubSystem(void *p) -{ - PWIN32_IOSUBSYSTEM old = pIOSubSystem; - if (p) { - PWIN32_IOSUBSYSTEM pio = (PWIN32_IOSUBSYSTEM)p; - if (pio->signature_begin == 12345678L - && pio->signature_end == 87654321L) { - pIOSubSystem = pio; - } - } - else { - pIOSubSystem = &win32stdio; - } - return old; -} - char * win32PerlLibPath(void) { @@ -162,156 +139,12 @@ my_popen(char *cmd, char *mode) #else #define fixcmd(x) #endif - -#if 1 -/* was #ifndef PERLDLL, but the #else stuff doesn't work on NT - * GSAR 97/03/13 - */ fixcmd(cmd); #ifdef __BORLANDC__ /* workaround a Borland stdio bug */ win32_fflush(stdout); win32_fflush(stderr); #endif return win32_popen(cmd, mode); -#else -/* - * There seems to be some problems for the _popen call in a DLL - * this trick at the moment seems to work but it is never test - * on NT yet - * - */ -# ifdef __cplusplus -#define EXT_C_FUNC extern "C" -# else -#define EXT_C_FUNC extern -# endif - - EXT_C_FUNC int __cdecl _set_osfhnd(int fh, long value); - EXT_C_FUNC void __cdecl _lock_fhandle(int); - EXT_C_FUNC void __cdecl _unlock_fhandle(int); - - BOOL fSuccess; - PerlIO *pf; /* to store the _popen return value */ - int tm = 0; /* flag indicating tDllExport or binary mode */ - int fhNeeded, fhInherited, fhDup; - int ineeded, iinherited; - DWORD dwDup; - int phdls[2]; /* I/O handles for pipe */ - HANDLE hPIn, hPOut, hPErr, - hSaveStdin, hSaveStdout, hSaveStderr, - hPNeeded, hPInherited, hPDuped; - - /* first check for errors in the arguments */ - if ( (cmd == NULL) || (mode == NULL) - || ((*mode != 'w') && (*mode != _T('r'))) ) - goto error1; - - if ( *(mode + 1) == _T('t') ) - tm = O_TEXT; - else if ( *(mode + 1) == _T('b') ) - tm = O_BINARY; - else - tm = (*mode == 'w' ? O_BINARY : O_TEXT); - - - fixcmd(cmd); - if (&win32stdio != pIOSubSystem) - return win32_popen(cmd, mode); - -#ifdef EFG - if ( _pipe( phdls, 1024, tm ) == -1 ) -#else - if ( win32_pipe( phdls, 1024, tm ) == -1 ) -#endif - goto error1; - - /* save the current situation */ - hSaveStdin = GetStdHandle(STD_INPUT_HANDLE); - hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); - hSaveStderr = GetStdHandle(STD_ERROR_HANDLE); - - if (*mode == _T('w')) { - ineeded = 1; - dwDup = STD_INPUT_HANDLE; - iinherited = 0; - } - else { - ineeded = 0; - dwDup = STD_OUTPUT_HANDLE; - iinherited = 1; - } - - fhNeeded = phdls[ineeded]; - fhInherited = phdls[iinherited]; - - fSuccess = DuplicateHandle(GetCurrentProcess(), - (HANDLE) stolen_get_osfhandle(fhNeeded), - GetCurrentProcess(), - &hPNeeded, - 0, - FALSE, /* not inherited */ - DUPLICATE_SAME_ACCESS); - - if (!fSuccess) - goto error2; - - fhDup = stolen_open_osfhandle((long) hPNeeded, tm); - win32_dup2(fhDup, fhNeeded); - win32_close(fhDup); - -#ifdef AAA - /* Close the Out pipe, child won't need it */ - hPDuped = (HANDLE) stolen_get_osfhandle(fhNeeded); - - _lock_fhandle(fhNeeded); - _set_osfhnd(fhNeeded, (long)hPNeeded); /* put in ours duplicated one */ - _unlock_fhandle(fhNeeded); - - CloseHandle(hPDuped); /* close the handle first */ -#endif - - if (!SetStdHandle(dwDup, (HANDLE) stolen_get_osfhandle(fhInherited))) - goto error2; - - /* - * make sure the child see the same stderr as the calling program - */ - if (!SetStdHandle(STD_ERROR_HANDLE, - (HANDLE)stolen_get_osfhandle(win32_fileno(win32_stderr())))) - goto error2; - - pf = win32_popen(cmd, mode); /* ask _popen to do the job */ - - /* restore to where we were */ - SetStdHandle(STD_INPUT_HANDLE, hSaveStdin); - SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout); - SetStdHandle(STD_ERROR_HANDLE, hSaveStderr); - - /* we don't need it any more, that's for the child */ - win32_close(fhInherited); - - if (NULL == pf) { - /* something wrong */ - win32_close(fhNeeded); - goto error1; - } - else { - /* - * here we steal the file handle in pf and stuff ours in - */ - win32_dup2(fhNeeded, win32_fileno(pf)); - win32_close(fhNeeded); - } - return (pf); - -error2: - win32_close(fhNeeded); - win32_close(fhInherited); - -error1: - return (NULL); - -#endif } long @@ -355,7 +188,7 @@ GetShell(void) } int -do_aspawn(void* really, void** mark, void** arglast) +do_aspawn(void* really, void ** mark, void ** arglast) { char **argv; char *strPtr; @@ -373,7 +206,8 @@ do_aspawn(void* really, void** mark, void** arglast) } else { argv[index++] = cmd = GetShell(); - argv[index++] = "/x"; /* always enable command extensions */ + if (IsWinNT()) + argv[index++] = "/x"; /* always enable command extensions */ argv[index++] = "/c"; } @@ -449,8 +283,11 @@ do_spawn2(char *cmd, int exectype) } if(needToTry) { char *argv[5]; - argv[0] = shell; argv[1] = "/x"; argv[2] = "/c"; - argv[3] = cmd; argv[4] = Nullch; + int i = 0; + argv[i++] = shell; + if (IsWinNT()) + argv[i++] = "/x"; + argv[i++] = "/c"; argv[i++] = cmd; argv[i] = Nullch; switch (exectype) { case EXECF_SPAWN: status = win32_spawnvp(P_WAIT, argv[0], @@ -514,7 +351,7 @@ opendir(char *filename) /* char *dummy;*/ /* check to see if filename is a directory */ - if (win32_stat(filename, &sbuf) < 0 || sbuf.st_mode & S_IFDIR == 0) { + if (win32_stat(filename, &sbuf) < 0 || (sbuf.st_mode & S_IFDIR) == 0) { return NULL; } @@ -556,7 +393,7 @@ opendir(char *filename) idx = strlen(FindData.cFileName)+1; New(1304, p->start, idx, char); if(p->start == NULL) { - CROAK("opendir: malloc failed!\n"); + croak("opendir: malloc failed!\n"); } strcpy(p->start, FindData.cFileName); /* if(downcase) @@ -576,7 +413,7 @@ opendir(char *filename) */ Renew(p->start, idx+len+1, char); if(p->start == NULL) { - CROAK("opendir: malloc failed!\n"); + croak("opendir: malloc failed!\n"); } strcpy(&p->start[idx], FindData.cFileName); /* if (downcase) @@ -715,11 +552,11 @@ kill(int pid, int sig) HANDLE hProcess= OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid); if (hProcess == NULL) { - CROAK("kill process failed!\n"); + croak("kill process failed!\n"); } else { if (!TerminateProcess(hProcess, sig)) - CROAK("kill process failed!\n"); + croak("kill process failed!\n"); CloseHandle(hProcess); } return 0; @@ -733,31 +570,18 @@ kill(int pid, int sig) int ioctl(int i, unsigned int u, char *data) { - CROAK("ioctl not implemented!\n"); + croak("ioctl not implemented!\n"); return -1; } #endif -unsigned int -sleep(unsigned int t) +DllExport unsigned int +win32_sleep(unsigned int t) { Sleep(t*1000); return 0; } - -#undef rename - -int -myrename(char *OldFileName, char *newname) -{ - if(_access(newname, 0) != -1) { /* file exists */ - _unlink(newname); - } - return rename(OldFileName, newname); -} - - DllExport int win32_stat(const char *path, struct stat *buffer) { @@ -777,7 +601,7 @@ win32_stat(const char *path, struct stat *buffer) }; } } - res = pIOSubSystem->pfnstat(p,buffer); + res = stat(p,buffer); #ifdef __BORLANDC__ if (res == 0) { if (S_ISDIR(buffer->st_mode)) @@ -823,29 +647,227 @@ win32_getenv(const char *name) #endif -#undef times -int -mytimes(struct tms *timebuf) +static long +FileTimeToClock(PFILETIME ft) { - clock_t t = clock(); - timebuf->tms_utime = t; - timebuf->tms_stime = 0; - timebuf->tms_cutime = 0; - timebuf->tms_cstime = 0; + __int64 qw = ft->dwHighDateTime; + qw <<= 32; + qw |= ft->dwLowDateTime; + qw /= 10000; /* File time ticks at 0.1uS, clock at 1mS */ + return (long) qw; +} +DllExport int +win32_times(struct tms *timebuf) +{ + FILETIME user; + FILETIME kernel; + FILETIME dummy; + if (GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, + &kernel,&user)) { + timebuf->tms_utime = FileTimeToClock(&user); + timebuf->tms_stime = FileTimeToClock(&kernel); + timebuf->tms_cutime = 0; + timebuf->tms_cstime = 0; + + } else { + /* That failed - e.g. Win95 fallback to clock() */ + clock_t t = clock(); + timebuf->tms_utime = t; + timebuf->tms_stime = 0; + timebuf->tms_cutime = 0; + timebuf->tms_cstime = 0; + } return 0; } -#undef alarm -unsigned int -myalarm(unsigned int sec) +static UINT timerid = 0; + + +static VOID CALLBACK TimerProc(HWND win, UINT msg, UINT id, DWORD time) +{ + KillTimer(NULL,timerid); + timerid=0; + sighandler(14); +} + +DllExport unsigned int +win32_alarm(unsigned int sec) { - /* we warn the usuage of alarm function */ - if (sec != 0) - WARN("dummy function alarm called, program might not function as expected\n"); + /* + * the 'obvious' implentation is SetTimer() with a callback + * which does whatever receiving SIGALRM would do + * we cannot use SIGALRM even via raise() as it is not + * one of the supported codes in + * + * Snag is unless something is looking at the message queue + * nothing happens :-( + */ + if (sec) + { + timerid = SetTimer(NULL,timerid,sec*1000,(TIMERPROC)TimerProc); + if (!timerid) + croak("Cannot set timer"); + } + else + { + if (timerid) + { + KillTimer(NULL,timerid); + timerid=0; + } + } return 0; } +#ifdef USE_FIXED_OSFHANDLE + +EXTERN_C int __cdecl _alloc_osfhnd(void); +EXTERN_C int __cdecl _set_osfhnd(int fh, long value); +EXTERN_C void __cdecl _lock_fhandle(int); +EXTERN_C void __cdecl _unlock_fhandle(int); +EXTERN_C void __cdecl _unlock(int); + +#if (_MSC_VER >= 1000) +typedef struct { + long osfhnd; /* underlying OS file HANDLE */ + char osfile; /* attributes of file (e.g., open in text mode?) */ + char pipech; /* one char buffer for handles opened on pipes */ +#if defined (_MT) && !defined (DLL_FOR_WIN32S) + int lockinitflag; + CRITICAL_SECTION lock; +#endif /* defined (_MT) && !defined (DLL_FOR_WIN32S) */ +} ioinfo; + +EXTERN_C ioinfo * __pioinfo[]; + +#define IOINFO_L2E 5 +#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) +#define _pioinfo(i) (__pioinfo[i >> IOINFO_L2E] + (i & (IOINFO_ARRAY_ELTS - 1))) +#define _osfile(i) (_pioinfo(i)->osfile) + +#else /* (_MSC_VER >= 1000) */ +extern char _osfile[]; +#endif /* (_MSC_VER >= 1000) */ + +#define FOPEN 0x01 /* file handle open */ +#define FAPPEND 0x20 /* file handle opened O_APPEND */ +#define FDEV 0x40 /* file handle refers to device */ +#define FTEXT 0x80 /* file handle is in text mode */ + +#define _STREAM_LOCKS 26 /* Table of stream locks */ +#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_NSTREAM_-1) /* Last stream lock */ +#define _FH_LOCKS (_LAST_STREAM_LOCK+1) /* Table of fh locks */ + +/*** +*int my_open_osfhandle(long osfhandle, int flags) - open C Runtime file handle +* +*Purpose: +* This function allocates a free C Runtime file handle and associates +* it with the Win32 HANDLE specified by the first parameter. This is a +* temperary fix for WIN95's brain damage GetFileType() error on socket +* we just bypass that call for socket +* +*Entry: +* long osfhandle - Win32 HANDLE to associate with C Runtime file handle. +* int flags - flags to associate with C Runtime file handle. +* +*Exit: +* returns index of entry in fh, if successful +* return -1, if no free entry is found +* +*Exceptions: +* +*******************************************************************************/ + +static int +my_open_osfhandle(long osfhandle, int flags) +{ + int fh; + char fileflags; /* _osfile flags */ + + /* copy relevant flags from second parameter */ + fileflags = FDEV; + + if(flags & O_APPEND) + fileflags |= FAPPEND; + + if(flags & O_TEXT) + fileflags |= FTEXT; + + /* attempt to allocate a C Runtime file handle */ + if((fh = _alloc_osfhnd()) == -1) { + errno = EMFILE; /* too many open files */ + _doserrno = 0L; /* not an OS error */ + return -1; /* return error to caller */ + } + + /* the file is open. now, set the info in _osfhnd array */ + _set_osfhnd(fh, osfhandle); + + fileflags |= FOPEN; /* mark as open */ + +#if (_MSC_VER >= 1000) + _osfile(fh) = fileflags; /* set osfile entry */ + _unlock_fhandle(fh); +#else + _osfile[fh] = fileflags; /* set osfile entry */ + _unlock(fh+_FH_LOCKS); /* unlock handle */ +#endif + + return fh; /* return handle */ +} + +#define _open_osfhandle my_open_osfhandle +#endif /* USE_FIXED_OSFHANDLE */ + +/* simulate flock by locking a range on the file */ + +#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError())) +#define LK_LEN 0xffff0000 + +DllExport int +win32_flock(int fd, int oper) +{ + OVERLAPPED o; + int i = -1; + HANDLE fh; + + if (!IsWinNT()) { + croak("flock() unimplemented on this platform"); + return -1; + } + fh = (HANDLE)_get_osfhandle(fd); + memset(&o, 0, sizeof(o)); + + switch(oper) { + case LOCK_SH: /* shared lock */ + LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i); + break; + case LOCK_EX: /* exclusive lock */ + LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i); + break; + case LOCK_SH|LOCK_NB: /* non-blocking shared lock */ + LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i); + break; + case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */ + LK_ERR(LockFileEx(fh, + LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, + 0, LK_LEN, 0, &o),i); + break; + case LOCK_UN: /* unlock lock */ + LK_ERR(UnlockFileEx(fh, 0, LK_LEN, 0, &o),i); + break; + default: /* unknown */ + errno = EINVAL; + break; + } + return i; +} + +#undef LK_ERR +#undef LK_LEN + /* * redirected io subsystem for all XS modules * @@ -854,45 +876,45 @@ myalarm(unsigned int sec) DllExport int * win32_errno(void) { - return (pIOSubSystem->pfnerrno()); + return (&errno); } DllExport char *** win32_environ(void) { - return (pIOSubSystem->pfnenviron()); + return (&(_environ)); } /* the rest are the remapped stdio routines */ DllExport FILE * win32_stderr(void) { - return (pIOSubSystem->pfnstderr()); + return (stderr); } DllExport FILE * win32_stdin(void) { - return (pIOSubSystem->pfnstdin()); + return (stdin); } DllExport FILE * win32_stdout() { - return (pIOSubSystem->pfnstdout()); + return (stdout); } DllExport int win32_ferror(FILE *fp) { - return (pIOSubSystem->pfnferror(fp)); + return (ferror(fp)); } DllExport int win32_feof(FILE *fp) { - return (pIOSubSystem->pfnfeof(fp)); + return (feof(fp)); } /* @@ -921,7 +943,7 @@ win32_strerror(int e) return strerror_buffer; } - return pIOSubSystem->pfnstrerror(e); + return strerror(e); } DllExport int @@ -930,7 +952,7 @@ win32_fprintf(FILE *fp, const char *format, ...) va_list marker; va_start(marker, format); /* Initialize variable arguments. */ - return (pIOSubSystem->pfnvfprintf(fp, format, marker)); + return (vfprintf(fp, format, marker)); } DllExport int @@ -939,188 +961,193 @@ win32_printf(const char *format, ...) va_list marker; va_start(marker, format); /* Initialize variable arguments. */ - return (pIOSubSystem->pfnvprintf(format, marker)); + return (vprintf(format, marker)); } DllExport int win32_vfprintf(FILE *fp, const char *format, va_list args) { - return (pIOSubSystem->pfnvfprintf(fp, format, args)); + return (vfprintf(fp, format, args)); } DllExport int win32_vprintf(const char *format, va_list args) { - return (pIOSubSystem->pfnvprintf(format, args)); + return (vprintf(format, args)); } DllExport size_t win32_fread(void *buf, size_t size, size_t count, FILE *fp) { - return pIOSubSystem->pfnfread(buf, size, count, fp); + return fread(buf, size, count, fp); } DllExport size_t win32_fwrite(const void *buf, size_t size, size_t count, FILE *fp) { - return pIOSubSystem->pfnfwrite(buf, size, count, fp); + return fwrite(buf, size, count, fp); } DllExport FILE * win32_fopen(const char *filename, const char *mode) { if (stricmp(filename, "/dev/null")==0) - return pIOSubSystem->pfnfopen("NUL", mode); - return pIOSubSystem->pfnfopen(filename, mode); + return fopen("NUL", mode); + return fopen(filename, mode); } +#ifndef USE_SOCKETS_AS_HANDLES +#undef fdopen +#define fdopen my_fdopen +#endif + DllExport FILE * win32_fdopen( int handle, const char *mode) { - return pIOSubSystem->pfnfdopen(handle, mode); + return fdopen(handle, (char *) mode); } DllExport FILE * win32_freopen( const char *path, const char *mode, FILE *stream) { if (stricmp(path, "/dev/null")==0) - return pIOSubSystem->pfnfreopen("NUL", mode, stream); - return pIOSubSystem->pfnfreopen(path, mode, stream); + return freopen("NUL", mode, stream); + return freopen(path, mode, stream); } DllExport int win32_fclose(FILE *pf) { - return pIOSubSystem->pfnfclose(pf); + return my_fclose(pf); /* defined in win32sck.c */ } DllExport int win32_fputs(const char *s,FILE *pf) { - return pIOSubSystem->pfnfputs(s, pf); + return fputs(s, pf); } DllExport int win32_fputc(int c,FILE *pf) { - return pIOSubSystem->pfnfputc(c,pf); + return fputc(c,pf); } DllExport int win32_ungetc(int c,FILE *pf) { - return pIOSubSystem->pfnungetc(c,pf); + return ungetc(c,pf); } DllExport int win32_getc(FILE *pf) { - return pIOSubSystem->pfngetc(pf); + return getc(pf); } DllExport int win32_fileno(FILE *pf) { - return pIOSubSystem->pfnfileno(pf); + return fileno(pf); } DllExport void win32_clearerr(FILE *pf) { - pIOSubSystem->pfnclearerr(pf); + clearerr(pf); return; } DllExport int win32_fflush(FILE *pf) { - return pIOSubSystem->pfnfflush(pf); + return fflush(pf); } DllExport long win32_ftell(FILE *pf) { - return pIOSubSystem->pfnftell(pf); + return ftell(pf); } DllExport int win32_fseek(FILE *pf,long offset,int origin) { - return pIOSubSystem->pfnfseek(pf, offset, origin); + return fseek(pf, offset, origin); } DllExport int win32_fgetpos(FILE *pf,fpos_t *p) { - return pIOSubSystem->pfnfgetpos(pf, p); + return fgetpos(pf, p); } DllExport int win32_fsetpos(FILE *pf,const fpos_t *p) { - return pIOSubSystem->pfnfsetpos(pf, p); + return fsetpos(pf, p); } DllExport void win32_rewind(FILE *pf) { - pIOSubSystem->pfnrewind(pf); + rewind(pf); return; } DllExport FILE* win32_tmpfile(void) { - return pIOSubSystem->pfntmpfile(); + return tmpfile(); } DllExport void win32_abort(void) { - pIOSubSystem->pfnabort(); + abort(); return; } DllExport int win32_fstat(int fd,struct stat *bufptr) { - return pIOSubSystem->pfnfstat(fd,bufptr); + return fstat(fd,bufptr); } DllExport int win32_pipe(int *pfd, unsigned int size, int mode) { - return pIOSubSystem->pfnpipe(pfd, size, mode); + return _pipe(pfd, size, mode); } DllExport FILE* win32_popen(const char *command, const char *mode) { - return pIOSubSystem->pfnpopen(command, mode); + return _popen(command, mode); } DllExport int win32_pclose(FILE *pf) { - return pIOSubSystem->pfnpclose(pf); + return _pclose(pf); } DllExport int win32_setmode(int fd, int mode) { - return pIOSubSystem->pfnsetmode(fd, mode); + return setmode(fd, mode); } DllExport long win32_lseek(int fd, long offset, int origin) { - return pIOSubSystem->pfnlseek(fd, offset, origin); + return lseek(fd, offset, origin); } DllExport long win32_tell(int fd) { - return pIOSubSystem->pfntell(fd); + return tell(fd); } DllExport int @@ -1134,102 +1161,268 @@ win32_open(const char *path, int flag, ...) va_end(ap); if (stricmp(path, "/dev/null")==0) - return pIOSubSystem->pfnopen("NUL", flag, pmode); - return pIOSubSystem->pfnopen(path,flag,pmode); + return open("NUL", flag, pmode); + return open(path,flag,pmode); } DllExport int win32_close(int fd) { - return pIOSubSystem->pfnclose(fd); + return close(fd); } DllExport int win32_eof(int fd) { - return pIOSubSystem->pfneof(fd); + return eof(fd); } DllExport int win32_dup(int fd) { - return pIOSubSystem->pfndup(fd); + return dup(fd); } DllExport int win32_dup2(int fd1,int fd2) { - return pIOSubSystem->pfndup2(fd1,fd2); + return dup2(fd1,fd2); } DllExport int win32_read(int fd, void *buf, unsigned int cnt) { - return pIOSubSystem->pfnread(fd, buf, cnt); + return read(fd, buf, cnt); } DllExport int win32_write(int fd, const void *buf, unsigned int cnt) { - return pIOSubSystem->pfnwrite(fd, buf, cnt); + return write(fd, buf, cnt); } DllExport int win32_mkdir(const char *dir, int mode) { - return pIOSubSystem->pfnmkdir(dir); /* just ignore mode */ + return mkdir(dir); /* just ignore mode */ } DllExport int win32_rmdir(const char *dir) { - return pIOSubSystem->pfnrmdir(dir); + return rmdir(dir); } DllExport int win32_chdir(const char *dir) { - return pIOSubSystem->pfnchdir(dir); + return chdir(dir); } DllExport int win32_spawnvp(int mode, const char *cmdname, const char *const *argv) { - return pIOSubSystem->pfnspawnvp(mode, cmdname, argv); + return spawnvp(mode, cmdname, (char * const *) argv); } DllExport int win32_execvp(const char *cmdname, const char *const *argv) { - return pIOSubSystem->pfnexecvp(cmdname, argv); + return execvp(cmdname, (char *const *)argv); } -int -stolen_open_osfhandle(long handle, int flags) +DllExport void +win32_perror(const char *str) { - return pIOSubSystem->pfn_open_osfhandle(handle, flags); + perror(str); } -long -stolen_get_osfhandle(int fd) +DllExport void +win32_setbuf(FILE *pf, char *buf) { - return pIOSubSystem->pfn_get_osfhandle(fd); + setbuf(pf, buf); } -/* - * Extras. - */ +DllExport int +win32_setvbuf(FILE *pf, char *buf, int type, size_t size) +{ + return setvbuf(pf, buf, type, size); +} DllExport int -win32_flock(int fd, int oper) +win32_flushall(void) { - if (!IsWinNT()) { - croak("flock() unimplemented on this platform"); - return -1; + return flushall(); +} + +DllExport int +win32_fcloseall(void) +{ + return fcloseall(); +} + +DllExport char* +win32_fgets(char *s, int n, FILE *pf) +{ + return fgets(s, n, pf); +} + +DllExport char* +win32_gets(char *s) +{ + return gets(s); +} + +DllExport int +win32_fgetc(FILE *pf) +{ + return fgetc(pf); +} + +DllExport int +win32_putc(int c, FILE *pf) +{ + return putc(c,pf); +} + +DllExport int +win32_puts(const char *s) +{ + return puts(s); +} + +DllExport int +win32_getchar(void) +{ + return getchar(); +} + +DllExport int +win32_putchar(int c) +{ + return putchar(c); +} + +#ifdef MYMALLOC + +#ifndef USE_PERL_SBRK + +static char *committed = NULL; +static char *base = NULL; +static char *reserved = NULL; +static char *brk = NULL; +static DWORD pagesize = 0; +static DWORD allocsize = 0; + +void * +sbrk(int need) +{ + void *result; + if (!pagesize) + {SYSTEM_INFO info; + GetSystemInfo(&info); + /* Pretend page size is larger so we don't perpetually + * call the OS to commit just one page ... + */ + pagesize = info.dwPageSize << 3; + allocsize = info.dwAllocationGranularity; + } + /* This scheme fails eventually if request for contiguous + * block is denied so reserve big blocks - this is only + * address space not memory ... + */ + if (brk+need >= reserved) + { + DWORD size = 64*1024*1024; + char *addr; + if (committed && reserved && committed < reserved) + { + /* Commit last of previous chunk cannot span allocations */ + addr = (char *) VirtualAlloc(committed,reserved-committed,MEM_COMMIT,PAGE_READWRITE); + if (addr) + committed = reserved; } - return pIOSubSystem->pfnflock(fd, oper); + /* Reserve some (more) space + * Note this is a little sneaky, 1st call passes NULL as reserved + * so lets system choose where we start, subsequent calls pass + * the old end address so ask for a contiguous block + */ + addr = (char *) VirtualAlloc(reserved,size,MEM_RESERVE,PAGE_NOACCESS); + if (addr) + { + reserved = addr+size; + if (!base) + base = addr; + if (!committed) + committed = base; + if (!brk) + brk = committed; + } + else + { + return (void *) -1; + } + } + result = brk; + brk += need; + if (brk > committed) + { + DWORD size = ((brk-committed + pagesize -1)/pagesize) * pagesize; + char *addr = (char *) VirtualAlloc(committed,size,MEM_COMMIT,PAGE_READWRITE); + if (addr) + { + committed += size; + } + else + return (void *) -1; + } + return result; } +#endif +#endif + +DllExport void* +win32_malloc(size_t size) +{ + return malloc(size); +} + +DllExport void* +win32_calloc(size_t numitems, size_t size) +{ + return calloc(numitems,size); +} + +DllExport void* +win32_realloc(void *block, size_t size) +{ + return realloc(block,size); +} + +DllExport void +win32_free(void *block) +{ + free(block); +} + + +int +win32_open_osfhandle(long handle, int flags) +{ + return _open_osfhandle(handle, flags); +} + +long +win32_get_osfhandle(int fd) +{ + return _get_osfhandle(fd); +} + +/* + * Extras. + */ + static XS(w32_GetCwd) { @@ -1458,6 +1651,7 @@ XS(w32_GetShortPathName) { dXSARGS; SV *shortpath; + DWORD len; if(items != 1) croak("usage: Win32::GetShortPathName($longPathName)"); @@ -1465,15 +1659,22 @@ XS(w32_GetShortPathName) shortpath = sv_mortalcopy(ST(0)); SvUPGRADE(shortpath, SVt_PV); /* src == target is allowed */ - if (GetShortPathName(SvPVX(shortpath), SvPVX(shortpath), SvCUR(shortpath))) + do { + len = GetShortPathName(SvPVX(shortpath), + SvPVX(shortpath), + SvLEN(shortpath)); + } while (len >= SvLEN(shortpath) && sv_grow(shortpath,len+1)); + if (len) { + SvCUR_set(shortpath,len); ST(0) = shortpath; + } else ST(0) = &sv_undef; XSRETURN(1); } void -init_os_extras() +Perl_init_os_extras() { char *file = __FILE__; dXSUB_SYS; @@ -1519,5 +1720,38 @@ Perl_win32_init(int *argcp, char ***argvp) * want to be at the vendor's whim on the default, we set * it explicitly here. */ +#if !defined(_ALPHA_) _control87(MCW_EM, MCW_EM); +#endif +} + +#ifdef USE_BINMODE_SCRIPTS + +void +win32_strip_return(SV *sv) +{ + char *s = SvPVX(sv); + char *e = s+SvCUR(sv); + char *d = s; + while (s < e) + { + if (*s == '\r' && s[1] == '\n') + { + *d++ = '\n'; + s += 2; + } + else + { + *d++ = *s++; + } + } + SvCUR_set(sv,d-SvPVX(sv)); } + +#endif + + + + + +