FU Logo
  • Startseite
  • Kontakt
  • Impressum
  • Home
  • Listenauswahl
  • Anleitungen

Re: [linux-minidisc] another way to send SCSI commands

<-- thread -->
<-- date -->
  • From: Michael Karcher <Michael.Karcher@fu-berlin.de>
  • To: Thomas Arp <manner.moe@gmx.de>
  • Date: Sat, 04 Dec 2010 18:23:41 +0100
  • Cc: appro@fy.chalmers.se, linux-minidisc@lists.fu-berlin.de
  • Subject: Re: [linux-minidisc] another way to send SCSI commands

[Cc to the dvd+rw-tools again, as another patch is attached. BTW: Thanks
for that lean code for that many OSsed!
Andy: Please do not misunderstand this mail as trying to make your code
look bad, even if I claim you violated some coding standard. I really
appreciate your work, and the code you have written shows no problems if
used correctly - it's just about prevention of abuse. This is of course
something one doesn't have in mind if one writes a SCSI transfer toolkit
for a single application instead of a general library. It's at least
partly our "fault" to take code out of dvd+rw-tools and use it
carelessly making our applications break.]

Am Samstag, den 04.12.2010, 14:33 +0100 schrieb Thomas Arp:
> I´m rewriting himdscsitest.c using the dvd-rw-tools headers for
> testing.
That's great!
> As far as i have tested yet when cmd.transport() has finished the
> Scsi_Command structure will be closed automatically.
As far as I can see, this is neither the case for Windows nor for Linux.
Can you point out the code you think it closes the file descriptor? I
see closing only in the destructor of Scsi_Command, so the device is
closed only when the Scsi_Command structure goes out of scope.

But I *do* see a potential problem that causes early closes: The
Scsi_Command structure must never be copied, as it violates the C++
"rule of three":
 http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29
"must never be copied" is *not* talking about DRM here (SCNR), but means
that you can not pass a "Scsi_Command" as value to a subfunction,
because pass-by-value copies the data (and that includes the handle) to
local storage of the subfunction, and if that subfunction terminates,
the local copy is destructed, closing the handle, although the object it
was copied from in the caller still is alive. Also hell will break loose
(i.e. you will get early closed fds/double-closed fds/leaked fds) if you
assign one Scsi_Command object to another one. So do only pass the
Scsi_Command structure by reference or pointer!

> Should we disable this autoclose feature and use genaral open and
> close commands instead or should every send-command function have it´s
> own Scsi_Command structure, so that we only need to give the
> devicename as parameter instead of a Scsi_Command structure?
Of course we don't want an autoclose feature, but I am very confident
that what you observed was caused by copying Scsi_Command objects and
using the object as intended wouldn't cause problems. I attach a patch
to this mail that explicitly prohibits copying and assigment of
Scsi_Command objects, so with the patched transport.hxx your program
should fail to compile if it contains the problem I suppose.

> Thomas
Regards,
  Michael Karcher

PS: Don't worry about Qt widget/dialog box classes you write violating
the rule-of-three the same way. QObject itself is noncopyable (by
defining an inaccessible copy-assignment operator and copy-constructor),
so there already is an inherited user-defined copy constructor and
assignment operator preventing problems. Cleanup in a destructor doesn't
matter in this case.

PS2: Of course "Scsi_Command_Is_Noncopyable" is reinventing the wheel.
Boost already has boost::noncopyable and Qt has Q_DISABLY_COPY (although
just for internal use) and thousands of other people wrote these 6 lines
of code, too. But I don't want to pull boost into transport.hxx, as
everyone who needed to install boost on Windows systems surely can
understand. If our project already used boost, it would be a different
story, of course.
--- ../dvd+rw-tools-7.1/transport.hxx	2010-12-03 02:56:36.000000000 +0100
+++ transport.hxx	2010-12-04 18:17:57.000000000 +0100
@@ -136,6 +136,14 @@
 
   return plusminus;
 }
+
+class Scsi_Command_Is_Noncopyable {
+    /* declare a private copy constructor and assignment operator */
+    Scsi_Command_Is_Noncopyable(const Scsi_Command_Is_Noncopyable &);
+    Scsi_Command_Is_Noncopyable &operator=(const Scsi_Command_Is_Noncopyable &);
+public:
+    Scsi_Command_Is_Noncopyable() {}
+};
 	
 #if defined(__linux)
 
@@ -205,7 +213,7 @@
 { return rsm_open_device.f!=open; }
 #endif
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     int fd,autoclose;
     char *filename;
@@ -389,7 +397,7 @@
 		WRITE=SCCMD_WRITE
 	     } Direction;
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     int fd,autoclose;
     char *filename;
@@ -510,7 +518,7 @@
 		WRITE=CAM_DIR_OUT
 	     } Direction;
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     int fd,autoclose;
     char *filename;
@@ -701,7 +709,7 @@
 		WRITE=USCSI_WRITE
 	     } Direction;
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     int fd,autoclose;
     char *filename;
@@ -920,7 +928,7 @@
                 WRITE=0
              } Direction;
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     int fd;
     int autoclose;
@@ -1077,7 +1085,7 @@
 		WRITE=DSRQ_WRITE
 	     } Direction;
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     int fd,autoclose;
     char *filename;
@@ -1277,7 +1285,7 @@
     unsigned char		sense[18];
 } SPKG;
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     HANDLE fd;
     int    autoclose;
@@ -1449,7 +1457,7 @@
 		WRITE=kSCSIDataTransfer_FromInitiatorToTarget
 	     } Direction;
 
-class Scsi_Command {
+class Scsi_Command : public Scsi_Command_Is_Noncopyable {
 private:
     int				autoclose,_timeout;
     char			*filename;
<-- thread -->
<-- date -->
  • References:
    • Re: [linux-minidisc] another way to send SCSI commands
      • From: "Thomas Arp" <manner.moe@gmx.de>
  • linux-minidisc - December 2010 - Archives indexes sorted by:
    [ thread ] [ subject ] [ author ] [ date ]
  • Complete archive of the linux-minidisc mailing list
  • More info on this list...

Hilfe

  • FAQ
  • Dienstbeschreibung
  • ZEDAT Beratung
  • postmaster@lists.fu-berlin.de

Service-Navigation

  • Startseite
  • Listenauswahl

Einrichtung Mailingliste

  • ZEDAT-Portal
  • Mailinglisten Portal