/** * This routine opens an ET system for client use. * * Given an ET system on the same host, this routine will map the system's shared memory into the * user's space. It also starts up a thread to produce a heartbeat and a second thread to monitor * the ET system's heartbeat. If the ET system is remote, a network connection is made to it.<p> * * The ET system is implemented as a single memory mapped file of the name, filename. * This routine should only be called once, before all other ET routines are used, or after a * system has been closed with a call to @ref et_close or @ref et_forcedclose. A successful return * from this routine assures connection to an ET system which is up and running. * <b><i>IT IS CRUCIAL THAT THE USER GET A RETURN VALUE OF "ET_OK" IF THE USER WANTS AN ET SYSTEM * GUARANTEED TO FUNCTION.</i></b><p> * * The user may open an ET system on a remote host. ET decides whether the user is on the same * as or a different machine than the system. If the determination is made that the user is on * another computer, then network connections are made to that system.<p> * * @param id pointer to ET system id which gets filled in if ET system successfully opened. * @param filename name of ET system file. * @param openconfig ET system open configuration. * * @returns @ref ET_OK if successful * @returns @ref ET_ERROR if bad arg, ET name too long, cannot initialize id, * creating/using shared memory, incompatible values for @ref ET_STATION_SELECT_INTS, * or ET system is 32 bit and this program is 64 bit, * @returns @ref ET_ERROR_TIMEOUT if the ET system is still not active before the routine returns. * @returns @ref ET_ERROR_TOOMANY if broad/multicasting and too many responses * @returns @ref ET_ERROR_REMOTE if broad/multicasting and cannot find/connect to ET system or * cannot allocate memory or ET system & user use different versions of ET, or * the host has a strange byte order. * @returns @ref ET_ERROR_READ if network read error. * @returns @ref ET_ERROR_WRITE if network write error. */ int et_open(et_sys_id *id, const char *filename, et_openconfig openconfig) { int status, auto_open=0, err, locality; et_open_config *config; et_openconfig auto_config = NULL; int def_debug; if (openconfig == NULL) { auto_open = 1; if (et_open_config_init(&auto_config) == ET_ERROR) { et_logmsg("ERROR", "et_open, null arg for openconfig, cannot use default\n"); return ET_ERROR; } openconfig = auto_config; } config = (et_open_config *) openconfig; err = ET_OK; /* argument checking */ if ((filename == NULL) || (config->init != ET_STRUCT_OK)) { et_logmsg("ERROR", "et_open, bad argument\n"); err = ET_ERROR; } else if (strlen(filename) > ET_FILENAME_LENGTH - 1) { et_logmsg("ERROR", "et_open, ET name too long\n"); err = ET_ERROR; } if (err != ET_OK) { if (auto_open == 1) { et_open_config_destroy(auto_config); } return err; } /* initialize id */ if (et_id_init(id) != ET_OK) { et_logmsg("ERROR", "et_open, cannot initialize id\n"); return ET_ERROR; } if (et_open_config_getdebugdefault(openconfig, &def_debug) != ET_OK) { def_debug = ET_DEBUG_ERROR; } et_system_setdebug(*id, def_debug); /* Decide whether we are looking for the ET system locally, * locally on some non-mutex-sharing operating * system, remotely, or anywhere. */ locality = et_findlocality(filename, openconfig); /* if host is local ... */ if (locality == ET_LOCAL) { status = etl_open(id, filename, openconfig); /* If this is a Java-based ET sys, try opening it as remote client. */ if (status == ET_ERROR_JAVASYS) { et_logmsg("ERROR", "et_open: cannot open Java ET file, try as remote client\n"); status = etr_open(id, filename, openconfig); } } /* else if host is remote ... */ else if (locality == ET_REMOTE) { status = etr_open(id, filename, openconfig); } /* else if host is local on Linux ... */ else if (locality == ET_LOCAL_NOSHARE) { status = etn_open(id, filename, openconfig); } /* else if too many systems responded and we have return error policy ... */ else if ((locality == ET_ERROR_TOOMANY) && (config->policy == ET_POLICY_ERROR)) { if (auto_open == 1) { et_open_config_destroy(auto_config); } et_logmsg("ERROR", "et_open: too many ET systems of that name responded\n"); return ET_ERROR; } /* else did not find ET system by broad/multicasting. In * this case, try to open a local system first then remote. */ else { int shared = et_sharedmutex(); /* if local operating system can share pthread mutexes ... */ if (shared == ET_MUTEX_SHARE) { status = etl_open(id, filename, openconfig); } else { status = etn_open(id, filename, openconfig); } if (status != ET_OK) { status = etr_open(id, filename, openconfig); } } if (status != ET_OK) { et_id_destroy(*id); } if (auto_open == 1) { et_open_config_destroy(auto_config); } return status; }
int et_open(et_sys_id *id, const char *filename, et_openconfig openconfig) { int status, auto_open=0, err; et_open_config *config; et_openconfig auto_config = NULL; int def_debug; if (openconfig == NULL) { auto_open = 1; if (et_open_config_init(&auto_config) == ET_ERROR) { et_logmsg("ERROR", "et_open, null arg for openconfig, cannot use default\n"); return ET_ERROR; } openconfig = auto_config; } config = (et_open_config *) openconfig; err = ET_OK; /* argument checking */ if ((filename == NULL) || (config->init != ET_STRUCT_OK)) { et_logmsg("ERROR", "et_open, bad argument\n"); err = ET_ERROR; } else if (strlen(filename) > ET_FILENAME_LENGTH - 1) { et_logmsg("ERROR", "et_open, ET name too long\n"); err = ET_ERROR; } if (err != ET_OK) { if (auto_open == 1) { et_open_config_destroy(auto_config); } return err; } /* initialize id */ if (et_id_init(id) != ET_OK) { et_logmsg("ERROR", "et_open, cannot initialize id\n"); return ET_ERROR; } if (et_open_config_getdebugdefault(openconfig, &def_debug) != ET_OK) { def_debug = ET_DEBUG_ERROR; } et_system_setdebug(*id, def_debug); /* We depart from the original version of et_open since * this ET client will attach to an ET system remotely by definition. * Force the configuration to make a tcp connection to the ET system, * even if it's not remote. */ config->mode = ET_HOST_AS_REMOTE; status = etr_open(id, filename, openconfig); if (status != ET_OK) { et_id_destroy(*id); } if (auto_open == 1) { et_open_config_destroy(auto_config); } return status; }