Am Freitag, 6. April 2007 16:02 schrieb Enrico Forestieri:

> I don't think that your commit fixes 3410. I was working on the attached
> patch that fixes it. The only relevant bit is in tempname.C, all other
> changes are consequential to that. I'll adapt this to your last commit.

Oh, even more encoding confusing. Does the attached version still work? The 
difference to your version is that we don't pass strings in filesystem 
encoding around. This is dangerous, because it leads exactly to bugs like 
3410.
If it works, please put it in.


Georg
Index: src/lyxsocket.C
===================================================================
--- src/lyxsocket.C	(Revision 17746)
+++ src/lyxsocket.C	(Arbeitskopie)
@@ -48,7 +48,7 @@ namespace lyx {
 // Address is the unix address for the socket.
 // MAX_CLIENTS is the maximum number of clients
 // that can connect at the same time.
-LyXServerSocket::LyXServerSocket(LyXFunc * f, string const & addr)
+LyXServerSocket::LyXServerSocket(LyXFunc * f, support::FileName const & addr)
 	: func(f),
 	  fd_(support::socktools::listen(addr, 3)),
 	  address_(addr)
@@ -62,7 +62,7 @@ LyXServerSocket::LyXServerSocket(LyXFunc
 	// Needed by xdvi
 	support::setEnv("XEDITOR", "lyxclient -g %f %l");
 	// Needed by lyxclient
-	support::setEnv("LYXSOCKET", address_);
+	support::setEnv("LYXSOCKET", address_.toFilesystemEncoding());
 
 	theApp()->registerSocketCallback(
 		fd_,
@@ -70,7 +70,7 @@ LyXServerSocket::LyXServerSocket(LyXFunc
 		);
 
 	LYXERR(Debug::LYXSERVER) << "lyx: New server socket "
-				 << fd_ << ' ' << address_ << endl;
+				 << fd_ << ' ' << address_.absFilename() << endl;
 }
 
 
@@ -84,14 +84,14 @@ LyXServerSocket::~LyXServerSocket()
 			lyxerr << "lyx: Server socket " << fd_
 			       << " IO error on closing: " << strerror(errno);
 	}
-	support::unlink(support::FileName(address_));
+	support::unlink(address_);
 	LYXERR(Debug::LYXSERVER) << "lyx: Server socket quitting" << endl;
 }
 
 
-string const & LyXServerSocket::address() const
+string const LyXServerSocket::address() const
 {
-	return address_;
+	return address_.absFilename();
 }
 
 
