Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Pedro Alves" <pedro_alves@portugalmail.pt>
To: gdb-patches@sourceware.org
Subject: Re: [RFC] gdb/testsuite/gdb.base/fileio.exp patch for cygwin
Date: Thu, 06 Dec 2007 04:25:00 -0000	[thread overview]
Message-ID: <4053daab0712051942q2a421ac7mcc04224d673c0d1d@mail.gmail.com> (raw)
In-Reply-To: <4053daab0712051706k528ad3d1m9fb692bdaba9560a@mail.gmail.com>

Pedro Alves wrote:
> Daniel Jacobowitz wrote:
>
> > I might be mistaken, but I don't think there's any way to figure out
> > the original identity of the pipe.  Handles aren't globally unique,
> > are they?
> >
>
> Yeah, I keep thinking CE, where they *are* global.
>
> There may be other ways to identify the pipes, like using
> named pipes for the ttys if possible -- but I don't know if
> it's possible to get a pipe name from a pipe handle.  If
> there's a way to know if two handles point to the same
> object it should work too, but I don't think that's possible either...
>

Just for completeness:

Been googling a bit, and, as the Cygwin folks sure know,
under NT it is possible to get the internal names of objects,
and NT assigns unique names to pipes.

This is from the test files pasted at the bottom:

>./parent.exe
par: Filename from handle (STD_INPUT_HANDLE) returned :
\Device\NamedPipe\Win32Pipes.00000c70.00000002
par: Filename from handle (STD_OUTPUT_HANDLE) returned :
\Device\NamedPipe\Win32Pipes.00000c70.00000003
par: Filename from handle (STD_ERROR_HANDLE) returned :
\Device\NamedPipe\Win32Pipes.00000c70.00000003
par: Filename from handle (hReadPipe) returned :
\Device\NamedPipe\Win32Pipes.00000290.00000002
par: Filename from handle (hWritePipe) returned :
\Device\NamedPipe\Win32Pipes.00000290.00000002
par: Filename from handle (h) returned :
\Device\NamedPipe\testpipe
par: Filename from handle (duph) returned :
\Device\NamedPipe\Win32Pipes.00000290.00000002
child: Filename from handle (STD_INPUT_HANDLE) returned :
\Device\NamedPipe\Win32Pipes.00000c70.00000002
child: Filename from handle (STD_OUTPUT_HANDLE) returned :
\Device\NamedPipe\Win32Pipes.00000c70.00000003
child: Filename from handle (STD_ERROR_HANDLE) returned :
\Device\NamedPipe\Win32Pipes.00000c70.00000003

Notice that the STD_{INPUT|OUTPUT|ERROR}_HANDLEs are the
same pipes.

Since the next big Cygwin release will be NT only, perhaps this could
be used to map pipes to ttys.

Disclosure: I haven't really looked into Cygwin's sources to see
what it would take.  It may be saying something plain dumb.

-- 
Pedro Alves


parent.c:

#include <stdio.h>
#include <windows.h>

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;

#define STATUS_SUCCESS 0
typedef ULONG NTSTATUS;

typedef enum _OBJECT_INFO_CLASS {
    ObjectBasicInfo,
    ObjectNameInfo,
    ObjectTypeInfo,
    ObjectAllTypesInfo,
    ObjectProtectionInfo
} OBJECT_INFO_CLASS;

typedef NTSTATUS (NTAPI * NTQUERYOBJECT)(HANDLE, OBJECT_INFO_CLASS,
					 PVOID, ULONG, PULONG);

typedef struct ObjectNameInfo_t {
    UNICODE_STRING ObjectName;
    WCHAR ObjectNameBuffer[1];
} OBJECT_NAME_INFO, *POBJECT_NAME_INFO;

static BOOL
print_object_name (const char *var, HANDLE h)
{
  HMODULE ntdll = GetModuleHandle ("ntdll.dll");
  NTQUERYOBJECT NtQueryObject
    = (NTQUERYOBJECT) GetProcAddress (ntdll, "NtQueryObject");

  char buf1[1024];
  char buf2[1024];

  POBJECT_NAME_INFO pObjectNameInfo = (POBJECT_NAME_INFO) buf1;

  int rc = NtQueryObject (h, ObjectNameInfo, buf1, sizeof (buf1), NULL);
  if (rc != STATUS_SUCCESS)
    {
      printf ("NtQueryObject failed with rc = 0x%x\n",  rc);
      return FALSE;
    }

  wcstombs (buf2, pObjectNameInfo->ObjectName.Buffer, 1024);
  printf ("par: Filename from handle (%s) returned :\n%s\n", var, buf2);
  return 0;
}

