Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Unsubscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com Message-ID: <001101bee8f7$8b5bd4d0$283f86a1@empros.com> From: "Geoff Hart" To: Subject: Re: perl problems (using ActiveState's perl from CYGWIN) Date: Tue, 17 Aug 1999 16:29:09 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.00.2014.211 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2014.211 In case anyone is interested in using Activestate's Perl distribution with CYGWIN, I have made a small tool that seems to work. It's a "perl.exe" executable, which translates the command line arguments from Cygwin to Win32, then invokes the perl interpreter *directly* from the Activestate .dll (I didn't want to spawn a subprocess). Of course, this doesn't fix any file name translation *within* the running script, so if you need that, this won't work. For example, if your script accepts file names as input, those paths would need to be Win32 valid. But it handles \ or / just fine. It's not the most efficient, because I couldn't figure out a way to call CYGWIN's "cygwin_conv_to_full_win32_path" from a Windows application - so I end up calling "cygpath". Also, I don't believe signal handling works quite the same for these non-CYGWIN apps. So, Ctrl-C will kill the top level process fine, but spawned processes seem to be somewhat insulated. I don't know of a clean way to deal with this. I would like to put this new perl.exe on an ftp server, if someone is willing to host it. It's 49k big. Here's the source and nmakefile (unfortunately, to build it you'll need to install the Activestate Perl source, and make Dynaloader.c): /* 1) include perlhost.h. This header defines all the OS Interfaces that are used by the PERL_OBJECT. 2) define the host data structure 'CPerlHost' 3) call the CPerlHost member function PerlCreate, which calls perl_alloc and perl_construct 4) call the CPerlHost member function PerlParse 5) call the CPerlHost member function PerlRun 6) when done, call the CPerlHost member function PerlDestroy, which calls perl_destruct and perl_free Including XSUB.h brings in the files that have macros to redefine the perl_* functions, to work with PERL_OBJECT. Note that these macros may cause problems when there are name collisions. A common problem is having a local variable that has the same name as a Perl function. To track down these name collisions compile using '/P' option with VC++ so that you can see what the preprocessor has done. */ #include #include #define NO_XSLOCKS // Bring in the macros that redefine perl_* functions to work with // PERL_OBJECT. // #include /* for Win32 */ #include "win32iop.h" #include #include #include #include #include #include #include // DynaLoader stuff. // char *staticlinkmodules[] = { "DynaLoader", NULL, }; // More DynaLoader stuff. // EXTERN_C void boot_DynaLoader _((CV* cv _CPERLarg)); static void xs_init(CPERLarg) { char *file = __FILE__; dXSUB_SYS; newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); } CPerlObj *pPerl; // The Perl object used by the host. int main (int argc, char **argv, char **env) { struct _stat stbuf; /* {for (char** pp = argv; *pp; pp++) { printf ("%s\n", *pp); }} */ char* name = argv[0]; for (char* pp = argv[0]; *pp; pp++) { if (*pp == '\\' || *pp == '/') name = ++pp; } char cmd[2048] = ""; /* Find the *real* version of this command (argv[0]) */ char path[2048]; strcpy (path, getenv("PATH")); char* path_end = path + strlen (path); {for (char* pp = path; pp < path_end; pp++) { if (*pp == ';') {*pp = 0;} }} char pathext[2048] = ";", *pPATHEXT = getenv("PATHEXT"); strcpy (pathext+1, pPATHEXT ? pPATHEXT : ".EXE;.COM;.BAT"); char* pathext_end = pathext + 1 + strlen (pathext+1); {for (char* ppe = pathext; ppe < pathext_end; ppe++) { if (*ppe == ';') {*ppe = 0;} }} int my_size = -1; {for (char* ppe = pathext; ppe < pathext_end; ppe += strlen (ppe) + 1) { sprintf (cmd, "%s%s", argv[0], ppe); if (!_stat (cmd, &stbuf)) { my_size = stbuf.st_size; break; } }} {for (char* pp = path; pp < path_end; pp += strlen (pp) + 1) { for (char* ppe = pathext; ppe < pathext_end; ppe += strlen (ppe) + 1) { sprintf (cmd, "%s\\%s%s", pp, name, ppe); if (!_stat (cmd, &stbuf)) { if (my_size == -1) { my_size = 0; } else if (stbuf.st_size != my_size) { goto FOUND; } } } }} printf ("Could not find command: %s! Aborting!!\n", name); exit (1); // Now translate command line arguments to native Win32. FOUND: char* cmd_args[256], args_storage[2048], *pas = cmd + strlen(cmd); int iarg = 0; cmd_args[iarg++] = cmd; for (int i = 1; i < argc; i++) { FILE *CYGPATH; char cmd[256]; *pas++ = 0; cmd_args[iarg++] = pas; if (*argv[i] == '-') goto NOT_FILE; {for (char* pc = argv[i]; *pc; pc++) { if (*pc == ' ' || *pc == ';' || *pc == '\'' || *pc == '"') { goto NOT_FILE; } }} sprintf (cmd, "cygpath -w %s 2>nul", argv[i]); if( (CYGPATH = _popen(cmd, "rb" )) == NULL ) exit( 1 ); if ((1 == fscanf (CYGPATH, "%s", pas)) && !_stat (pas, &stbuf)) { pas += strlen(pas); _pclose(CYGPATH); goto NEXT_ARG; } _pclose(CYGPATH); NOT_FILE: strcpy (pas, argv[i]); pas += strlen(pas); NEXT_ARG:; } cmd_args[iarg] = 0; CPerlHost host; // The Perl host host.PerlCreate(); // Create an instance of the Perl Interpreter host.PerlParse(xs_init, argc, cmd_args, NULL); host.PerlRun(); // Run the interpreter. host.PerlDestroy(); // Destroy the interpreter. return 0; } LIBDIR = C:\Perl\lib\CORE SRCDIR = C:\Perl\src LIBS = oldnames.lib kernel32.lib user32.lib winspool.lib advapi32.lib \ shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib \ wsock32.lib version.lib \ $(LIBDIR)\PerlCRT.lib $(LIBDIR)\PerlCore.lib \ $(LIBDIR)\PerlCAPI.lib CCFLAGS = -c -I$(LIBDIR) -Gf -W3 -DWIN32 -D_CONSOLE -DPERL_CORE \ -O2 -MD -DNDEBUG -TP -GX -DPERL_OBJECT -UPERLDLL CCDYNA = $(CCFLAGS) -I$(SRCDIR)\ext\DynaLoader all: cl.exe $(CCFLAGS) -Fo.\perl.obj perl.cpp cl.exe $(CCFLAGS) -Fo.\win32.obj $(SRCDIR)\win32\win32.c cl.exe $(CCFLAGS) -Fo.\win32sck.obj $(SRCDIR)\win32\win32sck.c cl.exe $(CCFLAGS) -Fo.\DynaLoader.obj \ $(SRCDIR)\ext\DynaLoader\DynaLoader.c link.exe -nologo -nodefaultlib -release -machine:x86 $(LIBS) \ -subsystem:console perl.obj win32.obj win32sck.obj \ DynaLoader.obj setargv.obj -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com