Path: sranha!katsu From: katsu@sra.co.jp (WATANABE Katsuhiro) Message-ID: Date: 22 Jan 91 13:22:48 Organization: Software Research Associates, Inc.,Japan In-reply-to: kana@snoopy.src.ricoh.co.jp's message of 18 Jan 91 10:21:37 GMT Newsgroups: fj.unix Subject: UNIX read/write Distribution: fj References: <3637@snoopy.src.ricoh.co.jp> 記事 <3637@snoopy.src.ricoh.co.jp> で kana@snoopy.src.ricoh.co.jp (Katsumi Kanasaki) さんいはく > 斉藤さん: > >あとは socket, pty, tty などなど すべてread/write の引数で指 > >定したバイト数と実際に読み書きされたバイト数が違う恐れがあります。 > > どのような場合に違ってくるのか確認させてください。 私もそこが知りたいと思います。(少なくとも SOCK_STREAM への write 中に シグナルを捕捉する場合はその一例であると思っています。) > シグナルがからんだ場合の挙動はUNIXのバージョンによっても違うので複雑 > ですが、4.3BSDならsigvecで特殊な指定をしない限り、シグナルな > しの場合と同じことになるのではないでしょうか。 シグナルがからむと、write で指定したバイト数と実際に書かれたバイト数が 違う場合があることを示す(つもりの)実験例を出したいと思います。 最後にあるプログラムは、自ホストの TCP の discard サーバー (inetd) へ SOCK_STREAM ソケットで接続し、SIGINT を捕捉しつつ write(,,65536) を 繰り返し、その返り値を観察するためのものです。走らせて、Ctrl-C を 叩きまくってみてください。 私が NEWS-OS 2.2 および 4.0 と Sun OS 4.1 と VAX 4.3 BSD で 試したところでは、いずれも write が中途半端に終る場面が観察されました。 しかし、金崎さんのおっしゃるようにUNIXのバージョンによって違うのかも しれません。(4.2BSD では inetd が discard/tcp を実装していないので、 SERVNAME を ftp とかに替えて試しましたが、他人様にお勧めはできません :-) みなさんのところではいかがですか? ……ちょきちょき……ちょきちょき……ちょきちょき…… #include #include #include #include #include #include #include #ifndef MAXHOSTNAMELEN /* if 4.2BSD */ #define MAXHOSTNAMELEN 64 #endif #define SERVNAME "discard" #define WRITESIZE 65536 extern int errno; extern char *sys_errlist[]; char *malloc(); int sighandle(); main(argc, argv) int argc; char **argv; { struct sockaddr_in server; struct servent *sp; struct hostent *hp; int s; int writtenSize; char *data, localhostname[MAXHOSTNAMELEN]; if ((sp = getservbyname(SERVNAME, "tcp")) == (struct servent *)NULL) { fprintf(stderr, "%s: %s/tcp unknown service.¥n", argv[0], SERVNAME); exit(1); } if (gethostname(localhostname, MAXHOSTNAMELEN) < 0) { fprintf(stderr, "%s: ", argv[0]); perror("gethostname()"); exit(2); } if ((hp = gethostbyname(localhostname)) == (struct hostent *)NULL) { fprintf(stderr, "%s: %s: unknown host.¥n", argv[0], localhostname); exit(3); } bzero((char *)&server, sizeof(server)); bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length); server.sin_family = hp->h_addrtype; server.sin_port = sp->s_port; if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "%s: ", argv[0]); perror("socket()"); exit(4); } if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0) { fprintf(stderr, "%s: ", argv[0]); perror("connect()"); exit(5); } if ((data = malloc(WRITESIZE)) == (char *)NULL) { fprintf(stderr, "%s: cannot allocate memory.¥n", argv[0]); exit(9); } signal(SIGINT, sighandle); /* siginterrupt(SIGINT, 1); */ while (1) { printf("Trying to write(,,%d)...", WRITESIZE); fflush(stdout); writtenSize = write(s, data, WRITESIZE); if (writtenSize == (-1)) { printf("ERROR : %s¥n", sys_errlist[errno]); } else { printf("%d chars written.¥n", writtenSize); } fflush(stdout); } } sighandle(sig) int sig; { } ……ちょきちょき……ちょきちょき……ちょきちょき…… -- ----____----____ 渡邊克宏 SRAソフトウェア工学研究所