From bc333ea2ef6941b4023ceccd47f44be7104799ad Mon Sep 17 00:00:00 2001 From: Philippe Houdoin Date: Tue, 8 Jun 2004 22:59:21 +0000 Subject: [PATCH] Fix a thread safety issue in "USB Port" transport. Now all transports okok'ed the received init message on success. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7867 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../hp_jetdirect/print_transport.cpp | 3 +- src/add-ons/print/transports/ipp/Ipp.cpp | 65 ++++++++++--------- src/add-ons/print/transports/lpr/Lpr.cpp | 65 ++++++++++--------- .../parallel_port/print_transport.cpp | 25 ++++++- .../print_to_file/print_transport.cpp | 11 ++-- .../serial_port/print_transport.cpp | 21 +++++- .../transports/usb_port/print_transport.cpp | 14 ++-- 7 files changed, 129 insertions(+), 75 deletions(-) diff --git a/src/add-ons/print/transports/hp_jetdirect/print_transport.cpp b/src/add-ons/print/transports/hp_jetdirect/print_transport.cpp index 0941b8d9f4..87ed0fbf94 100644 --- a/src/add-ons/print/transports/hp_jetdirect/print_transport.cpp +++ b/src/add-ons/print/transports/hp_jetdirect/print_transport.cpp @@ -57,7 +57,8 @@ extern "C" _EXPORT BDataIO * init_transport(BMessage *msg) if (transport->Ready()) { g_transport = transport; - msg->what = 'okok'; + if (msg) + msg->what = 'okok'; return g_transport; }; diff --git a/src/add-ons/print/transports/ipp/Ipp.cpp b/src/add-ons/print/transports/ipp/Ipp.cpp index a992716a06..9f487555ff 100644 --- a/src/add-ons/print/transports/ipp/Ipp.cpp +++ b/src/add-ons/print/transports/ipp/Ipp.cpp @@ -1,31 +1,34 @@ -// Sun, 18 Jun 2000 -// Y.Takagi - -#include "IppTransport.h" -#include "DbgMsg.h" - -IppTransport *transport = NULL; - -extern "C" _EXPORT void exit_transport() -{ - DBGMSG(("> exit_transport\n")); - if (transport) { - delete transport; - transport = NULL; - } - DBGMSG(("< exit_transport\n")); -} - -extern "C" _EXPORT BDataIO *init_transport(BMessage *msg) -{ - DBGMSG(("> init_transport\n")); - - transport = new IppTransport(msg); - - if (transport->fail()) { - exit_transport(); - } - - DBGMSG(("< init_transport\n")); - return transport; -} +// Sun, 18 Jun 2000 +// Y.Takagi + +#include "IppTransport.h" +#include "DbgMsg.h" + +IppTransport *transport = NULL; + +extern "C" _EXPORT void exit_transport() +{ + DBGMSG(("> exit_transport\n")); + if (transport) { + delete transport; + transport = NULL; + } + DBGMSG(("< exit_transport\n")); +} + +extern "C" _EXPORT BDataIO *init_transport(BMessage *msg) +{ + DBGMSG(("> init_transport\n")); + + transport = new IppTransport(msg); + + if (transport->fail()) { + exit_transport(); + } + + if (msg) + msg->what = 'okok'; + + DBGMSG(("< init_transport\n")); + return transport; +} diff --git a/src/add-ons/print/transports/lpr/Lpr.cpp b/src/add-ons/print/transports/lpr/Lpr.cpp index dfee68360c..e85b830f1c 100644 --- a/src/add-ons/print/transports/lpr/Lpr.cpp +++ b/src/add-ons/print/transports/lpr/Lpr.cpp @@ -1,31 +1,34 @@ -// Sun, 18 Jun 2000 -// Y.Takagi - -#include "LprTransport.h" -#include "DbgMsg.h" - -LprTransport *transport = NULL; - -extern "C" _EXPORT void exit_transport() -{ - DBGMSG(("> exit_transport\n")); - if (transport) { - delete transport; - transport = NULL; - } - DBGMSG(("< exit_transport\n")); -} - -extern "C" _EXPORT BDataIO *init_transport(BMessage *msg) -{ - DBGMSG(("> init_transport\n")); - - transport = new LprTransport(msg); - - if (transport->fail()) { - exit_transport(); - } - - DBGMSG(("< init_transport\n")); - return transport; -} +// Sun, 18 Jun 2000 +// Y.Takagi + +#include "LprTransport.h" +#include "DbgMsg.h" + +LprTransport *transport = NULL; + +extern "C" _EXPORT void exit_transport() +{ + DBGMSG(("> exit_transport\n")); + if (transport) { + delete transport; + transport = NULL; + } + DBGMSG(("< exit_transport\n")); +} + +extern "C" _EXPORT BDataIO *init_transport(BMessage *msg) +{ + DBGMSG(("> init_transport\n")); + + transport = new LprTransport(msg); + + if (transport->fail()) { + exit_transport(); + } + + if (msg) + msg->what = 'okok'; + + DBGMSG(("< init_transport\n")); + return transport; +} diff --git a/src/add-ons/print/transports/parallel_port/print_transport.cpp b/src/add-ons/print/transports/parallel_port/print_transport.cpp index a76b0b9f52..9b3df9ecac 100644 --- a/src/add-ons/print/transports/parallel_port/print_transport.cpp +++ b/src/add-ons/print/transports/parallel_port/print_transport.cpp @@ -56,18 +56,35 @@ ParallelPort::ParallelPort(BDirectory* printer, BMessage* msg) { char address[80]; char device[B_PATH_NAME_LENGTH]; - - int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address)); + bool bidirectional = true; + + unsigned int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address)); if (size <= 0 || size >= sizeof(address)) return; address[size] = 0; // make sure string is 0-terminated strcat(strcpy(device, "/dev/parallel/"), address); fFile = open(device, O_RDWR | O_EXCL | O_BINARY, 0); + if (fFile < 0) { + // Try unidirectional access mode + bidirectional = false; + fFile = open(device, O_WRONLY | O_EXCL | O_BINARY, 0); + } + + if (fFile < 0) + return; + + if (! msg) + // Caller don't care about transport init message output content... + return; + + msg->AddBool("bidirectional", bidirectional); + msg->AddString("_parallel/DeviceName", device); } ParallelPort::~ParallelPort() { if (InitCheck() == B_OK) { - close(fFile); fFile = -1; + close(fFile); + fFile = -1; } } @@ -82,6 +99,8 @@ ssize_t ParallelPort::Write(const void* buffer, size_t size) { BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) { ParallelPort* transport = new ParallelPort(printer, msg); if (transport->InitCheck() == B_OK) { + if (msg) + msg->what = 'okok'; return transport; } else { delete transport; return NULL; diff --git a/src/add-ons/print/transports/print_to_file/print_transport.cpp b/src/add-ons/print/transports/print_to_file/print_transport.cpp index 1a20f08ea2..404939258c 100644 --- a/src/add-ons/print/transports/print_to_file/print_transport.cpp +++ b/src/add-ons/print/transports/print_to_file/print_transport.cpp @@ -65,7 +65,8 @@ extern "C" _EXPORT BDataIO * init_transport file = new BFile(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); if ( file->InitCheck() != B_OK ) { - msg->what = 'canc'; // Indicates user cancel the panel... + if (msg) + msg->what = 'canc'; // Indicates user cancel the panel... delete file; return NULL; }; @@ -75,9 +76,11 @@ extern "C" _EXPORT BDataIO * init_transport BPath path; path.SetTo(&ref); - // Print transport add-ons should set to 'okok' the message on success - msg->what = 'okok'; - msg->AddString("path", path.Path()); // Add path of new choosen file to transport message + if (msg) { + // Print transport add-ons should set to 'okok' the message on success + msg->what = 'okok'; + msg->AddString("path", path.Path()); // Add path of new choosen file to transport message + } return file; } diff --git a/src/add-ons/print/transports/serial_port/print_transport.cpp b/src/add-ons/print/transports/serial_port/print_transport.cpp index d14dac58ac..9d52d89dae 100644 --- a/src/add-ons/print/transports/serial_port/print_transport.cpp +++ b/src/add-ons/print/transports/serial_port/print_transport.cpp @@ -56,13 +56,30 @@ SerialPort::SerialPort(BDirectory* printer, BMessage* msg) { char address[80]; char device[B_PATH_NAME_LENGTH]; + bool bidirectional = true; - int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address)); + unsigned int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address)); if (size <= 0 || size >= sizeof(address)) return; address[size] = 0; // make sure string is 0-terminated strcat(strcpy(device, "/dev/ports/"), address); fFile = open(device, O_RDWR | O_EXCL | O_BINARY, 0); + if (fFile < 0) { + // Try unidirectional access mode + bidirectional = false; + fFile = open(device, O_WRONLY | O_EXCL | O_BINARY, 0); + } + + if (fFile < 0) + return; + + if (! msg) + // Caller don't care about transport init message output content... + return; + + msg->AddBool("bidirectional", bidirectional); + msg->AddString("_serial/DeviceName", device); + } SerialPort::~SerialPort() { @@ -82,6 +99,8 @@ ssize_t SerialPort::Write(const void* buffer, size_t size) { BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) { SerialPort* transport = new SerialPort(printer, msg); if (transport->InitCheck() == B_OK) { + if (msg) + msg->what = 'okok'; return transport; } else { delete transport; return NULL; diff --git a/src/add-ons/print/transports/usb_port/print_transport.cpp b/src/add-ons/print/transports/usb_port/print_transport.cpp index 4a432533cf..a442086a0e 100644 --- a/src/add-ons/print/transports/usb_port/print_transport.cpp +++ b/src/add-ons/print/transports/usb_port/print_transport.cpp @@ -65,7 +65,8 @@ class UsbPort : public BDataIO { BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) { UsbPort* transport = new UsbPort(printer, msg); if (transport->IsOk()) { - msg->what = 'okok'; + if (msg) + msg->what = 'okok'; return transport; } else { delete transport; return NULL; @@ -84,6 +85,7 @@ UsbPort::UsbPort(BDirectory* printer, BMessage *msg) char *value; int ret; bool bidirectional = true; + char *next_token; // We support only one USB printer, so does BeOS R5. fFile = open("/dev/printer/usb/0", O_RDWR | O_EXCL | O_BINARY, 0); @@ -104,21 +106,25 @@ UsbPort::UsbPort(BDirectory* printer, BMessage *msg) return; } + if (! msg) + // Caller don't care about transport init message output content... + return; + // Fill up the message msg->AddBool("bidirectional", bidirectional); msg->AddString("device_id", device_id); // parse and split the device_id string into separate parameters - desc = strtok(device_id, ":"); + desc = strtok_r(device_id, ":", &next_token); while (desc) { snprintf(name, sizeof(name), "DEVID:%s", desc); - value = strtok(NULL, ";"); + value = strtok_r(NULL, ";", &next_token); if (!value) break; msg->AddString(name, value); // next device descriptor - desc = strtok(NULL, ":"); + desc = strtok_r(NULL, ":", &next_token); } }