From b19cf629308a54fc2d6eb4e07798485c3330a0f4 Mon Sep 17 00:00:00 2001
From: dpgilbert <dpgilbert@4ea69e1a-61f1-4043-bf83-b5c94c648137>
Date: Wed, 26 Nov 2003 10:37:00 +0000
Subject: [PATCH] Revert to O_RDONLY when O_RDWR fails patch [Maciej W.
 Rozycki]

git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@1294 4ea69e1a-61f1-4043-bf83-b5c94c648137
---
 sm5/os_linux.c   | 10 +++++++---
 sm5/os_linux.cpp | 10 +++++++---
 sm5/smartctl.c   |  8 +++++---
 sm5/smartctl.cpp |  8 +++++---
 4 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/sm5/os_linux.c b/sm5/os_linux.c
index 82cdd13e8..cd340d78d 100644
--- a/sm5/os_linux.c
+++ b/sm5/os_linux.c
@@ -60,7 +60,7 @@
 #include "smartd.h"
 #include "utility.h"
 
-const char *os_XXXX_c_cvsid="$Id: os_linux.c,v 1.30 2003/11/26 05:57:46 ballen4705 Exp $" \
+const char *os_XXXX_c_cvsid="$Id: os_linux.c,v 1.31 2003/11/26 10:34:29 dpgilbert Exp $" \
 ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID;
 
 // to hold onto exit code for atexit routine
@@ -73,8 +73,12 @@ void *FreeNonZero(void* address, int size,int whatline,char* file);
 
 // equivalent to open(path, flags)
 int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) 
-    return open(pathname, O_RDWR | O_NONBLOCK);
+  if (!strcmp(type,"SCSI")) {
+    int fd = open(pathname, O_RDWR | O_NONBLOCK);
+    if (fd < 0 && errno == EROFS)
+      fd = open(pathname, O_RDONLY | O_NONBLOCK);
+    return fd;
+  }
   else if (!strcmp(type,"ATA")) 
     return open(pathname, O_RDONLY | O_NONBLOCK);
   else
diff --git a/sm5/os_linux.cpp b/sm5/os_linux.cpp
index cc9c0ab01..4b38bfabf 100644
--- a/sm5/os_linux.cpp
+++ b/sm5/os_linux.cpp
@@ -60,7 +60,7 @@
 #include "smartd.h"
 #include "utility.h"
 
-const char *os_XXXX_c_cvsid="$Id: os_linux.cpp,v 1.30 2003/11/26 05:57:46 ballen4705 Exp $" \
+const char *os_XXXX_c_cvsid="$Id: os_linux.cpp,v 1.31 2003/11/26 10:34:29 dpgilbert Exp $" \
 ATACMDS_H_CVSID CONFIG_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID;
 
 // to hold onto exit code for atexit routine
@@ -73,8 +73,12 @@ void *FreeNonZero(void* address, int size,int whatline,char* file);
 
 // equivalent to open(path, flags)
 int deviceopen(const char *pathname, char *type){
-  if (!strcmp(type,"SCSI")) 
-    return open(pathname, O_RDWR | O_NONBLOCK);
+  if (!strcmp(type,"SCSI")) {
+    int fd = open(pathname, O_RDWR | O_NONBLOCK);
+    if (fd < 0 && errno == EROFS)
+      fd = open(pathname, O_RDONLY | O_NONBLOCK);
+    return fd;
+  }
   else if (!strcmp(type,"ATA")) 
     return open(pathname, O_RDONLY | O_NONBLOCK);
   else
diff --git a/sm5/smartctl.c b/sm5/smartctl.c
index e80e9f494..30168fc4c 100644
--- a/sm5/smartctl.c
+++ b/sm5/smartctl.c
@@ -43,7 +43,7 @@
 #include "utility.h"
 
 extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid; 
-const char* smartctl_c_cvsid="$Id: smartctl.c,v 1.105 2003/11/16 16:59:23 ballen4705 Exp $"
+const char* smartctl_c_cvsid="$Id: smartctl.c,v 1.106 2003/11/26 10:37:00 dpgilbert Exp $"
 ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
 
 // This is a block containing all the "control variables".  We declare
@@ -820,9 +820,11 @@ int main (int argc, char **argv){
     mode="ATA";
     
   // open device - SCSI devices are opened (O_RDWR | O_NONBLOCK) so the
-  // scsi generci device can be used (needs write permission for MODE 
+  // scsi generic device can be used (needs write permission for MODE 
   // SELECT command) plus O_NONBLOCK to stop open hanging if media not
-  // present (e.g. with st). 
+  // present (e.g. with st).  Opening is retried O_RDONLY if read-only
+  // media prevents opening O_RDWR (it cannot happen for scsi generic
+  // devices, but it can for the others).
   fd = deviceopen(device, mode);
   if (fd<0) {
     char errmsg[256];
diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp
index 6ccf0a168..82466cbf4 100644
--- a/sm5/smartctl.cpp
+++ b/sm5/smartctl.cpp
@@ -43,7 +43,7 @@
 #include "utility.h"
 
 extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid; 
-const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.105 2003/11/16 16:59:23 ballen4705 Exp $"
+const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.106 2003/11/26 10:37:00 dpgilbert Exp $"
 ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
 
 // This is a block containing all the "control variables".  We declare
@@ -820,9 +820,11 @@ int main (int argc, char **argv){
     mode="ATA";
     
   // open device - SCSI devices are opened (O_RDWR | O_NONBLOCK) so the
-  // scsi generci device can be used (needs write permission for MODE 
+  // scsi generic device can be used (needs write permission for MODE 
   // SELECT command) plus O_NONBLOCK to stop open hanging if media not
-  // present (e.g. with st). 
+  // present (e.g. with st).  Opening is retried O_RDONLY if read-only
+  // media prevents opening O_RDWR (it cannot happen for scsi generic
+  // devices, but it can for the others).
   fd = deviceopen(device, mode);
   if (fd<0) {
     char errmsg[256];
-- 
GitLab