Ключевые слова:solaris, trouble, socket, (найти похожие документы)
Date: Thu, 31 Oct 2002 15:54:51 +0500
From: Alexandre Snarskii <snar@paranoia.ru>
Newsgroups: ftn.ru.unix.prog
Subject: Solaris и соблюдение требования ANSI C по позиционированию между read/write
Hапоролся вот :)) Дано (в псевдокоде) :
/* совершенно стандартная процедура создания TCP socket и connect
на нужный нам сервер */
int s = socket (...);
connect(s,....);
FILE* f=fdopen(s,"r+");
char buffer[...];
/* протокольная секция */
fprintf(f,"%s\n", "some expression");
fread(buffer,sizeof(buffer),1,f);
/* до этого момента все идет прекрасно, вот кусок вывода truss:
* so_socket(PF_INET, SOCK_STREAM, IPPROTO_IP, "", 1) = 4
* connect(4, 0x0002B06C, 16, 1) = 0
* fstat64(4, 0xFFBFF080) = 0
* fstat64(4, 0xFFBFEF28) = 0
* ioctl(4, TCGETA, 0xFFBFF00C) Err#22 EINVAL
* write(4, " ! !\n ! s r a d b , r i".., 22) = 22
* read(4, " C\n", 8192) = 2
* что хотели, то и получили */
/* продолжаем протокол : */
fprintf(f,"%s\n","!gAS3254\r\n");
/* и вот тут-то и наступает она самая, родимая. Потому что в поток
* записывается вот такое:
*
* write(4, " C\n ! g A S 3 2 5 4\r\n", 12) = 12
*
* - попрошу особо отметить, что перед нашим блоком зачем-то записали
* еще и свежесчитанный "C\n".
*/
Удаленный сервер, видя такое злобное нарушение протокола,
разумеется, отвечает, что оппаньки, и работать дальше смысла
не имеет.
При этом на других системах (FreeBSD,OpenBSD,Linux) все работает
аки из пушки. А тут какое-то странное эхо появляется...
Вот. В общем, век живи, век RTFM, а все равно LMD.
Solaris оказался единственной системой, которая реализует
требование ANSI C о необходимости позиционирования между
read/write calls. При чем это даже в man'ах "нормальных"
unix'ов записано - вот, из FreeBSD например:
Reads and writes may be intermixed on read/write streams in any order,
and do not require an intermediate seek as in previous versions of stdio.
This is not portable to other systems, however; ANSI C requires that a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
file positioning function intervene between output and input, unless an
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
input operation encounters end-of-file.
Так что пришлось перед каждым fprintf'ом вставить fseek(f,0,SEEK_END)
и заработало...