Subject: [PATCH] Re: perl winpid?
From: Yitzchak Scott-Thoennes <[email-masked]>
To: Reini Urban <[email-masked]>
Cc: [email-masked], [email-masked], [email-masked]
Date: Tue, 8 Feb 2005 13:46:41 -0800

On Tue, Feb 08, 2005 at 03:48:01PM +0100, Reini Urban wrote:
> Gerrit P. Haase schrieb:
> >Yitzchak Scott-Thoennes wrote:
> >>On Mon, Feb 07, 2005 at 02:17:32PM +0100, Reini Urban wrote:
> >>>Igor Pechtchanski schrieb:
> >>>>On Sun, 6 Feb 2005, Reini Urban wrote:
> >>>>
> >>>>>I feel quite stupid now, but found nothing simple.
> >>>>>How to get the winpid from the current process in cygwin's perl?
> >
> >>>We will check out there where this cygwin specific functionality
> >>>will go to.
> >>>Win32::Process::CygwinToWin32ProcessID() is my suggestion.
> >
> >>I'd rather see them in the Proc:: namespace, and I think it would make
> >>sense to put them in perl's cygwin.c itself, if Gerrit is willing to
> >>release yet another perl-5.8.6.  If this sounds OK, I'll come up with
> >>a patch.
> >
> >I have no problem with another release.  And I agree that such important
> >functions should go inside perl.
> 
> Ok.
> Then we won't have to pollute the Win32::Process namespace with this 
> cygwin-only functionality. And we don't have to wait for the still 
> unmaintained libwin32 upstream.
> 
> README.cygwin, cygwin/cygwin.c:
> =item cygwin32_winpid_to_pid($pid)
> 
> Returns the windows process ID for the given cygwin pid. cygwin-only.
> 
> =item cygwin32_pid_to_winpid($pid)
> 
> Returns the cygwin process ID for the given windows pid. cygwin-only.

How does this look?

--- README.cygwin.orig	2003-08-19 07:37:00.000000000 -0700
+++ README.cygwin	2005-02-08 11:47:03.382880000 -0800
@@ -369,6 +369,8 @@
 
 See comment on fork in L<Miscellaneous> below.
 
+=head1 Specific features of the Cygwin port
+
 =head2 Script Portability on Cygwin
 
 Cygwin does an outstanding job of providing UNIX-like semantics on top of
@@ -470,6 +472,25 @@
 
 =back
 
+=head2 Prebuilt methods:
+
+=over 4
+
+=item C<Cwd::cwd>
+
+Returns current working directory.
+
+=item C<Proc::Cygwin::cygwin32_pid_to_winpid>
+
+Translates a cygwin pid to the corresponding Windows pid (which may or
+may not be the same).
+
+=item C<Proc::Cygwin::cygwin32_winpid_to_pid>
+
+Translates a Windows pid to the corresponding cygwin pid (if any).
+
+=back
+
 =head1 INSTALL PERL ON CYGWIN
 
 This will install Perl, including I<man> pages.
--- perl/cygwin/cygwin.c.orig	2002-03-20 15:02:25.000000000 -0800
+++ perl/cygwin/cygwin.c	2005-02-08 12:37:48.601689600 -0800
@@ -9,6 +9,7 @@
 
 #include <unistd.h>
 #include <process.h>
