--- Begin Message ---
- To: submit@bugs.debian.org
- Subject: g++: std::basic_filebuf::pubseekoff works incorrect on amd64
- From: Сергей Ниваров <newarrow@bk.ru>
- Date: Fri, 07 Jul 2006 15:25:33 +0400
- Message-id: <E1FyoSj-000E8I-00.newarrow-bk-ru@f42.mail.ru>
- Reply-to: Сергей Ниваров <newarrow@bk.ru>
Package: g++
Version: 4.0.3-3 , 4.1.1-5
I use stdio_filebuf for handling socket on in|out directions. If after first read i use write (or after first write use read) socket crashes. To prevent failure i use pubseekoff which fixes error. It works great on i386 but not on amd64. Same happens on g++ versions 4.0.3 and 4.1.1.
Below is 2 examples: http.c(write,read) and ftp.c(read,write).
Compiling command: g++ http.c ; g++ ftp.c
kernel: 2.6.16-2-em64t (2.6.16-2-686 on i386), libc6: 2.3.6.15
/// http.c ///
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <ext/stdio_filebuf.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons(80);
if (connect(sockfd, (sockaddr*)(&address), sizeof(address)))
{ std::cerr << "connect failed " << std::endl; exit(1); }
__gnu_cxx::stdio_filebuf<char> sockBuf (sockfd, std::ios_base::in | std::ios_base::out);
std::iostream sock(&sockBuf);
std::string in;
sock << "GET / HTTP/1.0\n\n" << std::flush; // succeeds
sockBuf.pubseekoff(0, std::ios_base::cur); // to prevent failure on
std::getline(sock, in); // socket crashes
std::cout << "have read: " << in << '\n'; // amd64: <null> ; i386: HTTP/1.1 200 OK
sleep(20); // pause to check apache logs if connection closed
return 0;
}
/// end of http.c ///
/// ftp.c: ///
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <ext/stdio_filebuf.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons(21);
if (connect(sockfd, (sockaddr*)(&address), sizeof(address)))
{ std::cerr << "connect failed " << std::endl; exit(1); }
__gnu_cxx::stdio_filebuf<char> sockBuf (sockfd, std::ios_base::in | std::ios_base::out);
std::iostream sock(&sockBuf);
std::string in;
std::getline(sock, in); // succeeds
std::cout << in << std::endl;
sockBuf.pubseekoff(0, std::ios_base::cur); // to prevent failure on out
sock << "quit\n"; // socket crashes
if (sock.bad()) { std::cerr << "write failed badly\n"; }
in.clear();
sock.clear();
std::getline(sock, in); // hangs
std::cerr << "have read\n";
return 0;
}
Sergey Nivarov
--- End Message ---