int
main (int argc, char **argv)
{
  print_object_name ("STD_INPUT_HANDLE", GetStdHandle (STD_INPUT_HANDLE));
  print_object_name ("STD_OUTPUT_HANDLE", GetStdHandle (STD_OUTPUT_HANDLE));
  print_object_name ("STD_ERROR_HANDLE", GetStdHandle (STD_ERROR_HANDLE));

  DWORD bufferSize = 1024;

  HANDLE h = CreateNamedPipe ("\\\\.\\pipe\\testpipe",
			      PIPE_ACCESS_DUPLEX,
			      PIPE_TYPE_BYTE,
			      PIPE_UNLIMITED_INSTANCES,
			      bufferSize,
			      bufferSize,
			      1,
			      NULL);

  if (h == INVALID_HANDLE_VALUE)
  {
    printf ("CreateNamedPipe failed\n");
    return 1;
  }

  HANDLE hReadPipe;
  HANDLE hWritePipe;
  BOOL good = CreatePipe (&hReadPipe, &hWritePipe, NULL, 100);
  if (!good)
  {
    printf ("CreatePipe failed\n");
    return 1;
  }

  print_object_name ("hReadPipe", hReadPipe);
  print_object_name ("hWritePipe", hWritePipe);
  print_object_name ("h", h);

  HANDLE duph = INVALID_HANDLE_VALUE;
  if (!DuplicateHandle (GetCurrentProcess(),
			hReadPipe,
			GetCurrentProcess(),
			&duph,
			0,
			TRUE,
			DUPLICATE_SAME_ACCESS))
    {
      printf ("DuplicateHandle failed\n");
      return 1;
    }

  print_object_name ("duph", duph);

  PROCESS_INFORMATION pi;

  STARTUPINFO si;
  memset (&si, 0, sizeof (si));
  si.cb = sizeof (si);

  CreateProcess (0,
		 "child.exe",/* command line */
		 NULL,	/* Security */
		 NULL,	/* thread */
		 TRUE,	/* inherit handles */
		 0,	/* start flags */
		 NULL,	/* environment */
		 NULL,	/* current directory */
		 &si,
		 &pi);

  return 0;
}

---------
child.c:

#include <stdio.h>
#include <windows.h>

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;

#define STATUS_SUCCESS 0
typedef ULONG NTSTATUS;

typedef enum _OBJECT_INFO_CLASS {
    ObjectBasicInfo,
    ObjectNameInfo,
    ObjectTypeInfo,
    ObjectAllTypesInfo,
    ObjectProtectionInfo
} OBJECT_INFO_CLASS;

typedef NTSTATUS (NTAPI * NTQUERYOBJECT)(HANDLE, OBJECT_INFO_CLASS,
					 PVOID, ULONG, PULONG);

typedef struct ObjectNameInfo_t {
    UNICODE_STRING ObjectName;
    WCHAR ObjectNameBuffer[1];
} OBJECT_NAME_INFO, *POBJECT_NAME_INFO;

static BOOL
print_object_name (const char *var, HANDLE h)
{
  HMODULE ntdll = GetModuleHandle ("ntdll.dll");
  NTQUERYOBJECT NtQueryObject
    = (NTQUERYOBJECT) GetProcAddress (ntdll, "NtQueryObject");

  char buf1[1024];
  char buf2[1024];

  POBJECT_NAME_INFO pObjectNameInfo = (POBJECT_NAME_INFO) buf1;

  int rc = NtQueryObject (h, ObjectNameInfo, buf1, sizeof (buf1), NULL);
  if (rc != STATUS_SUCCESS)
    {
      printf ("NtQueryObject failed with rc = 0x%x\n",  rc);
      return FALSE;
    }

  wcstombs (buf2, pObjectNameInfo->ObjectName.Buffer, 1024);
  printf ("child: Filename from handle (%s) returned :\n%s\n", var, buf2);
  return 0;
}

int
main (int argc, char **argv)
{
  print_object_name ("STD_INPUT_HANDLE", GetStdHandle (STD_INPUT_HANDLE));
  print_object_name ("STD_OUTPUT_HANDLE", GetStdHandle (STD_OUTPUT_HANDLE));
  print_object_name ("STD_ERROR_HANDLE", GetStdHandle (STD_ERROR_HANDLE));

  return 0;
}


  reply	other threads:[~2007-12-06  3:42 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-03 10:02 Pierre Muller
2007-12-04 23:50 ` Pedro Alves
2007-12-05  9:22   ` Pierre Muller
2007-12-05 22:56     ` Pedro Alves
2007-12-05 12:17   ` Corinna Vinschen
2007-12-05 19:19     ` Eli Zaretskii
2007-12-05 23:01     ` Pedro Alves
2007-12-06  1:06       ` Daniel Jacobowitz
2007-12-06  3:42         ` Pedro Alves
2007-12-06  4:25           ` Pedro Alves [this message]
2007-12-06 11:21             ` Corinna Vinschen
2007-12-07 13:54               ` Christopher Faylor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4053daab0712051942q2a421ac7mcc04224d673c0d1d@mail.gmail.com \
    --to=pedro_alves@portugalmail.pt \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox