⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtable.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* dtable.cc: file descriptor support.   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. */#define  __INSIDE_CYGWIN_NET__#include "winsup.h"#include <errno.h>#include <sys/socket.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/cygwin.h>#include <assert.h>#include <ntdef.h>#include <winnls.h>#define USE_SYS_TYPES_FD_SET#include <winsock.h>#include "pinfo.h"#include "cygerrno.h"#include "perprocess.h"#include "security.h"#include "fhandler.h"#include "path.h"#include "dtable.h"#include "cygheap.h"#include "ntdll.h"static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,					   STD_ERROR_HANDLE};static const char *handle_to_fn (HANDLE, char *);static const char NO_COPY unknown_file[] = "some disk file";/* Set aside space for the table of fds */voiddtable_init (void){  if (!cygheap->fdtab.size)    cygheap->fdtab.extend (NOFILE_INCR);}void __stdcallset_std_handle (int fd){  if (fd == 0)    SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_handle ());  else if (fd <= 2)    SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_output_handle ());}voiddtable::dec_console_fds (){  if (console_fds > 0 && !--console_fds &&      myself->ctty != TTY_CONSOLE && !check_pty_fds())    FreeConsole ();}intdtable::extend (int howmuch){  int new_size = size + howmuch;  fhandler_base **newfds;  if (howmuch <= 0)    return 0;  /* Try to allocate more space for fd table. We can't call realloc ()     here to preserve old table if memory allocation fails */  if (!(newfds = (fhandler_base **) ccalloc (HEAP_ARGV, new_size, sizeof newfds[0])))    {      debug_printf ("calloc failed");      return 0;    }  if (fds)    {      memcpy (newfds, fds, size * sizeof (fds[0]));      cfree (fds);    }  size = new_size;  fds = newfds;  debug_printf ("size %d, fds %p", size, fds);  return 1;}voiddtable::get_debugger_info (){  if (being_debugged ())    {      char std[3][sizeof ("/dev/ttyNNNN")];      std[0][0] = std[1][0] = std [2][0] = '\0';      char buf[sizeof ("cYgstd %x") + 32];      sprintf (buf, "cYgstd %x %x %x", (unsigned) &std, sizeof (std[0]), 3);      OutputDebugString (buf);      for (int i = 0; i < 3; i++)	if (std[i][0])	  {	    path_conv pc;	    HANDLE h = GetStdHandle (std_consts[i]);	    fhandler_base *fh = build_fhandler_from_name (i, std[i], NULL, pc);	    if (!fh)	      continue;	    if (!fh->open (&pc, (i ? O_WRONLY : O_RDONLY) | O_BINARY, 0777))	      release (i);	    else	      CloseHandle (h);	  }    }}/* Initialize the file descriptor/handle mapping table.   This function should only be called when a cygwin function is invoked   by a non-cygwin function, i.e., it should only happen very rarely. */voiddtable::stdio_init (){  extern void set_console_ctty ();  /* Set these before trying to output anything from strace.     Also, always set them even if we're to pick up our parent's fds     in case they're missed.  */  if (myself->ppid_handle || ISSTATE (myself, PID_CYGPARENT))    return;  HANDLE in = GetStdHandle (STD_INPUT_HANDLE);  HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);  HANDLE err = GetStdHandle (STD_ERROR_HANDLE);  init_std_file_from_handle (0, in);  /* STD_ERROR_HANDLE has been observed to be the same as     STD_OUTPUT_HANDLE.  We need separate handles (e.g. using pipes     to pass data from child to parent).  */  if (out == err)    {      /* Since this code is not invoked for forked tasks, we don't have	 to worry about the close-on-exec flag here.  */      if (!DuplicateHandle (hMainProc, out, hMainProc, &err, 0,			     1, DUPLICATE_SAME_ACCESS))	{	  /* If that fails, do this as a fall back.  */	  err = out;	  system_printf ("couldn't make stderr distinct from stdout");	}    }  init_std_file_from_handle (1, out);  init_std_file_from_handle (2, err);  /* Assign the console as the controlling tty for this process if we actually     have a console and no other controlling tty has been assigned. */  if (myself->ctty < 0 && GetConsoleCP () > 0)    set_console_ctty ();}intdtable::find_unused_handle (int start){  AssertResourceOwner (LOCK_FD_LIST, READ_LOCK);  do    {      for (size_t i = start; i < size; i++)	/* See if open -- no need for overhead of not_open */	if (fds[i] == NULL)	  return i;    }  while (extend (NOFILE_INCR));  return -1;}voiddtable::release (int fd){  if (!not_open (fd))    {      switch (fds[fd]->get_device ())	{	case FH_SOCKET:	  dec_need_fixup_before ();	  break;	case FH_CONSOLE:	  dec_console_fds ();	  break;	}      delete fds[fd];      fds[fd] = NULL;    }}extern "C" intcygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin,			    DWORD myaccess){  if (fd == -1)    fd = cygheap->fdtab.find_unused_handle ();  path_conv pc;  fhandler_base *res = cygheap->fdtab.build_fhandler_from_name (fd, name, handle,								pc);  res->init (handle, myaccess, bin ?: pc.binmode ());  return fd;}voiddtable::init_std_file_from_handle (int fd, HANDLE handle){  const char *name;  CONSOLE_SCREEN_BUFFER_INFO buf;  struct sockaddr sa;  int sal = sizeof (sa);  DCB dcb;  unsigned bin = O_BINARY;  first_fd_for_open = 0;  if (!not_open (fd))    return;  SetLastError (0);  DWORD ft = GetFileType (handle);  if (ft == FILE_TYPE_UNKNOWN && GetLastError () == ERROR_INVALID_HANDLE)    name = NULL;  else    {      /* See if we can consoleify it */      if (GetConsoleScreenBufferInfo (handle, &buf))	{	  if (ISSTATE (myself, PID_USETTY))	    name = "/dev/tty";	  else	    name = "/dev/conout";	}      else if (GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))	{	  if (ISSTATE (myself, PID_USETTY))	    name = "/dev/tty";	  else	    name = "/dev/conin";	}      else if (ft == FILE_TYPE_PIPE)	{	  if (fd == 0)	    name = "/dev/piper";	  else	    name = "/dev/pipew";	}      else if (wsock_started && getpeername ((SOCKET) handle, &sa, &sal) == 0)	name = "/dev/socket";      else if (GetCommState (handle, &dcb))	name = "/dev/ttyS0"; // FIXME - determine correct device      else	{	  name = handle_to_fn (handle, (char *) alloca (MAX_PATH + 100));	  bin = 0;	}    }  if (!name)    fds[fd] = NULL;  else    {      path_conv pc;      fhandler_base *fh = build_fhandler_from_name (fd, name, handle, pc);      if (!bin)	{	  bin = fh->get_default_fmode (O_RDWR);	  if (!bin && name != unknown_file)	    bin = pc.binmode ();	}      fh->init (handle, GENERIC_READ | GENERIC_WRITE, bin);      set_std_handle (fd);      paranoid_printf ("fd %d, handle %p", fd, handle);    }}fhandler_base *dtable::build_fhandler_from_name (int fd, const char *name, HANDLE handle,				  path_conv& pc, unsigned opt, suffix_info *si){  pc.check (name, opt | PC_NULLEMPTY | PC_FULL | PC_POSIX, si);  if (pc.error)    {      set_errno (pc.error);      return NULL;    }  if (!pc.exists () && handle)    pc.fillin (handle);  fhandler_base *fh = build_fhandler (fd, pc.get_devn (),				      pc.return_and_clear_normalized_path (),				      pc, pc.get_unitn ());  return fh;}fhandler_base *dtable::build_fhandler (int fd, DWORD dev, const char *unix_name,			const char *win32_name, int unit){  return build_fhandler (fd, dev, cstrdup (unix_name), win32_name, unit);}#define cnew(name) new ((void *) ccalloc (HEAP_FHANDLER, 1, sizeof (name))) namefhandler_base *dtable::build_fhandler (int fd, DWORD dev, char *unix_name,			const char *win32_name, int unit){  fhandler_base *fh;  dev &= FH_DEVMASK;  switch (dev)    {      case FH_TTYM:	fh = cnew (fhandler_tty_master) (unit);	break;      case FH_CONSOLE:      case FH_CONIN:      case FH_CONOUT:	if ((fh = cnew (fhandler_console) ()))	  inc_console_fds ();	break;      case FH_PTYM:	fh = cnew (fhandler_pty_master) ();	break;      case FH_TTYS:	if (unit < 0)	  fh = cnew (fhandler_tty_slave) ();	else	  fh = cnew (fhandler_tty_slave) (unit);	break;      case FH_WINDOWS:	fh = cnew (fhandler_windows) ();	break;      case FH_SERIAL:	fh = cnew (fhandler_serial) (unit);	break;      case FH_PIPE:      case FH_PIPER:      case FH_PIPEW:	fh = cnew (fhandler_pipe) (dev);	break;      case FH_SOCKET:	if ((fh = cnew (fhandler_socket) ()))	  inc_need_fixup_before ();	break;      case FH_DISK:	fh = cnew (fhandler_disk_file) ();	break;      case FH_CYGDRIVE:	fh = cnew (fhandler_cygdrive) (unit);	break;      case FH_FLOPPY:	fh = cnew (fhandler_dev_floppy) (unit);	break;      case FH_TAPE:	fh = cnew (fhandler_dev_tape) (unit);	break;      case FH_NULL:	fh = cnew (fhandler_dev_null) ();	break;      case FH_ZERO:	fh = cnew (fhandler_dev_zero) ();	break;      case FH_RANDOM:	fh = cnew (fhandler_dev_random) (unit);	break;      case FH_MEM:	fh = cnew (fhandler_dev_mem) (unit);	break;      case FH_CLIPBOARD:	fh = cnew (fhandler_dev_clipboard) ();	break;      case FH_OSS_DSP:	fh = cnew (fhandler_dev_dsp) ();	break;      case FH_PROC:	fh = cnew (fhandler_proc) ();	break;      case FH_REGISTRY:	fh = cnew (fhandler_registry) ();	break;      case FH_PROCESS:	fh = cnew (fhandler_process) ();	break;      default:	system_printf ("internal error -- unknown device - %p", dev);	fh = NULL;    }  if (unix_name)    {      char new_win32_name[strlen (unix_name) + 1];      if (!win32_name)	{	  char *p;	  /* FIXME: ? Should we call win32_device_name here?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -