最近,手头有个工作是把一个UNIX平台的项目移植到Windows平台,为了缩短开发周期,选择了cygwin作为解决方案。
因为是第一次接触cygwin, 难免就会遇到许多这样那样的问题。在这里,把遇到的问题和解决的办法罗列出来,既作为备忘,也可供参考。
环境:
Power Edge 1800(X3.0G/512MB/73G), Windows 2003, cygwin 1.5.18
1. 安装cygwin
ed2k://|file|[Cygwin].cygwin-cd-release-20051102.iso|1194323968|F43228693B5E32C2581B93F1481D0217|h=UMPATFPVS4IOP2IT2TPOPFD2KARCQCML|/|sources,218.12.212.11:4662|/
找了个完整安装包,本地安装就是方便。
2006.05.16
2. 提供telnet,ftp服务
既然是UNIX的模拟环境,当然要有telnet,ftp才好用。
简单的办法就是安装xinetd服务:
$cygrunsrv -I xinetd -p /usr/sbin/xinetd -d ‘CYGWIN xinetd’ -1 /dev/null -2 /dev/null
$cygrunsrv -S xinetd
2006.05.17
4. 设置用户
既然有了telnet和ftp,自然也的需要有用户了。
为了使 cygwin 能够接受登录,需要一个 passwd 文件。这可用以下代码完成:
$ mkpasswd -l > /etc/passwd
$ mkgroup -l > /etc/group
如果在windows上对用户做了什么改动,也需要执行这两个命令,这样才能保证信息的一致性。
注意:一般情况下,应把guest用户从/etc/passwd中去掉。
2006.05.17
3. 测试cygwin对大文件的支持。
有人说,早期的cygwin是不支持2GB以上的大文件的,所以写个程序测试一下。
众所周知,程序要实现LFS(large file support)需要定义宏: _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
这个没什么好说的。
需要注意的是:
cygwin中的有关函数原型为:
int fseek(FILE *FP, long OFFSET, int WHENCE);
int fseeko(FILE *FP, off_t OFFSET, int WHENCE);
所以代码中应使用 fseeko 而不是 fseek, 移植代码需要注意到这一点;
2006.05.20
4. 调用semget出错:"Bad system call"
在cygwin下要使用IPC,还要做一些工作才行:
a. 安装cygipc:
从cygwin安装包取得cygpic的安装包:cygipc-2.03-2.tar.bz2
$cp cygipc-2.03-2.tar.bz2 /
$cd /
$tar --bzip2 -xf cygipc-2.03-2.tar.bz2
$ipc-daemon2 --install-as-service
$net start ipc-daemon2
b. 安装cygserver
$cygserver-config
$net start cygserver
c. 设置CYGWIN变量
$export CYGWIN=server
2006.05.25
5. 调用semget出错:"No space left on device(errno=28)"
cygwin下,和信号灯有关的一些缺省值太小,所以会出现这样的错误信息。
要解决这个问题,自然就的修改这些缺省值了:
和 cygserver 有关的选项, 保存在 /etc/cygserver.conf, 只有在在启动cygserver时才读取此文件。
缺省的配置文件安装在/etc/defaults/etc 目录,/usr/bin/cygserver-config 脚本会把它拷贝到 /etc 目录,所以可以放心的修改 /etc/cygserver.conf。
修改的内容:
# kern.ipc.semmns: Maximum no. of semaphores hold concurrently.
# Default: 60, Min: 1, Max: 1024
kern.ipc.semmns 1024
# kern.ipc.semmsl: Maximum no. of semaphores per semaphore id.
# Default: 60, Min: 1, Max: 1024
kern.ipc.semmsl 120
注释很清楚,没什么好说的了。
2006.06.01
6. 如何生成 coredump 文件?
在cygwin下,程序崩溃了,却只生成一个*.stackdump 文件,里面的东西有一些堆栈信息,没太大价值。
郁闷!怎么没有 coredump 文件呢?
还是看文档吧,《Cygwin User’s Guide》
Chapter 3. Using Cygwin
The CYGWIN environment variable
error_start:Win32filepath - if set, runs Win32filepath when cygwin encounters a
fatal error, which is useful for debugging. Win32filepath is usually set to the path
to gdb or dumper, for example C:/cygwin/bin/gdb.exe. There is no default set.
以前也看到过,就是没引起重视,现在只有这根救命稻草了。
设置error_start为C:/cygwin/bin/dumper.exe
$ export CYGWIN='error_start=C:/cygwin/bin/dumper.exe'
再执行程序,哈哈,*.core 出来了。
2006.06.06
7. 裸设备的读写
目前遇到的问题是需要直接向裸设备写入数据。
windows是没有裸设备的概念的,但cygwin有,还是看看文档吧:
《Cygwin User's Guide》3. Using Cygwin - Special filenames - POSIX devices :
Beginning with Cygwin 1.3.4, raw devices are accessible by Cygwin processes using fixed POSIX device names.
The new fixed POSIX names are mapped to NT internal devices as follows:
...
/dev/sda /device/harddisk0/partition0 (whole disk)
/dev/sda1 /device/harddisk0/partition1 (first partition)
...
这样看来,应该是件很简单的事情嘛!
于是写了段代码用来向 /dev/sda2 写入数据:
FILE *fp = NULL;
char *buf = "test";
fp=fopen( "/dev/sda2","r+" );
fwrite( buf,1,4,fp); // fwrite 返回 4
fclose(fp); // 但 fclose 返回 -1
数据没写进去!有点奇怪!
后来试用dd命令:
dd if=/dev/sda1 of=/dev/sda2
dd if=write.c of=/dev/sda2
这都可以写入!
注意到一个细节,write.c 是697 bytes,但是只写入了512 bytes。
512不就是一个硬盘扇区的大小吗,问题应该就在这儿了。
在dd命令中, ibs和obs的默认值也是512, 但这个值是块大小的概念,和碰到的问题关系不大。
个人理解:读写硬盘时,只能以扇区大小为基本单位。
把代码改一下:
#define SECTOR_SIZE 512
FILE *fp = NULL;
char buf[SECTOR_SIZE] = "test";
fp=fopen( "/dev/sda2","r+" );
fwrite( buf,1,SECTOR_SIZE,fp);
fclose(fp);
OK!数据成功写入!
有消息说,IDEMA已经同意将硬盘扇区大小由目前的512Byte增加到4096Byte, 那是不是以后我的代码还得改呢?
2006.06.15
?. 下一个问题是什么呢?
版权声明:本文为博主原创文章,未经博主允许不得转载。