ioctl() permissions.
authorFlorian Pose <fp@igh-essen.com>
Mon, 09 Jun 2008 10:29:28 +0000
changeset 972 ad59641a68c8
parent 971 d169890332fe
child 973 a560a124a92e
ioctl() permissions.
master/cdev.c
tools/Master.cpp
tools/Master.h
tools/main.cpp
--- a/master/cdev.c	Mon Jun 09 10:27:56 2008 +0000
+++ b/master/cdev.c	Mon Jun 09 10:29:28 2008 +0000
@@ -474,6 +474,8 @@
             }
 
         case EC_IOCTL_SET_DEBUG:
+            if (!(filp->f_mode & FMODE_WRITE))
+                return -EPERM;
             if (ec_master_debug_level(master, (unsigned int) arg)) {
                 retval = -EINVAL;
             }
@@ -484,6 +486,9 @@
                 ec_ioctl_slave_state_t data;
                 ec_slave_t *slave;
 
+                if (!(filp->f_mode & FMODE_WRITE))
+                    return -EPERM;
+
                 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
                     retval = -EFAULT;
                     break;
@@ -680,7 +685,7 @@
             }
 
         default:
-            retval = -ENOIOCTLCMD;
+            retval = -ENOTTY;
     }
 
     return retval;
--- a/tools/Master.cpp	Mon Jun 09 10:27:56 2008 +0000
+++ b/tools/Master.cpp	Mon Jun 09 10:29:28 2008 +0000
@@ -90,6 +90,7 @@
 {
     index = 0;
     fd = -1;
+    currentPermissions = Read;
 }
 
 /****************************************************************************/
@@ -101,36 +102,17 @@
 
 /****************************************************************************/
 
