Added 'pdos' command to ethercat tool.
--- a/master/cdev.c Mon Jun 02 10:49:44 2008 +0000
+++ b/master/cdev.c Mon Jun 02 10:51:31 2008 +0000
@@ -52,15 +52,15 @@
int eccdev_release(struct inode *, struct file *);
ssize_t eccdev_read(struct file *, char __user *, size_t, loff_t *);
ssize_t eccdev_write(struct file *, const char __user *, size_t, loff_t *);
-int eccdev_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+long eccdev_ioctl(struct file *, unsigned int, unsigned long);
/*****************************************************************************/
static struct file_operations eccdev_fops = {
- .owner = THIS_MODULE,
- .open = eccdev_open,
- .release = eccdev_release,
- .ioctl = eccdev_ioctl
+ .owner = THIS_MODULE,
+ .open = eccdev_open,
+ .release = eccdev_release,
+ .unlocked_ioctl = eccdev_ioctl
};
/** \endcond */
@@ -107,9 +107,11 @@
int eccdev_open(struct inode *inode, struct file *filp)
{
ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
+ ec_master_t *master = cdev->master;
filp->private_data = cdev;
- EC_DBG("File opened.\n");
+ if (master->debug_level)
+ EC_DBG("File opened.\n");
return 0;
}
@@ -117,88 +119,237 @@
int eccdev_release(struct inode *inode, struct file *filp)
{
- //ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
-
- EC_DBG("File closed.\n");
+ ec_cdev_t *cdev = (ec_cdev_t *) filp->private_data;
+ ec_master_t *master = cdev->master;
+
+ if (master->debug_level)
+ EC_DBG("File closed.\n");
return 0;
}
/*****************************************************************************/
-int eccdev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- ec_cdev_t *cdev = container_of(inode->i_cdev, ec_cdev_t, cdev);
+long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ ec_cdev_t *cdev = (ec_cdev_t *) filp->private_data;
ec_master_t *master = cdev->master;
+ long retval = 0;
if (master->debug_level)
- EC_DBG("ioctl(inode = %x, filp = %x, cmd = %u, arg = %u)\n",
- (u32) inode, (u32) filp, (u32) cmd, (u32) arg);
-
+ EC_DBG("ioctl(filp = %x, cmd = %u, arg = %u)\n",
+ (u32) filp, (u32) cmd, (u32) arg);
+
+ // FIXME lock
+
switch (cmd) {
case EC_IOCTL_SLAVE_COUNT:
+ retval = master->slave_count;
+ break;
+
+ case EC_IOCTL_SLAVE:
{
- unsigned int slave_count = master->slave_count;
- EC_INFO("EC_IOCTL_SLAVE_COUNT\n");
- if (!arg)
- return -EFAULT;
- if (copy_to_user((void __user *) arg, &slave_count,
- sizeof(unsigned int)))
- return -EFAULT;
- return 0;
+ ec_ioctl_slave_t data;
+ const ec_slave_t *slave;
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (!(slave = ec_master_find_slave(
+ master, 0, data.position))) {
+ EC_ERR("Slave %u does not exist!\n", data.position);
+ retval = -EINVAL;
+ break;
+ }
+
+ data.vendor_id = slave->sii.vendor_id;
+ data.product_code = slave->sii.product_code;
+ data.alias = slave->sii.alias;
+ data.state = slave->current_state;
+
+ data.sync_count = slave->sii.sync_count;
+
+ if (slave->sii.name) {
+ strncpy(data.name, slave->sii.name,
+ EC_IOCTL_SLAVE_NAME_SIZE);
+ data.name[EC_IOCTL_SLAVE_NAME_SIZE - 1] = 0;
+ } else {
+ data.name[0] = 0;
+ }
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ break;
}
- case EC_IOCTL_SLAVE_INFO:
+ case EC_IOCTL_SYNC:
{
- struct ec_ioctl_slave_info *infos, *info;
- unsigned int slave_count = master->slave_count;
+ ec_ioctl_sync_t data;
const ec_slave_t *slave;
- unsigned int i = 0;
-
- if (master->debug_level)
- EC_DBG("EC_IOCTL_SLAVE_INFOS\n");
-
- if (!slave_count)
- return 0;
-
- if (!arg)
- return -EFAULT;
-
- if (!(infos = kmalloc(slave_count *
- sizeof(struct ec_ioctl_slave_info),
- GFP_KERNEL)))
- return -ENOMEM;
-
- list_for_each_entry(slave, &master->slaves, list) {
- info = &infos[i++];
- info->vendor_id = slave->sii.vendor_id;
- info->product_code = slave->sii.product_code;
- info->alias = slave->sii.alias;
- info->ring_position = slave->ring_position;
- info->state = slave->current_state;
- if (slave->sii.name) {
- strncpy(info->description, slave->sii.name,
- EC_IOCTL_SLAVE_INFO_DESC_SIZE);
- info->description[EC_IOCTL_SLAVE_INFO_DESC_SIZE - 1]
- = 0;
- } else {
- info->description[0] = 0;
- }
- }
-
- if (copy_to_user((void __user *) arg, infos, slave_count *
- sizeof(struct ec_ioctl_slave_info))) {
- kfree(infos);
- return -EFAULT;
- }
-
- kfree(infos);
- return 0;
+ const ec_sync_t *sync;
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (!(slave = ec_master_find_slave(
+ master, 0, data.slave_position))) {
+ EC_ERR("Slave %u does not exist!\n", data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ if (data.sync_index >= slave->sii.sync_count) {
+ EC_ERR("Sync manager %u does not exist in slave %u!\n",
+ data.sync_index, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ sync = &slave->sii.syncs[data.sync_index];
+
+ data.physical_start_address = sync->physical_start_address;
+ data.default_size = sync->length;
+ data.control_register = sync->control_register;
+ data.enable = sync->enable;
+ data.assign_source = sync->assign_source;
+ data.pdo_count = ec_pdo_list_count(&sync->pdos);
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
}
+ case EC_IOCTL_PDO:
+ {
+ ec_ioctl_pdo_t data;
+ const ec_slave_t *slave;
+ const ec_sync_t *sync;
+ const ec_pdo_t *pdo;
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (!(slave = ec_master_find_slave(
+ master, 0, data.slave_position))) {
+ EC_ERR("Slave %u does not exist!\n", data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ if (data.sync_index >= slave->sii.sync_count) {
+ EC_ERR("Sync manager %u does not exist in slave %u!\n",
+ data.sync_index, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ sync = &slave->sii.syncs[data.sync_index];
+ if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
+ &sync->pdos, data.pdo_pos))) {
+ EC_ERR("Sync manager %u does not contain a Pdo with "
+ "position %u in slave %u!\n", data.sync_index,
+ data.pdo_pos, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ data.dir = pdo->dir;
+ data.index = pdo->index;
+ data.entry_count = ec_pdo_entry_count(pdo);
+
+ if (pdo->name) {
+ strncpy(data.name, pdo->name, EC_IOCTL_PDO_NAME_SIZE);
+ data.name[EC_IOCTL_PDO_NAME_SIZE - 1] = 0;
+ } else {
+ data.name[0] = 0;
+ }
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+ }
+
+ case EC_IOCTL_PDO_ENTRY:
+ {
+ ec_ioctl_pdo_entry_t data;
+ const ec_slave_t *slave;
+ const ec_sync_t *sync;
+ const ec_pdo_t *pdo;
+ const ec_pdo_entry_t *entry;
+
+ if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (!(slave = ec_master_find_slave(
+ master, 0, data.slave_position))) {
+ EC_ERR("Slave %u does not exist!\n", data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ if (data.sync_index >= slave->sii.sync_count) {
+ EC_ERR("Sync manager %u does not exist in slave %u!\n",
+ data.sync_index, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ sync = &slave->sii.syncs[data.sync_index];
+ if (!(pdo = ec_pdo_list_find_pdo_by_pos_const(
+ &sync->pdos, data.pdo_pos))) {
+ EC_ERR("Sync manager %u does not contain a Pdo with "
+ "position %u in slave %u!\n", data.sync_index,
+ data.pdo_pos, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ if (!(entry = ec_pdo_find_entry_by_pos_const(
+ pdo, data.entry_pos))) {
+ EC_ERR("Pdo 0x%04X does not contain an entry with "
+ "position %u in slave %u!\n", data.pdo_pos,
+ data.entry_pos, data.slave_position);
+ retval = -EINVAL;
+ break;
+ }
+
+ data.index = entry->index;
+ data.subindex = entry->subindex;
+ data.bit_length = entry->bit_length;
+ if (entry->name) {
+ strncpy(data.name, entry->name,
+ EC_IOCTL_PDO_ENTRY_NAME_SIZE);
+ data.name[EC_IOCTL_PDO_ENTRY_NAME_SIZE - 1] = 0;
+ } else {
+ data.name[0] = 0;
+ }
+
+ if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
+ retval = -EFAULT;
+ break;
+ }
+ break;
+ }
+
default:
- return -ENOIOCTLCMD;
+ retval = -ENOIOCTLCMD;
}
-}
-
-/*****************************************************************************/
+
+ return retval;
+}
+
+/*****************************************************************************/
--- a/master/ioctl.h Mon Jun 02 10:49:44 2008 +0000
+++ b/master/ioctl.h Mon Jun 02 10:51:31 2008 +0000
@@ -44,22 +44,80 @@
/*****************************************************************************/
enum {
- EC_IOCTL_SLAVE_COUNT = 0,
- EC_IOCTL_SLAVE_INFO,
+ EC_IOCTL_SLAVE_COUNT,
+ EC_IOCTL_SLAVE,
+ EC_IOCTL_SYNC,
+ EC_IOCTL_PDO,
+ EC_IOCTL_PDO_ENTRY,
};
/*****************************************************************************/
-#define EC_IOCTL_SLAVE_INFO_DESC_SIZE 243
+#define EC_IOCTL_SLAVE_NAME_SIZE 114
-struct ec_ioctl_slave_info {
+typedef struct {
+ // input
+ uint16_t position;
+
+ // outputs
uint32_t vendor_id;
uint32_t product_code;
uint16_t alias;
- uint16_t ring_position;
uint8_t state;
- char description[EC_IOCTL_SLAVE_INFO_DESC_SIZE];
-};
+ uint8_t sync_count;
+ char name[EC_IOCTL_SLAVE_NAME_SIZE];
+} ec_ioctl_slave_t;
+
+/*****************************************************************************/
+
+typedef struct {
+ // inputs
+ uint16_t slave_position;
+ unsigned int sync_index;
+
+ // outputs
+ uint16_t physical_start_address;
+ uint16_t default_size;
+ uint8_t control_register;
+ uint8_t enable;
+ uint8_t assign_source;
+ uint8_t pdo_count;
+} ec_ioctl_sync_t;
+
+/*****************************************************************************/
+
+#define EC_IOCTL_PDO_NAME_SIZE 114
+
+typedef struct {
+ // inputs
+ uint16_t slave_position;
+ unsigned int sync_index;
+ unsigned int pdo_pos;
+
+ // outputs
+ uint8_t dir;
+ uint16_t index;
+ uint8_t entry_count;
+ char name[EC_IOCTL_PDO_NAME_SIZE];
+} ec_ioctl_pdo_t;
+
+/*****************************************************************************/
+
+#define EC_IOCTL_PDO_ENTRY_NAME_SIZE 110
+
+typedef struct {
+ // inputs
+ uint16_t slave_position;
+ unsigned int sync_index;
+ unsigned int pdo_pos;
+ unsigned int entry_pos;
+
+ // outputs
+ uint16_t index;
+ uint8_t subindex;
+ uint8_t bit_length;
+ char name[EC_IOCTL_PDO_NAME_SIZE];
+} ec_ioctl_pdo_entry_t;
/*****************************************************************************/
--- a/tools/Master.cpp Mon Jun 02 10:49:44 2008 +0000
+++ b/tools/Master.cpp Mon Jun 02 10:51:31 2008 +0000
@@ -16,7 +16,6 @@
using namespace std;
#include "Master.h"
-#include "../master/ioctl.h"
/****************************************************************************/
@@ -63,70 +62,205 @@
/****************************************************************************/
-unsigned int Master::slaveCount()
-{
- unsigned int numSlaves;
-
- if (ioctl(fd, EC_IOCTL_SLAVE_COUNT, &numSlaves)) {
- stringstream err;
- err << "Failed to get number of slaves: " << strerror(errno);
- throw MasterException(err.str());
- }
-
- return numSlaves;
-}
-
-/****************************************************************************/
-
void Master::listSlaves()
{
unsigned int numSlaves = slaveCount(), i;
- struct ec_ioctl_slave_info *infos, *info;
+ ec_ioctl_slave_t slave;
uint16_t lastAlias, aliasIndex;
- if (!numSlaves)
- return;
-
- infos = new struct ec_ioctl_slave_info[numSlaves];
-
- if (ioctl(fd, EC_IOCTL_SLAVE_INFO, infos)) {
- stringstream err;
- err << "Failed to get slave information: " << strerror(errno);
- throw MasterException(err.str());
- }
-
lastAlias = 0;
aliasIndex = 0;
for (i = 0; i < numSlaves; i++) {
- info = &infos[i];
- cout << setw(2) << info->ring_position << " ";
-
- if (info->alias) {
- lastAlias = info->alias;
+ getSlave(&slave, i);
+ cout << setw(2) << i << " ";
+
+ if (slave.alias) {
+ lastAlias = slave.alias;
aliasIndex = 0;
}
if (lastAlias) {
cout << setw(10) << "#" << lastAlias << ":" << aliasIndex;
}
- cout << " " << slaveState(info->state) << " ";
-
- if (strlen(info->description)) {
- cout << info->description;
+ cout << " " << slaveState(slave.state) << " ";
+
+ if (strlen(slave.name)) {
+ cout << slave.name;
} else {
- cout << "0x" << hex << setfill('0') << info->vendor_id
- << ":0x" << info->product_code;
+ cout << "0x" << hex << setfill('0') << slave.vendor_id
+ << ":0x" << slave.product_code;
}
cout << endl;
}
-
- delete [] infos;
-}
-
-/****************************************************************************/
-
-string Master::slaveState(uint8_t state) const
+}
+
+/****************************************************************************/
+
+void Master::listPdos(int slavePosition)
+{
+ ec_ioctl_slave_t slave;
+ ec_ioctl_sync_t sync;
+ ec_ioctl_pdo_t pdo;
+ ec_ioctl_pdo_entry_t entry;
+ unsigned int i, j, k;
+
+ getSlave(&slave, slavePosition);
+
+ for (i = 0; i < slave.sync_count; i++) {
+ getSync(&sync, slavePosition, i);
+
+ cout << "SM" << i << ":"
+ << " PhysAddr 0x"
+ << hex << setfill('0') << setw(4) << sync.physical_start_address
+ << ", DefaultSize "
+ << dec << setfill(' ') << setw(4) << sync.default_size
+ << ", ControlRegister 0x"
+ << hex << setfill('0') << setw(2)
+ << (unsigned int) sync.control_register
+ << ", Enable " << dec << (unsigned int) sync.enable
+ << endl;
+
+ for (j = 0; j < sync.pdo_count; j++) {
+ getPdo(&pdo, slavePosition, i, j);
+
+ cout << " " << (pdo.dir ? "T" : "R") << "xPdo 0x"
+ << hex << setfill('0') << setw(4) << pdo.index
+ << " \"" << pdo.name << "\"" << endl;
+
+ for (k = 0; k < pdo.entry_count; k++) {
+ getPdoEntry(&entry, slavePosition, i, j, k);
+
+ cout << " Pdo entry 0x"
+ << hex << setfill('0') << setw(4) << entry.index
+ << ":" << hex << setfill('0') << setw(2)
+ << (unsigned int) entry.subindex
+ << ", " << dec << (unsigned int) entry.bit_length
+ << " bit, \"" << entry.name << "\"" << endl;
+ }
+ }
+ }
+}
+
+/****************************************************************************/
+
+unsigned int Master::slaveCount()
+{
+ int ret;
+
+ if ((ret = ioctl(fd, EC_IOCTL_SLAVE_COUNT, 0)) < 0) {
+ stringstream err;
+ err << "Failed to get slave: " << strerror(errno);
+ throw MasterException(err.str());
+ }
+
+ return ret;
+}
+
+/****************************************************************************/
+
+void Master::getSlave(ec_ioctl_slave_t *slave, uint16_t slaveIndex)
+{
+ slave->position = slaveIndex;
+
+ if (ioctl(fd, EC_IOCTL_SLAVE, slave)) {
+ stringstream err;
+ err << "Failed to get slave: ";
+ if (errno == EINVAL)
+ err << "Slave " << slaveIndex << " does not exist!";
+ else
+ err << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
+void Master::getSync(
+ ec_ioctl_sync_t *sync,
+ uint16_t slaveIndex,
+ uint8_t syncIndex
+ )
+{
+ sync->slave_position = slaveIndex;
+ sync->sync_index = syncIndex;
+
+ if (ioctl(fd, EC_IOCTL_SYNC, sync)) {
+ stringstream err;
+ err << "Failed to get sync manager: ";
+ if (errno == EINVAL)
+ err << "Either slave " << slaveIndex << " does not exist, "
+ << "or contains less than " << (unsigned int) syncIndex + 1
+ << " sync managers!";
+ else
+ err << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
+void Master::getPdo(
+ ec_ioctl_pdo_t *pdo,
+ uint16_t slaveIndex,
+ uint8_t syncIndex,
+ uint8_t pdoPos
+ )
+{
+ pdo->slave_position = slaveIndex;
+ pdo->sync_index = syncIndex;
+ pdo->pdo_pos = pdoPos;
+
+ if (ioctl(fd, EC_IOCTL_PDO, pdo)) {
+ stringstream err;
+ err << "Failed to get Pdo: ";
+ if (errno == EINVAL)
+ err << "Either slave " << slaveIndex << " does not exist, "
+ << "or contains less than " << (unsigned int) syncIndex + 1
+ << " sync managers, or sync manager "
+ << (unsigned int) syncIndex << " contains less than "
+ << pdoPos + 1 << " Pdos!" << endl;
+ else
+ err << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
+void Master::getPdoEntry(
+ ec_ioctl_pdo_entry_t *entry,
+ uint16_t slaveIndex,
+ uint8_t syncIndex,
+ uint8_t pdoPos,
+ uint8_t entryPos
+ )
+{
+ entry->slave_position = slaveIndex;
+ entry->sync_index = syncIndex;
+ entry->pdo_pos = pdoPos;
+ entry->entry_pos = entryPos;
+
+ if (ioctl(fd, EC_IOCTL_PDO_ENTRY, entry)) {
+ stringstream err;
+ err << "Failed to get Pdo entry: ";
+ if (errno == EINVAL)
+ err << "Either slave " << slaveIndex << " does not exist, "
+ << "or contains less than " << (unsigned int) syncIndex + 1
+ << " sync managers, or sync manager "
+ << (unsigned int) syncIndex << " contains less than "
+ << pdoPos + 1 << " Pdos, or the Pdo at position " << pdoPos
+ << " contains less than " << (unsigned int) entryPos + 1
+ << " entries!" << endl;
+ else
+ err << strerror(errno);
+ throw MasterException(err.str());
+ }
+}
+
+/****************************************************************************/
+
+string Master::slaveState(uint8_t state)
{
switch (state) {
case 1: return "INIT";
--- a/tools/Master.h Mon Jun 02 10:49:44 2008 +0000
+++ b/tools/Master.h Mon Jun 02 10:51:31 2008 +0000
@@ -10,6 +10,8 @@
#include <stdexcept>
using namespace std;
+#include "../master/ioctl.h"
+
/****************************************************************************/
class MasterException:
@@ -38,11 +40,19 @@
void open(unsigned int);
void close();
- unsigned int slaveCount();
void listSlaves();
+ void listPdos(int);
protected:
- string slaveState(uint8_t) const;
+ unsigned int slaveCount();
+ void slaveSyncs(uint16_t);
+ void getSlave(ec_ioctl_slave_t *, uint16_t);
+ void getSync(ec_ioctl_sync_t *, uint16_t, uint8_t);
+ void getPdo(ec_ioctl_pdo_t *, uint16_t, uint8_t, uint8_t);
+ void getPdoEntry(ec_ioctl_pdo_entry_t *, uint16_t, uint8_t, uint8_t,
+ uint8_t);
+
+ static string slaveState(uint8_t);
private:
unsigned int index;
--- a/tools/main.cpp Mon Jun 02 10:49:44 2008 +0000
+++ b/tools/main.cpp Mon Jun 02 10:51:31 2008 +0000
@@ -19,7 +19,7 @@
#define DEFAULT_SLAVESPEC ""
static unsigned int masterIndex = DEFAULT_MASTER;
-static string slaveSpec = DEFAULT_SLAVESPEC;
+static int slavePosition = -1;
static string command = DEFAULT_COMMAND;
/*****************************************************************************/
@@ -30,10 +30,11 @@
<< "Usage: ethercat <COMMAND> [OPTIONS]" << endl
<< "Commands:" << endl
<< " list (ls, slaves) List all slaves (former 'lsec')." << endl
+ << " pdos List Pdo mapping of given slaves." << endl
<< "Global options:" << endl
<< " --master -m <master> Index of the master to use. Default: "
<< DEFAULT_MASTER << endl
- << " --slave -s <slave> Slave specification. Default: All "
+ << " --slave -s <slave> Numerical ring position. Default: All "
"slaves." << endl
<< " --help -h Show this help." << endl;
}
@@ -68,7 +69,14 @@
break;
case 's':
- slaveSpec = optarg;
+ number = strtoul(optarg, &remainder, 0);
+ if (remainder == optarg || *remainder
+ || number < 0 || number > 0xFFFF) {
+ cerr << "Invalid slave position " << optarg << "!" << endl;
+ printUsage();
+ exit(1);
+ }
+ slavePosition = number;
break;
case 'h':
@@ -101,13 +109,21 @@
getOptions(argc, argv);
- master.open(masterIndex);
+ try {
+ master.open(masterIndex);
- if (command == "list" || command == "ls" || command == "slaves") {
- master.listSlaves();
- } else {
- cerr << "Unknown command " << command << "!" << endl;
- printUsage();
+ if (command == "list" || command == "ls" || command == "slaves") {
+ master.listSlaves();
+
+ } else if (command == "pdos") {
+ master.listPdos(slavePosition);
+ } else {
+ cerr << "Unknown command " << command << "!" << endl;
+ printUsage();
+ exit(1);
+ }
+ } catch (MasterException &e) {
+ cerr << e.what() << endl;
exit(1);
}