+#include <sys/cygwin.h>
 
 /*
  * pp_system() implemented via spawn()
@@ -155,6 +156,39 @@
     XSRETURN_UNDEF;
 }
 
+static
+XS(XS_Proc_Cygwin_cygwin32_pid_to_winpid)
+{
+    dXSARGS;
+    if (items != 1)
+        Perl_croak(aTHX_ "Usage: Proc::Cygwin::cygwin32_pid_to_winpid(pid)");
+    pid_t pid = (pid_t)SvIV(ST(0));
+    pid_t RETVAL;
+    dXSTARG;
+    if ((RETVAL = cygwin_internal(CW_CYGWIN_PID_TO_WINPID, pid)) > 0) {
+	XSprePUSH; PUSHi((IV)RETVAL);
+        XSRETURN(1);
+    }
+    XSRETURN_UNDEF;
+}
+
+static
+XS(XS_Proc_Cygwin_cygwin32_winpid_to_pid)
+{
+    dXSARGS;
+    if (items != 1)
+        Perl_croak(aTHX_ "Usage: Proc::Cygwin::cygwin32_winpid_to_pid(pid)");
+    pid_t pid = (pid_t)SvIV(ST(0));
+    pid_t RETVAL;
+    dXSTARG;
+    if ((RETVAL = cygwin32_winpid_to_pid(pid)) > 0) {
+        XSprePUSH; PUSHi((IV)RETVAL);
+        XSRETURN(1);
+    }
+    XSRETURN_UNDEF;
+}
+
+
 void
 init_os_extras(void)
 {
@@ -162,4 +196,8 @@
     dTHX;
 
     newXS("Cwd::cwd", Cygwin_cwd, file);
+    newXS("Proc::Cygwin::cygwin32_winpid_to_pid",
+          XS_Proc_Cygwin_cygwin32_winpid_to_pid, file);
+    newXS("Proc::Cygwin::cygwin32_pid_to_winpid",
+          XS_Proc_Cygwin_cygwin32_pid_to_winpid, file);
 }
--- perl/MANIFEST.orig	2005-02-01 04:17:14.000000000 -0800
+++ perl/MANIFEST	2005-02-08 13:35:30.299366400 -0800
@@ -2493,6 +2493,7 @@
 t/lib/1_compile.t		See if the various libraries and extensions compile
 t/lib/commonsense.t		See if configuration meets basic needs
 t/lib/compmod.pl		Helper for 1_compile.t
+t/lib/cygwin.t			Builtin cygwin function tests
 t/lib/Devel/switchd.pm		Module for t/run/switchd.t
 t/lib/Dev/Null.pm		Module for testing Test::Harness
 t/lib/dprof/test1_t		Perl code profiler tests
--- perlpatch/t/lib/cygwin.t	1970-01-01 00:00:00.000000000 +0000
+++ perl/t/lib/cygwin.t	2005-02-08 21:33:53.319916800 +0000
@@ -0,0 +1,33 @@
+#!perl
+
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = ('../lib');
+    unless ($^O eq "cygwin") {
+	print "1..0 # skipped: cygwin specific test\n";
+	exit 0;
+    }
+}
+
+use Test::More tests => 4;
+
+is(Proc::Cygwin::cygwin32_winpid_to_pid(
+       Proc::Cygwin::cygwin32_pid_to_winpid($$)),
+   $$, "perl pid translates to itself");
+
+my $parent = getppid;
+SKIP: {
+    skip "test not run from cygwin process", 1 if $parent <= 1;
+    is(Proc::Cygwin::cygwin32_winpid_to_pid(
+           Proc::Cygwin::cygwin32_pid_to_winpid($parent)),
+       $parent, "parent pid translates to itself");
+}
+
+my $catpid = open my $cat, "|cat" or die "Couldn't cat: $!";
+open my $ps, "ps|" or die "Couldn't do ps: $!";
+my ($catwinpid) = map /^.\s+$catpid\s+\d+\s+\d+\s+(\d+)/, <$ps>;
+close($ps);
+
+is(Proc::Cygwin::cygwin32_winpid_to_pid($catwinpid), $catpid, "winpid to pid");
+is(Proc::Cygwin::cygwin32_pid_to_winpid($catpid), $catwinpid, "pid to winpid");
+close($cat);

> Or as seperate Proc::Cygwin package, which could be maintained at CPAN 
> and go to vendor_perl within gerrit's perl package?
> 
>   Proc::Cygwin::Win32ProcessID($pid)
>   Proc::Cygwin::CygwinProcessID($winpid)

I'd rather not create a separate module for this.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/