@@ -191,7 +191,7 @@ void LyXServerSocket::writeln(string con
 // void LyXServerSocket::dump() const
 // {
 //	lyxerr << "LyXServerSocket debug dump.\n"
-//	     << "fd = " << fd_ << ", address = " << address_ << ".\n"
+//	     << "fd = " << fd_ << ", address = " << address_.absFilename() << ".\n"
 //	     << "Clients: " << clients.size() << ".\n";
 //	std::map<int, shared_ptr<LyXDataSocket> >::const_iterator client = clients.begin();
 //	std::map<int, shared_ptr<LyXDataSocket> >::const_iterator end = clients.end();
Index: src/lyxsocket.h
===================================================================
--- src/lyxsocket.h	(Revision 17746)
+++ src/lyxsocket.h	(Arbeitskopie)
@@ -14,6 +14,7 @@
 #ifndef LYXSOCKET_H
 #define LYXSOCKET_H
 
+#include "support/filename.h"
 #include "support/socktools.h"
 #include "lyxfunc.h"
 
@@ -41,11 +42,11 @@ class LyXDataSocket;
 class LyXServerSocket {
 public:
 	///
-	LyXServerSocket(LyXFunc *, std::string const &);
+	LyXServerSocket(LyXFunc *, support::FileName const &);
 	///
 	~LyXServerSocket();
 	/// Address of the local socket
-	std::string const & address() const;
+	std::string const address() const;
 	/// To be called when there is activity in the server socket
 	void serverCallback();
 	/// To be called when there is activity in the data socket
@@ -58,7 +59,7 @@ private:
 	/// File descriptor for the server socket
 	int fd_;
 	/// Stores the socket filename
-	std::string address_;
+	support::FileName address_;
 	/// Maximum number of simultaneous clients
 	enum {
 		MAX_CLIENTS = 10
Index: src/support/socktools.h
===================================================================
--- src/support/socktools.h	(Revision 17746)
+++ src/support/socktools.h	(Arbeitskopie)
@@ -12,13 +12,14 @@
 #ifndef SOCKTOOLS_H
 #define SOCKTOOLS_H
 
-#include <string>
-
 namespace lyx {
 namespace support {
+
+class FileName;
+
 namespace socktools {
 
-int listen(std::string const &, int);
+int listen(FileName const &, int);
 int accept(int);
 
 } // namespace socktools
Index: src/support/tempname.C
===================================================================
--- src/support/tempname.C	(Revision 17746)
+++ src/support/tempname.C	(Arbeitskopie)
@@ -100,7 +100,7 @@ FileName const tempName(FileName const &
 
 	int const tmpf = make_tempfile(tmpl.get());
 	if (tmpf != -1) {
-		string const t(tmpl.get());
+		string const t(to_utf8(from_filesystem8bit(tmpl.get())));
 #if defined (HAVE_CLOSE)
 		::close(tmpf);
 #elif defined (HAVE__CLOSE)
Index: src/support/socktools.C
===================================================================
--- src/support/socktools.C	(Revision 17746)
+++ src/support/socktools.C	(Arbeitskopie)
@@ -20,7 +20,7 @@ namespace lyx {
 namespace support {
 namespace socktools {
 
-int listen(std::string const &, int)
+int listen(FileName const &, int)
 {
 	return -1;
 }
@@ -72,22 +72,23 @@ namespace socktools {
 // of error). The first argument is the socket address, the second
 // is the length of the queue for connections. If successful, a socket
 // special file 'name' will be created in the filesystem.
-int listen(string const & name, int queue)
+int listen(FileName const & name, int queue)
 {
 	int fd; // File descriptor for the socket
 	sockaddr_un addr; // Structure that hold the socket address
 
-	// We use 'name' to fill 'addr'
-	string::size_type len = name.size();
+	// We use 'localname' to fill 'addr'
+	string const localname = name.toFilesystemEncoding();
+	string::size_type len = localname.size();
 	// the field sun_path in sockaddr_un is a char[108]
 	if (len > 107) {
-		lyxerr << "lyx: Socket address '" << name << "' too long."
+		lyxerr << "lyx: Socket address '" << name.absFilename() << "' too long."
 		       << endl;
 		return -1;
 	}
 	// Synonims for AF_UNIX are AF_LOCAL and AF_FILE
 	addr.sun_family = AF_UNIX;
-	name.copy(addr.sun_path, 107);
+	localname.copy(addr.sun_path, 107);
 	addr.sun_path[len] = '\0';
 
 	// This creates a file descriptor for the socket
@@ -112,10 +113,10 @@ int listen(string const & name, int queu
 	// the socket special file in the filesystem. bind() returns -1
 	// in case of error
 	if ((::bind (fd, reinterpret_cast<sockaddr *>(&addr), SUN_LEN(&addr))) == -1) {
-		lyxerr << "lyx: Could not bind address '" << name
+		lyxerr << "lyx: Could not bind address '" << name.absFilename()
 		       << "' to socket descriptor: " << strerror(errno) << endl;
 		::close(fd);
-		unlink(FileName(name));
+		unlink(name);
 		return -1;
 	}
 
@@ -128,7 +129,7 @@ int listen(string const & name, int queu
 		lyxerr << "lyx: Could not put socket in 'listen' state: "
 		       << strerror(errno) << endl;
 		::close(fd);
-		unlink(FileName(name));
+		unlink(name);
 		return -1;
 	}
 
Index: src/client/client.C
===================================================================
--- src/client/client.C	(Revision 17746)
+++ src/client/client.C	(Arbeitskopie)
@@ -13,6 +13,7 @@
 #include <config.h>
 
 #include "debug.h"
+#include "support/filename.h"
 #include "support/unicode.h"
 #include "support/lstrings.h"
 
@@ -57,7 +58,8 @@
 
 namespace lyx {
 
-using lyx::support::prefixIs;
+using support::FileName;
+using support::prefixIs;
 
 using boost::scoped_ptr;
 namespace fs = boost::filesystem;
@@ -113,14 +115,14 @@ namespace socktools {
 
 
 /// Connect to the socket \p name.
-/// Caution: \p name is in filesystem encoding
-int connect(string const & name)
+int connect(FileName const & name)
 {
 	int fd; // File descriptor for the socket
 	sockaddr_un addr; // Structure that hold the socket address
 
+	string const encoded = name.toFilesystemEncoding();
 	// char sun_path[108]
-	string::size_type len = name.size();
+	string::size_type len = encoded.size();
 	if (len > 107) {
 		cerr << "lyxclient: Socket address '" << name
 		     << "' too long." << endl;
@@ -128,7 +130,7 @@ int connect(string const & name)
 	}
 	// Synonims for AF_UNIX are AF_LOCAL and AF_FILE
 	addr.sun_family = AF_UNIX;
-	name.copy(addr.sun_path, 107);
+	encoded.copy(addr.sun_path, 107);
 	addr.sun_path[len] = '\0';
 
 	if ((fd = ::socket(PF_UNIX, SOCK_STREAM, 0))== -1) {
@@ -139,7 +141,7 @@ int connect(string const & name)
 	if (::connect(fd,
 		      reinterpret_cast<struct sockaddr *>(&addr),
 		      sizeof(addr)) == -1) {
-		cerr << "lyxclient: Could not connect to socket " << name
+		cerr << "lyxclient: Could not connect to socket " << name.absFilename()
 		     << ": " << strerror(errno) << endl;
 		::close(fd);
 		return -1;
@@ -221,7 +223,7 @@ bool IOWatch::isset(int fd) {
 // Modified LyXDataSocket class for use with the client
 class LyXDataSocket {
 public:
-	LyXDataSocket(string const &);
+	LyXDataSocket(FileName const &);
 	~LyXDataSocket();
 	// File descriptor of the connection
 	int fd() const;
@@ -241,7 +243,7 @@ private:
 };
 
 
-LyXDataSocket::LyXDataSocket(string const & address)
+LyXDataSocket::LyXDataSocket(FileName const & address)
 {
 	if ((fd_ = support::socktools::connect(address)) == -1) {
 		connected_ = false;
@@ -534,7 +536,7 @@ int main(int argc, char * argv[])
 	scoped_ptr<LyXDataSocket> server;
 
 	if (!cmdline::serverAddress.empty()) {
-		server.reset(new LyXDataSocket(to_utf8(cmdline::serverAddress)));
+		server.reset(new LyXDataSocket(FileName(to_utf8(cmdline::serverAddress))));
 		if (!server->connected()) {
 			cerr << "lyxclient: " << "Could not connect to "
 			     << to_utf8(cmdline::serverAddress) << endl;
@@ -543,12 +545,12 @@ int main(int argc, char * argv[])
 	} else {
 		// We have to look for an address.
 		// serverPid can be empty.
-		vector<fs::path> addrs = support::lyxSockets(to_utf8(cmdline::mainTmp), cmdline::serverPid);
+		vector<fs::path> addrs = support::lyxSockets(to_filesystem8bit(cmdline::mainTmp), cmdline::serverPid);
 		vector<fs::path>::const_iterator addr = addrs.begin();
 		vector<fs::path>::const_iterator end = addrs.end();
 		for (; addr != end; ++addr) {
 			// Caution: addr->string() is in filesystem encoding
-			server.reset(new LyXDataSocket(addr->string()));
+			server.reset(new LyXDataSocket(FileName(to_utf8(from_filesystem8bit(addr->string())))));
 			if (server->connected())
 				break;
 			lyxerr << "lyxclient: " << "Could not connect to "
Index: src/lyx_main.C
===================================================================
--- src/lyx_main.C	(Revision 17746)
+++ src/lyx_main.C	(Arbeitskopie)
@@ -456,7 +456,7 @@ int LyX::exec(int & argc, char * argv[])
 	// such that package().temp_dir() is properly initialized.
 	pimpl_->lyx_server_.reset(new LyXServer(&pimpl_->lyxfunc_, lyxrc.lyxpipes));
 	pimpl_->lyx_socket_.reset(new LyXServerSocket(&pimpl_->lyxfunc_, 
-			package().temp_dir().absFilename() + "/lyxsocket"));
+			FileName(package().temp_dir().absFilename() + "/lyxsocket")));
 
 	// Start the real execution loop.
 	exit_status = pimpl_->application_->exec();

Reply via email to