1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
| 1. 从输入数据中解析环境变量,将键值对插入哈希表。 2. 如果 crlf_is_lf 为 1,则将 CRLF 转换为 LF。 3. 如果 nvars 不为 0,则跳过不需要处理的变量。 4. 如果 flag 中包含 H_NOCLEAR,则不清除哈希表。 5. 如果 flag 中不包含 H_NOCLEAR,则销毁旧的哈希表,并创建新的哈希表。 6. 如果导入的环境中没有的变量将被删除。 7. 返回 1 表示插入成功,返回 0 表示插入失败。
int himport_r(struct hsearch_data *htab, const char *env, size_t size, const char sep, int flag, int crlf_is_lf, int nvars, char * const vars[]) { char *data, *sp, *dp, *name, *value; char *localvars[nvars]; int i;
if (htab == NULL) { __set_errno(EINVAL); return 0; }
if ((data = malloc(size + 1)) == NULL) { debug("himport_r: can't malloc %lu bytes\n", (ulong)size + 1); __set_errno(ENOMEM); return 0; } memcpy(data, env, size); data[size] = '\0'; dp = data;
if (nvars) memcpy(localvars, vars, sizeof(vars[0]) * nvars);
#if CONFIG_IS_ENABLED(ENV_APPEND) flag |= H_NOCLEAR; #endif if ((flag & H_NOCLEAR) == 0 && !nvars) { if (htab->table) hdestroy_r(htab); }
if (!htab->table) { int nent = CONFIG_ENV_MIN_ENTRIES + size / 8;
if (nent > CONFIG_ENV_MAX_ENTRIES) nent = CONFIG_ENV_MAX_ENTRIES;
debug("Create Hash Table: N=%d\n", nent);
if (hcreate_r(nent, htab) == 0) { free(data); return 0; } } if(crlf_is_lf) { unsigned ignored_crs = 0; for(;dp < data + size && *dp; ++dp) { if(*dp == '\r' && dp < data + size - 1 && *(dp+1) == '\n') ++ignored_crs; else *(dp-ignored_crs) = *dp; } size -= ignored_crs; dp = data; } do { struct env_entry e, *rv;
while (isblank(*dp)) ++dp;
if (*dp == '#') { while (*dp && (*dp != sep)) ++dp; ++dp; continue; }
for (name = dp; *dp != '=' && *dp && *dp != sep; ++dp) ;
if (*dp == '\0' || *(dp + 1) == '\0' || *dp == sep || *(dp + 1) == sep) { if (*dp == '=') *dp++ = '\0'; *dp++ = '\0';
debug("DELETE CANDIDATE: \"%s\"\n", name); if (!drop_var_from_set(name, nvars, localvars)) continue;
if (hdelete_r(name, htab, flag)) debug("DELETE ERROR ##############################\n");
continue; } *dp++ = '\0';
for (value = sp = dp; *dp && (*dp != sep); ++dp) { if ((*dp == '\\') && *(dp + 1)) ++dp; *sp++ = *dp; } *sp++ = '\0'; ++dp; if (*name == 0) { debug("INSERT: unable to use an empty key\n"); __set_errno(EINVAL); free(data); return 0; } if (!drop_var_from_set(name, nvars, localvars)) continue;
e.key = name; e.data = value;
hsearch_r(e, ENV_ENTER, &rv, htab, flag); #if !IS_ENABLED(CONFIG_ENV_WRITEABLE_LIST) if (rv == NULL) { printf("himport_r: can't insert \"%s=%s\" into hash table\n", name, value); } #endif
debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n", htab, htab->filled, htab->size, rv, name, value); } while ((dp < data + size) && *dp); debug("INSERT: free(data = %p)\n", data); free(data);
if (flag & H_NOCLEAR) goto end;
for (i = 0; i < nvars; i++) { if (localvars[i] == NULL) continue; if (hdelete_r(localvars[i], htab, flag)) printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]); else printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]); }
end: debug("INSERT: done\n"); return 1; }
|