123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- /*
- Copyright (c) 2014 Intel Corporation. All Rights Reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "offload_env.h"
- #include <string.h>
- #include <ctype.h>
- #include "offload_util.h"
- #include "liboffload_error_codes.h"
- // for environment variables valid on all cards
- const int MicEnvVar::any_card = -1;
- MicEnvVar::~MicEnvVar()
- {
- for (std::list<MicEnvVar::CardEnvVars*>::const_iterator
- it = card_spec_list.begin();
- it != card_spec_list.end(); it++) {
- CardEnvVars *card_data = *it;
- delete card_data;
- }
- }
- MicEnvVar::VarValue::~VarValue()
- {
- free(env_var_value);
- }
- MicEnvVar::CardEnvVars::~CardEnvVars()
- {
- for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin();
- it != env_vars.end(); it++) {
- VarValue *var_value = *it;
- delete var_value;
- }
- }
- // Searching for card in "card_spec_list" list with the same "number"
- MicEnvVar::CardEnvVars* MicEnvVar::get_card(int number)
- {
- if (number == any_card) {
- return &common_vars;
- }
- for (std::list<MicEnvVar::CardEnvVars*>::const_iterator
- it = card_spec_list.begin();
- it != card_spec_list.end(); it++) {
- CardEnvVars *card_data = *it;
- if (card_data->card_number == number) {
- return card_data;
- }
- }
- return NULL;
- }
- // Searching for environment variable in "env_var" list with the same name
- MicEnvVar::VarValue* MicEnvVar::CardEnvVars::find_var(
- char* env_var_name,
- int env_var_name_length
- )
- {
- for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin();
- it != env_vars.end(); it++) {
- VarValue *var_value = *it;
- if (var_value->length == env_var_name_length &&
- !strncmp(var_value->env_var, env_var_name,
- env_var_name_length)) {
- return var_value;
- }
- }
- return NULL;
- }
- void MicEnvVar::analyze_env_var(char *env_var_string)
- {
- char *env_var_name;
- char *env_var_def;
- int card_number;
- int env_var_name_length;
- MicEnvVarKind env_var_kind;
- env_var_kind = get_env_var_kind(env_var_string,
- &card_number,
- &env_var_name,
- &env_var_name_length,
- &env_var_def);
- switch (env_var_kind) {
- case c_mic_var:
- case c_mic_card_var:
- add_env_var(card_number,
- env_var_name,
- env_var_name_length,
- env_var_def);
- break;
- case c_mic_card_env:
- mic_parse_env_var_list(card_number, env_var_def);
- break;
- case c_no_mic:
- default:
- break;
- }
- }
- void MicEnvVar::add_env_var(
- int card_number,
- char *env_var_name,
- int env_var_name_length,
- char *env_var_def
- )
- {
- VarValue *var;
- CardEnvVars *card;
- // The case corresponds to common env var definition of kind
- // <mic-prefix>_<var>
- if (card_number == any_card) {
- card = &common_vars;
- }
- else {
- card = get_card(card_number);
- if (!card) {
- // definition for new card occured
- card = new CardEnvVars(card_number);
- card_spec_list.push_back(card);
- }
- }
- var = card->find_var(env_var_name, env_var_name_length);
- if (!var) {
- // put new env var definition in "env_var" list
- var = new VarValue(env_var_name, env_var_name_length, env_var_def);
- card->env_vars.push_back(var);
- }
- }
- // The routine analyses string pointed by "env_var_string" argument
- // according to the following syntax:
- //
- // Specification of prefix for MIC environment variables
- // MIC_ENV_PREFIX=<mic-prefix>
- //
- // Setting single MIC environment variable
- // <mic-prefix>_<var>=<value>
- // <mic-prefix>_<card-number>_<var>=<value>
- // Setting multiple MIC environment variables
- // <mic-prefix>_<card-number>_ENV=<env-vars>
- MicEnvVarKind MicEnvVar::get_env_var_kind(
- char *env_var_string,
- int *card_number,
- char **env_var_name,
- int *env_var_name_length,
- char **env_var_def
- )
- {
- int len = strlen(prefix);
- char *c = env_var_string;
- int num = 0;
- bool card_is_set = false;
- if (strncmp(c, prefix, len) != 0 || c[len] != '_') {
- return c_no_mic;
- }
- c += len + 1;
- *card_number = any_card;
- if (isdigit(*c)) {
- while (isdigit (*c)) {
- num = (*c++ - '0') + (num * 10);
- }
- if (*c != '_') {
- return c_no_mic;
- }
- c++;
- *card_number = num;
- card_is_set = true;
- }
- if (!isalpha(*c)) {
- return c_no_mic;
- }
- *env_var_name = *env_var_def = c;
- if (strncmp(c, "ENV=", 4) == 0) {
- if (!card_is_set) {
- *env_var_name_length = 3;
- *env_var_name = *env_var_def = c;
- *env_var_def = strdup(*env_var_def);
- return c_mic_var;
- }
- *env_var_def = c + strlen("ENV=");
- *env_var_def = strdup(*env_var_def);
- return c_mic_card_env;
- }
- if (isalpha(*c)) {
- *env_var_name_length = 0;
- while (isalnum(*c) || *c == '_') {
- c++;
- (*env_var_name_length)++;
- }
- }
- if (*c != '=') {
- return c_no_mic;
- }
- *env_var_def = strdup(*env_var_def);
- return card_is_set? c_mic_card_var : c_mic_var;
- }
- // analysing <env-vars> in form:
- // <mic-prefix>_<card-number>_ENV=<env-vars>
- // where:
- //
- // <env-vars>:
- // <env-var>
- // <env-vars> | <env-var>
- //
- // <env-var>:
- // variable=value
- // variable="value"
- // variable=
- void MicEnvVar::mic_parse_env_var_list(
- int card_number, char *env_vars_def_list)
- {
- char *c = env_vars_def_list;
- char *env_var_name;
- int env_var_name_length;
- char *env_var_def;
- bool var_is_quoted;
- if (*c == '"') {
- c++;
- }
- while (*c != 0) {
- var_is_quoted = false;
- env_var_name = c;
- env_var_name_length = 0;
- if (isalpha(*c)) {
- while (isalnum(*c) || *c == '_') {
- c++;
- env_var_name_length++;
- }
- }
- else {
- LIBOFFLOAD_ERROR(c_mic_parse_env_var_list1);
- return;
- }
- if (*c != '=') {
- LIBOFFLOAD_ERROR(c_mic_parse_env_var_list2);
- return;
- }
- c++;
- if (*c == '"') {
- var_is_quoted = true;
- c++;
- }
- // Environment variable values that contain | will need to be escaped.
- while (*c != 0 && *c != '|' &&
- (!var_is_quoted || *c != '"'))
- {
- // skip escaped symbol
- if (*c == '\\') {
- c++;
- }
- c++;
- }
- if (var_is_quoted) {
- c++; // for "
- while (*c != 0 && *c != '|') {
- c++;
- }
- }
- int sz = c - env_var_name;
- env_var_def = (char*)malloc(sz);
- if (env_var_def == NULL)
- LIBOFFLOAD_ERROR(c_malloc);
- memcpy(env_var_def, env_var_name, sz);
- env_var_def[sz] = 0;
- if (*c == '|') {
- c++;
- while (*c != 0 && *c == ' ') {
- c++;
- }
- }
- add_env_var(card_number,
- env_var_name,
- env_var_name_length,
- env_var_def);
- }
- }
- // Collect all definitions for the card with number "card_num".
- // The returned result is vector of string pointers defining one
- // environment variable. The vector is terminated by NULL pointer.
- // In the begining of the vector there are env vars defined as
- // <mic-prefix>_<card-number>_<var>=<value>
- // or
- // <mic-prefix>_<card-number>_ENV=<env-vars>
- // where <card-number> is equal to "card_num"
- // They are followed by definitions valid for any card
- // and absent in previous definitions.
- char** MicEnvVar::create_environ_for_card(int card_num)
- {
- VarValue *var_value;
- VarValue *var_value_find;
- CardEnvVars *card_data = get_card(card_num);
- CardEnvVars *card_data_common;
- std::list<char*> new_env;
- char **rez;
- if (!prefix) {
- return NULL;
- }
- // There is no personel env var definitions for the card with
- // number "card_num"
- if (!card_data) {
- return create_environ_for_card(any_card);
- }
- for (std::list<MicEnvVar::VarValue*>::const_iterator
- it = card_data->env_vars.begin();
- it != card_data->env_vars.end(); it++) {
- var_value = *it;
- new_env.push_back(var_value->env_var_value);
- }
- if (card_num != any_card) {
- card_data_common = get_card(any_card);
- for (std::list<MicEnvVar::VarValue*>::const_iterator
- it = card_data_common->env_vars.begin();
- it != card_data_common->env_vars.end(); it++) {
- var_value = *it;
- var_value_find = card_data->find_var(var_value->env_var,
- var_value->length);
- if (!var_value_find) {
- new_env.push_back(var_value->env_var_value);
- }
- }
- }
- int new_env_size = new_env.size();
- rez = (char**) malloc((new_env_size + 1) * sizeof(char*));
- if (rez == NULL)
- LIBOFFLOAD_ERROR(c_malloc);
- std::copy(new_env.begin(), new_env.end(), rez);
- rez[new_env_size] = 0;
- return rez;
- }
|