is-cygwin-tty check

Corinna Vinschen corinna-cygwin@cygwin.com
Sat Nov 12 09:11:00 GMT 2016


Hi Mihail,

On Nov 12 07:34, Mihail Konev wrote:
> On Sat, Nov 12, 2016 at 07:21:07AM +0500, Mihail Konev wrote:
> > 
> > Is the check correct?
> > 
> > In particular, should it put any restrictions
> > on what is before and after the -pty%d- (slashes, non-[-a-z0-9] ?)
> > 
> 
> A spare question ...
> 
> fhandler_tty.cc says it all:
>   \Device\NamedPipe\[a-z0-9]+-[a-z0-9]+-pty[0-9]+-[-a-z0-9]+

That looks a bit too open for my taste.  I attached a proposal for
an isatty(3) replacement I proposed to a customer a couple years ago.
Hope that helps.  Feel free to discuss it further on this list.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
#include <stdio.h>
#include <io.h>

#include <errno.h>
#include <wchar.h>
#include <windows.h>
#include <winternl.h>

#ifndef __MINGW64_VERSION_MAJOR
/* MS winternl.h defines FILE_INFORMATION_CLASS, but with only a
   different single member. */
enum FILE_INFORMATION_CLASSX
{
  FileNameInformation = 9
};

typedef struct _FILE_NAME_INFORMATION
{
  ULONG FileNameLength;
  WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;

NTSTATUS (NTAPI *pNtQueryInformationFile) (HANDLE, PIO_STATUS_BLOCK, PVOID,
					  ULONG, FILE_INFORMATION_CLASSX);
#else
NTSTATUS (NTAPI *pNtQueryInformationFile) (HANDLE, PIO_STATUS_BLOCK, PVOID,
					  ULONG, FILE_INFORMATION_CLASS);
#endif

int
isatty (int fd)
{
  HANDLE fh;
  NTSTATUS status;
  IO_STATUS_BLOCK io;
  long buf[66];	/* NAME_MAX + 1 + sizeof ULONG */
  PFILE_NAME_INFORMATION pfni = (PFILE_NAME_INFORMATION) buf;
  PWCHAR cp;

  /* First check using _isatty.
  
     Note that this returns the wrong result for NUL, for instance! 
     Workaround is not to use _isatty at all, but rather GetFileType
     plus object name checking. */
  if (_isatty (fd))
    return 1;

  /* Now fetch the underlying HANDLE. */
  fh = (HANDLE) _get_osfhandle (fd);
  if (!fh || fh == INVALID_HANDLE_VALUE)
    {
      errno = EBADF;
      return 0;
    }

  /* Must be a pipe. */
  if (GetFileType (fh) != FILE_TYPE_PIPE)
    goto no_tty;

  /* Calling the native NT function NtQueryInformationFile is required to
     support pre-Vista systems.  If that's of no concern, Vista introduced
     the GetFileInformationByHandleEx call with the FileNameInfo info class,
     which can be used instead. */
  if (!pNtQueryInformationFile)
    {
      pNtQueryInformationFile = (NTSTATUS (NTAPI *)(HANDLE, PIO_STATUS_BLOCK,
      				PVOID, ULONG, FILE_INFORMATION_CLASS))
			       GetProcAddress (GetModuleHandle ("ntdll.dll"),
					       "NtQueryInformationFile");
      if (!pNtQueryInformationFile)
      	goto no_tty;
    }
  if (!NT_SUCCESS (pNtQueryInformationFile (fh, &io, pfni, sizeof buf,
					   FileNameInformation)))
    goto no_tty;

  /* The filename is not guaranteed to be NUL-terminated. */
  pfni->FileName[pfni->FileNameLength / sizeof (WCHAR)] = L'\0';

  /* Now check the name pattern.  The filename of a Cygwin pseudo tty pipe
     looks like this:

       \cygwin-%16llx-pty%d-{to,from}-master
     
     %16llx is the hash of the Cygwin installation, (to support multiple
     parallel installations), %d is the pseudo tty number, "to" or "from"
     differs the pipe direction. "from" is a stdin, "to" a stdout-like
     pipe. */
  cp = pfni->FileName;
  if (!wcsncmp (cp, L"\\cygwin-", 8)
      && !wcsncmp (cp + 24, L"-pty", 4))
    {
      cp = wcschr (cp + 28, '-');
      if (!cp)
      	goto no_tty;
      if (!wcscmp (cp, L"-from-master") || !wcscmp (cp, L"-to-master"))
      	return 1;
    }
no_tty:
  errno = EINVAL;
  return 0;
}

int
main ()
{
  if (isatty(0))
    printf("tty\n");
  else
    printf("not a tty\n");
  return 0;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-developers/attachments/20161112/e47bcf6c/attachment.sig>


More information about the Cygwin-developers mailing list