From: Benjamin Stuhl Date: Mon, 13 Nov 2000 15:08:08 +0000 (-0800) Subject: Get PerlIO building on Win32 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e601c439adce167078ac7b49550c0418ace86f94;p=p5sagit%2Fp5-mst-13.2.git Get PerlIO building on Win32 Message-ID: <20001113230808.18659.qmail@web6305.mail.yahoo.com> p4raw-id: //depot/perl@7679 --- diff --git a/MANIFEST b/MANIFEST index 375d55d..3436022 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1723,6 +1723,7 @@ warnings.h The warning numbers warnings.pl Program to write warnings.h and lib/warnings.pm win32/Makefile Win32 makefile for NMAKE (Visual C++ build) win32/bin/exetype.pl Set executable type to CONSOLE or WINDOWS +win32/bin/mdelete.bat multifile delete win32/bin/perlglob.pl Win32 globbing win32/bin/pl2bat.pl wrap perl scripts into batch files win32/bin/runperl.pl run perl script via batch file namesake diff --git a/ext/SDBM_File/Makefile.PL b/ext/SDBM_File/Makefile.PL index a1debb9..bff3e7b 100644 --- a/ext/SDBM_File/Makefile.PL +++ b/ext/SDBM_File/Makefile.PL @@ -1,4 +1,5 @@ use ExtUtils::MakeMaker; +use Config; # The existence of the ./sdbm/Makefile.PL file causes MakeMaker # to automatically include Makefile code for the targets @@ -21,18 +22,26 @@ WriteMakefile( sub MY::postamble { if ($^O =~ /MSWin32/ && Win32::IsWin95()) { - # XXX: dmake-specific, like rest of Win95 port - return - ' + if ($Config{'make'} =~ /dmake/i) { + # dmake-specific + return <) { if ($PLATFORM eq 'win32') { foreach my $symbol (qw( + setuid + setgid boot_DynaLoader Perl_init_os_extras Perl_thread_create @@ -579,35 +582,6 @@ if ($PLATFORM eq 'win32') { RunPerl win32_errno win32_environ - win32_stdin - win32_stdout - win32_stderr - win32_ferror - win32_feof - win32_strerror - win32_fprintf - win32_printf - win32_vfprintf - win32_vprintf - win32_fread - win32_fwrite - win32_fopen - win32_fdopen - win32_freopen - win32_fclose - win32_fputs - win32_fputc - win32_ungetc - win32_getc - win32_fileno - win32_clearerr - win32_fflush - win32_ftell - win32_fseek - win32_fgetpos - win32_fsetpos - win32_rewind - win32_tmpfile win32_abort win32_fstat win32_stat @@ -678,17 +652,6 @@ if ($PLATFORM eq 'win32') { win32_getenv win32_putenv win32_perror - win32_setbuf - win32_setvbuf - win32_flushall - win32_fcloseall - win32_fgets - win32_gets - win32_fgetc - win32_putc - win32_puts - win32_getchar - win32_putchar win32_malloc win32_calloc win32_realloc @@ -720,6 +683,47 @@ if ($PLATFORM eq 'win32') { win32_getpid win32_crypt win32_dynaload + + win32_stdin + win32_stdout + win32_stderr + win32_ferror + win32_feof + win32_strerror + win32_fprintf + win32_printf + win32_vfprintf + win32_vprintf + win32_fread + win32_fwrite + win32_fopen + win32_fdopen + win32_freopen + win32_fclose + win32_fputs + win32_fputc + win32_ungetc + win32_getc + win32_fileno + win32_clearerr + win32_fflush + win32_ftell + win32_fseek + win32_fgetpos + win32_fsetpos + win32_rewind + win32_tmpfile + win32_setbuf + win32_setvbuf + win32_flushall + win32_fcloseall + win32_fgets + win32_gets + win32_fgetc + win32_putc + win32_puts + win32_getchar + win32_putchar )) { try_symbol($symbol); diff --git a/perlio.c b/perlio.c index 8d54f77..e15fc5c 100644 --- a/perlio.c +++ b/perlio.c @@ -107,9 +107,9 @@ PerlIO_debug(char *fmt,...) static int dbg = 0; if (!dbg) { - char *s = getenv("PERLIO_DEBUG"); + char *s = PerlEnv_getenv("PERLIO_DEBUG"); if (s && *s) - dbg = open(s,O_WRONLY|O_CREAT|O_APPEND,0666); + dbg = PerlLIO_open3(s,O_WRONLY|O_CREAT|O_APPEND,0666); else dbg = -1; } @@ -128,7 +128,7 @@ PerlIO_debug(char *fmt,...) Perl_sv_vcatpvf(aTHX_ sv, fmt, &ap); s = SvPV(sv,len); - write(dbg,s,len); + PerlLIO_write(dbg,s,len); va_end(ap); SvREFCNT_dec(sv); } @@ -354,7 +354,7 @@ PerlIO_default_layer(I32 n) int len; if (!PerlIO_layer_hv) { - char *s = getenv("PERLIO"); + char *s = PerlEnv_getenv("PERLIO"); newXS("perlio::import",XS_perlio_import,__FILE__); newXS("perlio::unimport",XS_perlio_unimport,__FILE__); PerlIO_layer_hv = get_hv("perlio::layers",GV_ADD|GV_ADDMULTI); @@ -370,13 +370,13 @@ PerlIO_default_layer(I32 n) { while (*s) { - while (*s && isspace((unsigned char)*s)) + while (*s && isSPACE((unsigned char)*s)) s++; if (*s) { char *e = s; SV *layer; - while (*e && !isspace((unsigned char)*e)) + while (*e && !isSPACE((unsigned char)*e)) e++; layer = PerlIO_find_layer(s,e-s); if (layer) @@ -902,7 +902,7 @@ PerlIOUnix_open(PerlIO_funcs *self, const char *path,const char *mode) int oflags = PerlIOUnix_oflags(mode); if (oflags != -1) { - int fd = open(path,oflags,0666); + int fd = PerlLIO_open3(path,oflags,0666); if (fd >= 0) { PerlIOUnix *s = PerlIOSelf(PerlIO_push(f = PerlIO_allocate(),self,mode),PerlIOUnix); @@ -923,7 +923,7 @@ PerlIOUnix_reopen(const char *path, const char *mode, PerlIO *f) (*PerlIOBase(f)->tab->Close)(f); if (oflags != -1) { - int fd = open(path,oflags,0666); + int fd = PerlLIO_open3(path,oflags,0666); if (fd >= 0) { s->fd = fd; @@ -943,7 +943,7 @@ PerlIOUnix_read(PerlIO *f, void *vbuf, Size_t count) return 0; while (1) { - SSize_t len = read(fd,vbuf,count); + SSize_t len = PerlLIO_read(fd,vbuf,count); if (len >= 0 || errno != EINTR) { if (len < 0) @@ -961,7 +961,7 @@ PerlIOUnix_write(PerlIO *f, const void *vbuf, Size_t count) int fd = PerlIOSelf(f,PerlIOUnix)->fd; while (1) { - SSize_t len = write(fd,vbuf,count); + SSize_t len = PerlLIO_write(fd,vbuf,count); if (len >= 0 || errno != EINTR) { if (len < 0) @@ -974,7 +974,7 @@ PerlIOUnix_write(PerlIO *f, const void *vbuf, Size_t count) IV PerlIOUnix_seek(PerlIO *f, Off_t offset, int whence) { - Off_t new = lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence); + Off_t new = PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,offset,whence); PerlIOBase(f)->flags &= ~PERLIO_F_EOF; return (new == (Off_t) -1) ? -1 : 0; } @@ -982,7 +982,7 @@ PerlIOUnix_seek(PerlIO *f, Off_t offset, int whence) Off_t PerlIOUnix_tell(PerlIO *f) { - return lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR); + return PerlLIO_lseek(PerlIOSelf(f,PerlIOUnix)->fd,0,SEEK_CUR); } IV @@ -990,7 +990,7 @@ PerlIOUnix_close(PerlIO *f) { int fd = PerlIOSelf(f,PerlIOUnix)->fd; int code = 0; - while (close(fd) != 0) + while (PerlLIO_close(fd) != 0) { if (errno != EINTR) { @@ -2269,7 +2269,7 @@ PerlIO_tmpfile(void) { PerlIOBase(f)->flags |= PERLIO_F_TEMP; } - unlink(SvPVX(sv)); + PerlLIO_unlink(SvPVX(sv)); SvREFCNT_dec(sv); } return f; diff --git a/win32/Makefile b/win32/Makefile index af11990..121f8c8 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -63,6 +63,12 @@ INST_ARCH = \$(ARCHNAME) #USE_IMP_SYS = define # +# uncomment to enable the experimental PerlIO I/O subsystem. +# This is currently incompatible with USE_MULTI, USE_ITHREADS, +# and USE_IMP_SYS +#USE_PERLIO = define + +# # WARNING! This option is deprecated and will eventually go away (enable # USE_ITHREADS instead). # @@ -273,10 +279,18 @@ ARCHNAME = MSWin32-$(PROCESSOR_ARCHITECTURE)-thread !IF "$(USE_MULTI)" == "define" ARCHNAME = MSWin32-$(PROCESSOR_ARCHITECTURE)-multi !ELSE +!IF "$(USE_PERLIO)" == "define" +ARCHNAME = MSWin32-$(PROCESSOR_ARCHITECTURE)-perlio +!ELSE ARCHNAME = MSWin32-$(PROCESSOR_ARCHITECTURE) !ENDIF !ENDIF !ENDIF +!ENDIF + +!IF "$(USE_PERLIO)" == "define" +BUILDOPT = $(BUILDOPT) -DUSE_PERLIO +!ENDIF !IF "$(USE_ITHREADS)" == "define" ARCHNAME = $(ARCHNAME)-thread @@ -465,6 +479,8 @@ RCOPY = xcopy /f /r /i /e /d NOOP = @echo NULL = +DEL = bin\mdelete.bat + # # filenames given to xsubpp must have forward slashes (since it puts # full pathnames in #line strings) @@ -691,8 +707,8 @@ CFG_VARS = \ "INST_ARCH=$(INST_ARCH)" \ "archname=$(ARCHNAME)" \ "cc=$(CC)" \ - "ccflags=$(OPTIMIZE:"=\") $(DEFINES) $(BUILDOPT)" \ - "cf_email=$(EMAIL)" \ + "ccflags=-nologo -Gf -W3 $(OPTIMIZE:"=\") $(DEFINES) $(BUILDOPT)" \ + "cf_email=$(EMAIL)" \ "d_crypt=$(D_CRYPT)" \ "d_mymalloc=$(PERL_MALLOC)" \ "libs=$(LIBFILES)" \ @@ -753,14 +769,16 @@ regen_config_h: rename config.h $(CFGH_TMPL) $(CONFIGPM) : $(MINIPERL) ..\config.sh config_h.PL ..\minimod.pl - cd .. && miniperl configpm + cd .. + miniperl configpm + cd win32 if exist lib\* $(RCOPY) lib\*.* ..\lib\$(NULL) $(XCOPY) ..\*.h $(COREDIR)\*.* $(XCOPY) *.h $(COREDIR)\*.* $(XCOPY) ..\ext\re\re.pm $(LIBDIR)\*.* $(RCOPY) include $(COREDIR)\*.* - $(MINIPERL) -I..\lib config_h.PL "INST_VER=$(INST_VER)" \ - || $(MAKE) /$(MAKEFLAGS) $(CONFIGPM) + -$(MINIPERL) -I..\lib config_h.PL "INST_VER=$(INST_VER)" + if errorlevel 1 $(MAKE) /$(MAKEFLAGS) $(CONFIGPM) $(MINIPERL) : $(MINIDIR) $(MINI_OBJ) $(LINK32) -subsystem:console -out:$@ @<< @@ -803,7 +821,9 @@ $(PERLDLL): perldll.def $(PERLDLL_OBJ) $(PERLDLL_RES) $(XCOPY) $(PERLIMPLIB) $(COREDIR) $(MINIMOD) : $(MINIPERL) ..\minimod.pl - cd .. && miniperl minimod.pl > lib\ExtUtils\Miniperl.pm + cd .. + miniperl minimod.pl > lib\ExtUtils\Miniperl.pm + cd win32 ..\x2p\a2p$(o) : ..\x2p\a2p.c $(CC) -I..\x2p $(CFLAGS) $(OBJOUT_FLAG)$@ -c ..\x2p\a2p.c @@ -1004,10 +1024,14 @@ distclean: clean -del /f $(LIBDIR)\Devel\Peek.pm $(LIBDIR)\Devel\DProf.pm -del /f $(LIBDIR)\File\Glob.pm -del /f $(LIBDIR)\Storable.pm - -if exist $(LIBDIR)\IO rmdir /s /q $(LIBDIR)\IO || rmdir /s $(LIBDIR)\IO - -if exist $(LIBDIR)\Thread rmdir /s /q $(LIBDIR)\Thread || rmdir /s $(LIBDIR)\Thread - -if exist $(LIBDIR)\B rmdir /s /q $(LIBDIR)\B || rmdir /s $(LIBDIR)\B - -if exist $(LIBDIR)\Data rmdir /s /q $(LIBDIR)\Data || rmdir /s $(LIBDIR)\Data + -if exist $(LIBDIR)\IO rmdir /s /q $(LIBDIR)\IO + -rmdir /s $(LIBDIR)\IO + -if exist $(LIBDIR)\Thread rmdir /s /q $(LIBDIR)\Thread + -rmdir /s $(LIBDIR)\Thread + -if exist $(LIBDIR)\B rmdir /s /q $(LIBDIR)\B + -rmdir /s $(LIBDIR)\B + -if exist $(LIBDIR)\Data rmdir /s /q $(LIBDIR)\Data + -rmdir /s $(LIBDIR)\Data -del /f $(PODDIR)\*.html -del /f $(PODDIR)\*.bat cd ..\utils @@ -1024,8 +1048,10 @@ distclean: clean cd $(EXTDIR) -del /s *.lib *.def *.map *.pdb *.bs Makefile *$(o) pm_to_blib cd ..\win32 - -if exist $(AUTODIR) rmdir /s /q $(AUTODIR) || rmdir /s $(AUTODIR) - -if exist $(COREDIR) rmdir /s /q $(COREDIR) || rmdir /s $(COREDIR) + -if exist $(AUTODIR) rmdir /s /q $(AUTODIR) + -rmdir /s $(AUTODIR) + -if exist $(COREDIR) rmdir /s /q $(COREDIR) + -rmdir /s $(COREDIR) install : all installbare installhtml @@ -1082,26 +1108,26 @@ test-wide-notty : test-prep cd ..\win32 clean : - -@erase miniperlmain$(o) - -@erase $(MINIPERL) - -@erase perlglob$(o) - -@erase perlmain$(o) - -@erase config.w32 - -@erase /f config.h - -@erase $(GLOBEXE) - -@erase $(PERLEXE) - -@erase $(WPERLEXE) - -@erase $(PERLDLL) - -@erase $(CORE_OBJ) - -if exist $(MINIDIR) rmdir /s /q $(MINIDIR) || rmdir /s $(MINIDIR) - -@erase $(WIN32_OBJ) - -@erase $(DLL_OBJ) - -@erase $(X2P_OBJ) - -@erase ..\*$(o) ..\*.lib ..\*.exp *$(o) *.lib *.exp *.res - -@erase ..\t\*.exe ..\t\*.dll ..\t\*.bat - -@erase ..\x2p\*.exe ..\x2p\*.bat - -@erase *.ilk - -@erase *.pdb + -@$(DEL) miniperlmain$(o) + -@$(DEL) $(MINIPERL) + -@$(DEL) perlglob$(o) + -@$(DEL) perlmain$(o) + -@$(DEL) config.w32 + -@$(DEL) /f config.h + -@$(DEL) $(GLOBEXE) + -@$(DEL) $(PERLEXE) + -@$(DEL) $(WPERLEXE) + -@$(DEL) $(PERLDLL) + -@$(DEL) $(CORE_OBJ) + -if exist $(MINIDIR) deltree /y $(MINIDIR) + -@$(DEL) $(WIN32_OBJ) + -@$(DEL) $(DLL_OBJ) + -@$(DEL) $(X2P_OBJ) + -@$(DEL) ..\*$(o) ..\*.lib ..\*.exp *$(o) *.lib *.exp *.res + -@$(DEL) ..\t\*.exe ..\t\*.dll ..\t\*.bat + -@$(DEL) ..\x2p\*.exe ..\x2p\*.bat + -@$(DEL) *.ilk + -@$(DEL) *.pdb # Handy way to run perlbug -ok without having to install and run the # installed perlbug. We don't re-run the tests here - we trust the user. diff --git a/win32/bin/mdelete.bat b/win32/bin/mdelete.bat new file mode 100644 index 0000000..99b1c3d --- /dev/null +++ b/win32/bin/mdelete.bat @@ -0,0 +1,30 @@ +@echo off +rem ! This is a batch file to delete all the files on its +rem ! command line, to work around command.com's del command's +rem ! braindeadness +rem ! +rem ! -- BKS, 11-11-2000 + +:nextfile +set file=%1 +shift +if "%file%"=="" goto end +del %file% +goto nextfile +:end + +@echo off +rem ! This is a batch file to delete all the files on its +rem ! command line, to work around command.com's del command's +rem ! braindeadness +rem ! +rem ! -- BKS, 11-11-2000 + +:nextfile +set file=%1 +shift +if "%file%"=="" goto end +del %file% +goto nextfile +:end + diff --git a/win32/config.gc b/win32/config.gc index ffb3a7f..171f153 100644 --- a/win32/config.gc +++ b/win32/config.gc @@ -323,7 +323,7 @@ d_statvfs='undef' d_stdio_cnt_lval='define' d_stdio_ptr_lval='define' d_stdio_ptr_lval_sets_cnt='undef' -d_stdio_ptr_lval_nochange_cnt='undef' +d_stdio_ptr_lval_nochange_cnt='define' d_stdio_stream_array='undef' d_stdiobase='define' d_stdstdio='define' diff --git a/win32/config.vc b/win32/config.vc index 042bcc0..6ec27fd 100644 --- a/win32/config.vc +++ b/win32/config.vc @@ -323,7 +323,7 @@ d_statvfs='undef' d_stdio_cnt_lval='define' d_stdio_ptr_lval='define' d_stdio_ptr_lval_sets_cnt='undef' -d_stdio_ptr_lval_nochange_cnt='undef' +d_stdio_ptr_lval_nochange_cnt='define' d_stdio_stream_array='undef' d_stdiobase='define' d_stdstdio='define' diff --git a/win32/win32.c b/win32/win32.c index 2b31878..e4e553c 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -977,6 +977,31 @@ chown(const char *path, uid_t owner, gid_t group) return 0; } +/* + * XXX this needs strengthening (for PerlIO) + * -- BKS, 11-11-200 +*/ +int mkstemp(const char *path) +{ + dTHX; + char buf[MAX_PATH+1]; + int i = 0, fd = -1; + +retry: + if (i++ > 10) { /* give up */ + errno = ENOENT; + return -1; + } + if (!GetTempFileNameA((LPCSTR)path, "plr", 1, buf)) { + errno = ENOENT; + return -1; + } + fd = PerlLIO_open3(buf, O_CREAT|O_RDWR|O_EXCL, 0600); + if (fd == -1) + goto retry; + return fd; +} + static long find_pid(int pid) { @@ -2106,7 +2131,6 @@ win32_str_os_error(void *sv, DWORD dwErr) } } - DllExport int win32_fprintf(FILE *fp, const char *format, ...) { @@ -2341,9 +2365,11 @@ win32_pipe(int *pfd, unsigned int size, int mode) /* * a popen() clone that respects PERL5SHELL + * + * changed to return PerlIO* rather than FILE * by BKS, 11-11-2000 */ -DllExport FILE* +DllExport PerlIO* win32_popen(const char *command, const char *mode) { #ifdef USE_RTL_POPEN @@ -2417,7 +2443,11 @@ win32_popen(const char *command, const char *mode) } /* we have an fd, return a file stream */ - return (win32_fdopen(p[parent], (char *)mode)); +#ifdef USE_PERLIO + return (PerlIO_fdopen(p[parent], (char *)mode)); +#else + return (fdopen(p[parent], (char *)mode)); +#endif cleanup: /* we don't need to check for errors here */ @@ -2437,7 +2467,7 @@ cleanup: */ DllExport int -win32_pclose(FILE *pf) +win32_pclose(PerlIO *pf) { #ifdef USE_RTL_POPEN return _pclose(pf); @@ -2447,7 +2477,7 @@ win32_pclose(FILE *pf) SV *sv; LOCK_FDPID_MUTEX; - sv = *av_fetch(w32_fdpid, win32_fileno(pf), TRUE); + sv = *av_fetch(w32_fdpid, PerlIO_fileno(pf), TRUE); if (SvIOK(sv)) childpid = SvIVX(sv); @@ -2459,7 +2489,11 @@ win32_pclose(FILE *pf) return -1; } - win32_fclose(pf); +#ifdef USE_PERLIO + PerlIO_close(pf); +#else + fclose(pf); +#endif SvIVX(sv) = 0; UNLOCK_FDPID_MUTEX; @@ -2721,10 +2755,13 @@ win32_open(const char *path, int flag, ...) return open(PerlDir_mapA(path), flag, pmode); } +/* close() that understands socket */ +extern int my_close(int); /* in win32sck.c */ + DllExport int win32_close(int fd) { - return close(fd); + return my_close(fd); } DllExport int diff --git a/win32/win32.h b/win32/win32.h index d9ffbfe..808191a 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -302,6 +302,7 @@ extern int kill(int pid, int sig); extern void *sbrk(int need); extern char * getlogin(void); extern int chown(const char *p, uid_t o, gid_t g); +extern int mkstemp(const char *path); #undef Stat #define Stat win32_stat diff --git a/win32/win32sck.c b/win32/win32sck.c index 3b81d8b..4a4131c 100644 --- a/win32/win32sck.c +++ b/win32/win32sck.c @@ -418,6 +418,41 @@ win32_socket(int af, int type, int protocol) return s; } +/* + * close RTL fd while respecting sockets + * added as temporary measure until PerlIO has real + * Win32 native layer + * -- BKS, 11-11-2000 +*/ + +int my_close(int fd) +{ + int osf; + if (!wsock_started) /* No WinSock? */ + return(close(fd)); /* Then not a socket. */ + osf = TO_SOCKET(fd);/* Get it now before it's gone! */ + if (osf != -1) { + int err; + err = closesocket(osf); + if (err == 0) { +#if defined(USE_FIXED_OSFHANDLE) || defined(PERL_MSVCRT_READFIX) + _set_osfhnd(fd, INVALID_HANDLE_VALUE); +#endif + (void)close(fd); /* handle already closed, ignore error */ + return 0; + } + else if (err == SOCKET_ERROR) { + err = WSAGetLastError(); + if (err != WSAENOTSOCK) { + (void)close(fd); + errno = err; + return EOF; + } + } + } + return close(fd); +} + #undef fclose int my_fclose (FILE *pf) @@ -425,14 +460,14 @@ my_fclose (FILE *pf) int osf; if (!wsock_started) /* No WinSock? */ return(fclose(pf)); /* Then not a socket. */ - osf = TO_SOCKET(fileno(pf));/* Get it now before it's gone! */ + osf = TO_SOCKET(win32_fileno(pf));/* Get it now before it's gone! */ if (osf != -1) { int err; win32_fflush(pf); err = closesocket(osf); if (err == 0) { #if defined(USE_FIXED_OSFHANDLE) || defined(PERL_MSVCRT_READFIX) - _set_osfhnd(fileno(pf), INVALID_HANDLE_VALUE); + _set_osfhnd(win32_fileno(pf), INVALID_HANDLE_VALUE); #endif (void)fclose(pf); /* handle already closed, ignore error */ return 0;