# HG changeset patch # User Florian Pose # Date 1213007368 0 # Node ID ad59641a68c8af8da4143181495fd29ff8de1ad7 # Parent d169890332fe5da611684d84eb68810ecc74cb1b ioctl() permissions. diff -r d169890332fe -r ad59641a68c8 master/cdev.c --- 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; diff -r d169890332fe -r ad59641a68c8 tools/Master.cpp --- 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; diff -r d169890332fe -r ad59641a68c8 tools/Master.h --- 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 &); @@ -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; }; /****************************************************************************/ diff -r d169890332fe -r ad59641a68c8 tools/main.cpp --- 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);