-void Master::open(unsigned int index)
-{
-    stringstream deviceName;
-    
-    Master::index = index;
-
-    deviceName << "/dev/EtherCAT" << index;
-    
-    if ((fd = ::open(deviceName.str().c_str(), O_RDONLY)) == -1) {
-        stringstream err;
-        err << "Failed to open master device " << deviceName.str() << ": "
-            << strerror(errno);
-        throw MasterException(err.str());
-    }
-}
-
-/****************************************************************************/
-
-void Master::close()
-{
-    if (fd == -1)
-        return;
-
-    ::close(fd);
+void Master::setIndex(unsigned int i)
+{
+    index = i;
 }
 
 /****************************************************************************/
 
 void Master::outputData(int domainIndex)
 {
+    open(Read);
+
     if (domainIndex == -1) {
         unsigned int numDomains = domainCount(), i;
 
@@ -164,6 +146,8 @@
         throw MasterException(err.str());
     }
 
+    open(ReadWrite);
+
     if (ioctl(fd, EC_IOCTL_SET_DEBUG, debugLevel) < 0) {
         stringstream err;
         err << "Failed to set debug level: " << strerror(errno);
@@ -175,6 +159,8 @@
 
 void Master::showDomains(int domainIndex)
 {
+    open(Read);
+
     if (domainIndex == -1) {
         unsigned int numDomains = domainCount(), i;
 
@@ -190,10 +176,14 @@
 
 void Master::listSlaves()
 {
-    unsigned int numSlaves = slaveCount(), i;
+    unsigned int numSlaves, i;
     ec_ioctl_slave_t slave;
     uint16_t lastAlias, aliasIndex;
     
+    open(Read);
+
+    numSlaves = slaveCount();
+
     lastAlias = 0;
     aliasIndex = 0;
     for (i = 0; i < numSlaves; i++) {
@@ -229,6 +219,7 @@
     stringstream err;
     unsigned int i;
     
+    open(Read);
     getMaster(&data);
 
     cout
@@ -277,6 +268,8 @@
 
 void Master::listPdos(int slavePosition, bool quiet)
 {
+    open(Read);
+
     if (slavePosition == -1) {
         unsigned int numSlaves = slaveCount(), i;
 
@@ -292,6 +285,8 @@
 
 void Master::listSdos(int slavePosition, bool quiet)
 {
+    open(Read);
+
     if (slavePosition == -1) {
         unsigned int numSlaves = slaveCount(), i;
 
@@ -357,6 +352,9 @@
     } else { // no data type specified: fetch from dictionary
         ec_ioctl_sdo_entry_t entry;
         unsigned int entryByteSize;
+
+        open(Read);
+
         try {
             getSdoEntry(&entry, slavePosition,
                     data.sdo_index, data.sdo_entry_subindex);
@@ -383,12 +381,17 @@
 
     data.target = new uint8_t[data.target_size + 1];
 
+    open(Read);
+
     if (ioctl(fd, EC_IOCTL_SDO_UPLOAD, &data) < 0) {
         stringstream err;
         err << "Failed to upload Sdo: " << strerror(errno);
         delete [] data.target;
-        throw MasterException(err.str());
-    }
+        close();
+        throw MasterException(err.str());
+    }
+
+    close();
 
     if (dataType->byteSize && data.data_size != dataType->byteSize) {
         stringstream err;
@@ -470,6 +473,8 @@
         throw MasterException(err.str());
     }
 
+    open(ReadWrite);
+
     if (slavePosition == -1) {
         unsigned int i, numSlaves = slaveCount();
         for (i = 0; i < numSlaves; i++)
@@ -483,6 +488,8 @@
 
 void Master::generateXml(int slavePosition)
 {
+    open(Read);
+
     if (slavePosition == -1) {
         unsigned int numSlaves = slaveCount(), i;
 
@@ -496,6 +503,43 @@
 
 /****************************************************************************/
 
+void Master::open(Permissions perm)
+{
+    stringstream deviceName;
+
+    if (fd != -1) { // already open
+        if (currentPermissions < perm) { // more permissions required
+            close();
+        } else {
+            return;
+        }
+    }
+    
+    deviceName << "/dev/EtherCAT" << index;
+    
+    if ((fd = ::open(deviceName.str().c_str(),
+                    perm == ReadWrite ? O_RDWR : O_RDONLY)) == -1) {
+        stringstream err;
+        err << "Failed to open master device " << deviceName.str() << ": "
+            << strerror(errno);
+        throw MasterException(err.str());
+    }
+
+    currentPermissions = perm;
+}
+
+/****************************************************************************/
+
+void Master::close()
+{
+    if (fd == -1)
+        return;
+
+    ::close(fd);
+}
+
+/****************************************************************************/
+
 void Master::outputDomainData(unsigned int domainIndex)
 {
     ec_ioctl_domain_t domain;
--- a/tools/Master.h	Mon Jun 09 10:27:56 2008 +0000
+++ b/tools/Master.h	Mon Jun 09 10:29:28 2008 +0000
@@ -39,8 +39,7 @@
         Master();
         ~Master();
 
-        void open(unsigned int);
-        void close();
+        void setIndex(unsigned int);
 
         void outputData(int);
         void setDebug(const vector<string> &);
@@ -54,6 +53,10 @@
         void generateXml(int);
 
     protected:
+        enum Permissions {Read, ReadWrite};
+        void open(Permissions);
+        void close();
+
         void outputDomainData(unsigned int);
         void showDomain(unsigned int);
         void listSlavePdos(uint16_t, bool = false, bool = false);
@@ -84,6 +87,7 @@
 
         unsigned int index;
         int fd;
+        Permissions currentPermissions;
 };
 
 /****************************************************************************/
--- a/tools/main.cpp	Mon Jun 09 10:27:56 2008 +0000
+++ b/tools/main.cpp	Mon Jun 09 10:29:28 2008 +0000
@@ -162,7 +162,7 @@
 	getOptions(argc, argv);
 
     try {
-        master.open(masterIndex);
+        master.setIndex(masterIndex);
 
         if (command == "data") {
             master.outputData(domainIndex);