From 86ea4b4504fe6f019a34747896e853e0903be3c9 Mon Sep 17 00:00:00 2001 From: Florian Pose <fp@igh-essen.com> Date: Mon, 9 Jun 2008 10:29:28 +0000 Subject: [PATCH] ioctl() permissions. --- master/cdev.c | 7 +++- tools/Master.cpp | 92 +++++++++++++++++++++++++++++++++++------------- tools/Master.h | 8 +++-- tools/main.cpp | 2 +- 4 files changed, 81 insertions(+), 28 deletions(-) diff --git a/master/cdev.c b/master/cdev.c index f91781ae..006e29b5 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -474,6 +474,8 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } 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 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 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 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } default: - retval = -ENOIOCTLCMD; + retval = -ENOTTY; } return retval; diff --git a/tools/Master.cpp b/tools/Master.cpp index 42998794..45413ff6 100644 --- a/tools/Master.cpp +++ b/tools/Master.cpp @@ -90,6 +90,7 @@ Master::Master() { index = 0; fd = -1; + currentPermissions = Read; } /****************************************************************************/ @@ -101,36 +102,17 @@ Master::~Master() /****************************************************************************/ -void Master::open(unsigned int index) +void Master::setIndex(unsigned int i) { - 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); + index = i; } /****************************************************************************/ void Master::outputData(int domainIndex) { + open(Read); + if (domainIndex == -1) { unsigned int numDomains = domainCount(), i; @@ -164,6 +146,8 @@ void Master::setDebug(const vector<string> &commandArgs) 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::setDebug(const vector<string> &commandArgs) void Master::showDomains(int domainIndex) { + open(Read); + if (domainIndex == -1) { unsigned int numDomains = domainCount(), i; @@ -190,10 +176,14 @@ void Master::showDomains(int domainIndex) 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 @@ void Master::showMaster() stringstream err; unsigned int i; + open(Read); getMaster(&data); cout @@ -277,6 +268,8 @@ void Master::showMaster() void Master::listPdos(int slavePosition, bool quiet) { + open(Read); + if (slavePosition == -1) { unsigned int numSlaves = slaveCount(), i; @@ -292,6 +285,8 @@ void Master::listPdos(int slavePosition, bool quiet) void Master::listSdos(int slavePosition, bool quiet) { + open(Read); + if (slavePosition == -1) { unsigned int numSlaves = slaveCount(), i; @@ -357,6 +352,9 @@ void Master::sdoUpload( } 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,13 +381,18 @@ void Master::sdoUpload( 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; + close(); throw MasterException(err.str()); } + close(); + if (dataType->byteSize && data.data_size != dataType->byteSize) { stringstream err; err << "Data type mismatch. Expected " << dataType->name @@ -470,6 +473,8 @@ void Master::requestStates( 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::requestStates( void Master::generateXml(int slavePosition) { + open(Read); + if (slavePosition == -1) { unsigned int numSlaves = slaveCount(), i; @@ -496,6 +503,43 @@ void Master::generateXml(int slavePosition) /****************************************************************************/ +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 --git a/tools/Master.h b/tools/Master.h index 808cae4b..f96db21d 100644 --- a/tools/Master.h +++ b/tools/Master.h @@ -39,8 +39,7 @@ class Master Master(); ~Master(); - void open(unsigned int); - void close(); + void setIndex(unsigned int); void outputData(int); void setDebug(const vector<string> &); @@ -54,6 +53,10 @@ class Master 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 @@ class Master unsigned int index; int fd; + Permissions currentPermissions; }; /****************************************************************************/ diff --git a/tools/main.cpp b/tools/main.cpp index 1b8b7a9c..fc5e820b 100644 --- a/tools/main.cpp +++ b/tools/main.cpp @@ -162,7 +162,7 @@ int main(int argc, char **argv) getOptions(argc, argv); try { - master.open(masterIndex); + master.setIndex(masterIndex); if (command == "data") { master.outputData(domainIndex); -- GitLab