cygwin getservbyname実験室
cygwin環境でサービスのポート番号がどのように決定されるか実験してみた。
% ls -l /etc/services lrwxrwxrwx 1 haradats なし 37 Nov 2 23:33 /etc/hosts -> C:\WINDOWS\system32\drivers\etc\services % perl -e 'print getservbyname("ftp", "tcp") . "\n";' 21 % mv /etc/services /etc/services.bak % perl -e 'print getservbyname("ftp", "tcp") . "\n";' 21 % mv /etc/services.bak /etc/services % mv 'c:\windows\system32\drivers\etc\services' 'c:\windows\system32\drivers\etc\services.bak' % perl -e 'print getservbyname("ftp", "tcp") . "\n";' % mv 'c:\windows\system32\drivers\etc\services.bak' ' c:\windows\system32\drivers\etc\services' % perl -e 'print getservbyname("ftp", "tcp") . "\n";' 21 %
- cygwinのgetservbynameは/etc/servicesを参照していない(削除しても動作する)。その代わりに、
- %SystemRoot%\System32\drivers\etc\servicesを参照しているようだ
- cygwinのgetservbynameは、サービスとポート番号の対応について、レジストリのDataBasePathの値に格納されている値が示す「フォルダ」の下にあるservicesというファイルにより参照している。
上記はperlのone linerだが、C言語で書いても同じ結果だった。
#include#include main(int argc, char **argv) { struct servent *servent; if (argc != 2) { fprintf(stderr, "usage: %s \n", argv[0]); exit(1); } if ( (servent = getservbyname(argv[1], "tcp")) != NULL) { printf("%s\n", servent->s_name); /* official service name */ /* char **s_aliases; /* alias list */ printf("%d\n", ntohs(servent->s_port)); /* port # */ printf("%s\n", servent->s_proto); /* protocol to use */ } else { perror(argv[1]); } }