ioctl() permissions.
--- 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);