`
xiaoer_1982
  • 浏览: 1832158 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

cygwin关键技术:设备模拟

阅读更多

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

本文适用于

Cygwin checkout-2008-09-28

vs2008

欢迎转载,但请保留作者信息

Linux下有众多的设备,但是这些设备都有统一的接口,可以很方便地用open/close/read/write函数进行操作,而在windows下,很多不同的设备都由不同的API进行操作,为此cygwin引入了fhandler,其文档这样解释:

fhandlers are the core mechanism by which cygwin provides a file descripter (fd)

interface to things such as a random number generated, winsock sockets, raw disk

devices, the clipboard, the console and so on. Under unix access to all such

devices is via a combination of IOCTL's and open/close/read/write calls. Some

special functions do exist - such as bind () and listen () for sockets, but

these consistently operate on fd's. Under Win32 there are disparate interfaces

that have little in common with each other. See for example Direct Sound and

the Clipboard.

下面我们就来学习一下它的实现过程。

1.1 类关系图

使用vs2008提供的类关系图分析,可以发现很多相关的类:

class diagram

这些类都从一个叫fhandler_base的父类继承而来,很容易猜想fhandler_base将为设备定义一个统一的接口,其具体实现则由子类完成。当需要对某个设备进行操作时再创建相应的对象。

查看fhandler_base的定义,可以发现一些很熟悉的虚函数:

class fhandler_base

{

………………

virtual int open (int, mode_t = 0);

virtual int close ();

virtual int ioctl (unsigned int cmd, void *);

virtual int fcntl (int cmd, void *);

virtual ssize_t readv (const struct iovec *, int iovcnt, ssize_t tot = -1);

virtual ssize_t writev (const struct iovec *, int iovcnt, ssize_t tot = -1);

virtual ssize_t __stdcall pread (void *, size_t, _off64_t) __attribute__ ((regparm (3)));

virtual ssize_t __stdcall pwrite (void *, size_t, _off64_t) __attribute__ ((regparm (3)));

virtual _off64_t lseek (_off64_t offset, int whence);

……………….

}

1.2 设备创建

Cygwin模拟了大部分Linux pc下的设备,基本上每一类设备都可以找到一个实现对应功能的类,这些类都从fhandler_base继承而来,但是cygwin并不鼓励用new创建这些类的实例,其原因如下:

Note: In most case, it is safe to assume that using new/delete (or

malloc/free) in an fhandler is dangerous and to be avoided. The reason

for this is that memory allocated to fhandlers is copied between execed

processes in the cygwin heap. Memory allocated in new/delete is only

copied to forked processes. So use cmalloc/cfree.

Obviously it is possible to use new/delete in some situations but if you're

seeing strange core dumps with usages like cat < /my/newfhandler then the

above may well be the culprit.

实际上,cygwin希望用户使用open函数来打开设备,这个函数将最终调用一个叫build_fh_pc的函数进行实例的创建:

#define fh_unset ((fhandler_base *) 1)

fhandler_base *

build_fh_pc (path_conv& pc)

{

fhandler_base *fh = fh_unset;

switch (pc.dev.major)

{

…………

default:

switch (pc.dev)

{

case FH_CONSOLE:

case FH_CONIN:

case FH_CONOUT:

fh = cnew (fhandler_console) ();

break;

…………….

}

}

if (fh == fh_unset)

fh = cnew (fhandler_nodevice) ();

if (fh)

fh->set_name (pc);

else

set_errno (EMFILE);

debug_printf ("fh %p", fh);

return fh;

}

注意上述函数在创建实例时使用了一个叫cnew的宏:

#define cnew(name) new ((void *) ccalloc (HEAP_FHANDLER, 1, sizeof (name))) name

这样,创建出来的实例将使用cygwin内部使用的heap空间。

1.3 设备对象管理

对于上面创建出来的实例,cygwin又是如何管理的呢?因为cygwin下的设备可以使用open函数打开,我们就从open函数看起:

int open (const char *unix_path, int flags, ...)

{

int res = -1;

va_list ap;

mode_t mode = 0;

sig_dispatch_pending ();

syscall_printf ("open (%s, %p)", unix_path, flags);

myfault efault;

//if (efault.faulted (EFAULT))

// /* errno already set */;

//else if (!*unix_path)

if (!*unix_path)

set_errno (ENOENT);

else

{

/* check for optional mode argument */

va_start (ap, flags);

mode = va_arg (ap, mode_t);

va_end (ap);

fhandler_base *fh;

cygheap_fdnew fd;

if (fd >= 0)

{

if (!(fh = build_fh_name (unix_path, NULL,

(flags & (O_NOFOLLOW | O_EXCL))

? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW,

stat_suffixes)))

res = -1; // errno already set

else if ((flags & O_NOFOLLOW) && fh->issymlink ())

{

……………

}

else if (!fh->open (flags, (mode & 07777) & ~cygheap->umask))

{

delete fh;

res = -1;

}

else

{

cygheap->fdtab[fd] = fh;

if ((res = fd) <= 2)

set_std_handle (res);

}

}

}

syscall_printf ("%d = cyg_open (%s, %p)", res, unix_path, flags);

return res;

}

在创建对象的实例后,关键操作在

cygheap->fdtab[fd] = fh;

在这里init_cygheap里的一个成员

dtable fdtab;

其类型为dtablecygwin用它来对这些创建出来的实例进行管理。注意这里的fdtab是放在cygheap上的,这样在传递给fork出来的子进程时将可以很容易知道父进程打开的设备,并能根据这些设备的种类采取不同的措施,如句柄的继承,复制特定的数据等等。

2 参考资料

cygwin关键技术:cygheap(2009-9-2)

cygwin关键技术:tls(2009-8-24)

vs2008下使用cygwin23):stdinstdoutstderr(2008-10-21)

vs2008下使用cygwin22):使用tls(2008-10-20)

分享到:
评论

相关推荐

    cygwin安装资源.zip

    Cygwin的一个关键优势是它支持在Windows上编译源代码,这对于那些需要在Linux环境下编译的项目特别有用。GCC(GNU Compiler Collection)作为Cygwin的一部分,可以用来编译C、C++、Fortran和其他编程语言的源代码。...

    threadx cygwin skyeye基于2410

    ThreadX是一款广泛使用的嵌入式RTOS,Cygwin则是一个在Windows上提供类UNIX开发环境的软件,而SkyEye是一个开源的、高性能的嵌入式系统模拟器,可以用来模拟多种硬件平台。 描述中提到的“在cygwin上基于skyeye的...

    ejtag-debug-cygwin-v3.8.2.rar

    ejtag-debug-cygwin是一款基于Cygwin环境的EJTAG调试工具,Cygwin是Windows上的一个类Unix模拟环境,允许在Windows上运行许多Linux下的命令行工具。ejtag-debug-cygwin提供了与龙芯1B处理器通信的接口,支持用户进行...

    Cygwin Terminal

    Cygwin Terminal是一款在Windows操作系统上模拟Linux终端环境的软件,它为开发者提供了一个类似于Linux命令行的界面,便于在Windows环境下进行JNI(Java Native Interface)开发。JNI是Java平台的一项重要技术,允许...

    nutch-0.9 环境搭建所需最小cygwin

    Cygwin是一个在Windows上模拟Linux环境的开源软件,它提供了许多在Linux环境下才能运行的命令行工具,使得我们能够在Windows系统上执行类似Linux的操作,这对于需要在Windows系统中运行Nutch这样的基于Unix/Linux的...

    计算代数库Pari2.6.1, Cygwin编译静态库

    总的来说,通过Cygwin编译Pari2.6.1为静态库是一项复杂而关键的任务,它涉及了数学软件的底层实现、编译技术以及跨平台兼容性。这个过程不仅可以帮助开发者更好地理解和控制软件的构建过程,也为终端用户提供了一种...

    Cygwin User's Guide

    Cygwin是一个在Windows操作系统上模拟Linux环境的开源工具集。它通过提供一个兼容的POSIX层,使得用户可以在Windows上运行许多原本为Unix或Linux设计的应用程序。Cygwin用户指南是为那些希望在Windows环境中使用...

    可以在cygwin下面编译通过的cldc kvm 1.1

    标签“cldc kvm”直接对应了该资源的关键技术点,即与Java ME开发相关的CLDC和KVM。 压缩包内的文件列表提供了进一步的信息: 1. `copyright.html`:通常包含软件的版权信息和许可协议。 2. `index.html`:可能是...

    OpenSSL1.0.1cForAndroid.zip

    "cygwin" 和 "ndk" 标签则强调了编译过程中使用的工具和技术,Cygwin提供了Linux环境下的命令行工具和编译环境,而NDK则为构建原生库提供了必要的API和编译工具。 在压缩包内的文件名称 "OpenSSL1.0.1cForAndroid-...

    msys-1.0.dll

    - **系统组件:** msys-1.0.dll是Msys系统的核心组件,它包含了用于模拟Unix环境所需的关键功能。 - **内存管理:** 这个动态链接库涉及到Cygwin或Msys的内存分配机制,当系统报告无法为Cygwin的堆分配空间时,可能...

    Windows和Linux系统下NS-2网络模拟软件的安装.pdf

    NS-2(Network Simulator version 2)是一种开源的和免费的网络模拟软件,主要用于网络技术的研究和开发。NS-2由UC Berkeley开发而成,具有虚拟时钟和离散事件驱动的特点,能够完全模拟整个网络环境。NS-2采用两级...

    win7+eclips+cygn+android+cocos2dx

    1. **Cygwin**:Cygwin是一个在Windows操作系统上模拟Unix环境的开源工具集,它提供了许多在Linux下常见的命令行工具,包括编译器和链接器,使得开发者可以在Windows下进行类似Unix的开发工作。为了在Windows下编译...

    windows下模拟unix文件系统

    在Windows操作系统中模拟Unix文件系统是一项重要的技术,它允许开发者和用户在Windows环境中使用与Unix类似的操作方式,以便于在跨平台开发或者使用Unix工具时保持一致性。这主要通过使用像Cygwin、MSYS2或Git Bash...

    yasm编译工具

    3. **跨平台支持**:除了原生支持Windows,`yasm`还可在Linux、Mac OS X等操作系统上运行,尤其在Cygwin环境下,可以模拟Linux环境进行开发。 4. **兼容性广**:`yasm`不仅兼容NASM语法,还支持Intel和AT&T汇编语法...

    基于蒙特卡洛模拟的CDO损失分布测算研究及实证分析_尹占华

    :CDO 作为一种资产组合, 其信用质量的度量关键取决于如何处理资产之间的相关性。在介绍常用于测算CDO 损失分布的二项式扩展技术的基础上, 提出了一种蒙特卡洛模拟方法:即在分别采用不同工具处 理资产之间相关性的...

    hadoop在win上搭建需要的工具类

    2. **Cygwin**:由于Hadoop依赖于许多Linux命令,如`ssh`和`scp`,Cygwin提供了一个模拟Linux环境的层。它包括了所需的命令行工具,如`bash`、`ssh`等。确保在Cygwin中安装了这些必要的包。 3. **WinUtils**:这是...

    基于ZigBee网络的无线测控基站GPRS通信模块的设计与实现.doc

    《基于ZigBee网络的无线测控基站...通过这些关键技术的结合,文章实现了ZigBee网络与GPRS通信的无缝对接,创建了一个成本效益高的无线测控系统,该系统具有广泛的应用前景,特别是在需要远程监控和数据传输的场景下。

    Windows程序运行于Linux系统的技术.pdf

    因此,开发支持Windows设备驱动程序和应用程序的Linux兼容内核成为提升Linux市场竞争力的关键。 此外,文章还提及了未来的发展趋势,随着技术的进步,如容器化技术(Docker等)和轻量级虚拟化技术的发展,可能会...

    云计算 实验三(新)

    【云计算 实验三(新)】的实验内容主要围绕着Hadoop环境的搭建,涉及到的主要技术有JDK的安装、Cygwin的安装与配置、SSHD服务的安装与启动,以及SSH登录的配置,最后是Hadoop安装包的下载与安装。以下是详细的知识...

    跨平台嵌入式Linux开发环境研究.pdf

    嵌入式Linux开发是一项关键的技术,尤其在当今自动化需求日益增长的时代,嵌入式系统广泛应用于各种设备中。Linux操作系统因其开源、低成本和高可靠性,成为嵌入式领域的首选。为了在不同的平台上进行嵌入式Linux...

Global site tag (gtag.js) - Google Analytics