init_utils.c 18.9 KB
Newer Older
Z
zhong_ning 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "init_utils.h"
S
sun_fan 已提交
16

Z
zhong_ning 已提交
17 18
#include <ctype.h>
#include <errno.h>
19
#include <dirent.h>
Z
zhong_ning 已提交
20
#include <fcntl.h>
M
Mupceet 已提交
21
#include <grp.h>
S
sun_fan 已提交
22
#include <limits.h>
S
sun_fan 已提交
23
#include <pwd.h>
Z
zhong_ning 已提交
24
#include <stdlib.h>
S
sun_fan 已提交
25
#include <string.h>
M
Mupceet 已提交
26
#include <sys/ioctl.h>
Z
zhong_ning 已提交
27 28
#include <sys/stat.h>
#include <unistd.h>
29

Z
zhong_ning 已提交
30 31
#include "init_log.h"
#include "securec.h"
X
xionglei6 已提交
32
#include "service_control.h"
Z
zhong_ning 已提交
33 34

#define MAX_BUF_SIZE  1024
M
Mupceet 已提交
35
#define MAX_SMALL_BUFFER 3096
Z
zhong_ning 已提交
36

Z
zhong_ning 已提交
37
#define MAX_JSON_FILE_LEN 102400    // max init.cfg size 100KB
38 39 40 41 42
#define CONVERT_MICROSEC_TO_SEC(x) ((x) / 1000 / 1000.0)
#ifndef DT_DIR
#define DT_DIR 4
#endif

S
sun_fan 已提交
43 44 45 46 47 48 49
#define THOUSAND_UNIT_INT 1000
#define THOUSAND_UNIT_FLOAT 1000.0

float ConvertMicrosecondToSecond(int x)
{
    return ((x / THOUSAND_UNIT_INT) / THOUSAND_UNIT_FLOAT);
}
Z
zhong_ning 已提交
50

Z
zhumingxian 已提交
51
#ifndef __LITEOS_M__
M
Mupceet 已提交
52
static bool CheckDigit(const char *name)
Z
zhong_ning 已提交
53
{
X
xionglei6 已提交
54
    size_t nameLen = strlen(name);
M
Mupceet 已提交
55 56 57
    for (size_t i = 0; i < nameLen; ++i) {
        if (!isdigit(name[i])) {
            return false;
Z
zhong_ning 已提交
58 59
        }
    }
M
Mupceet 已提交
60 61
    return true;
}
Z
zhumingxian 已提交
62
#endif
M
Mupceet 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

int StringToUint(const char *name, unsigned int *value)
{
    errno = 0;
    *value = (unsigned int)strtoul(name, 0, DECIMAL_BASE);
    INIT_CHECK_RETURN_VALUE(errno == 0, -1);
    return 0;
}

uid_t DecodeUid(const char *name)
{
#ifndef __LITEOS_M__
    INIT_CHECK_RETURN_VALUE(name != NULL, -1);
    uid_t uid = -1;
    if (CheckDigit(name)) {
        if (!StringToUint(name, &uid)) {
            return uid;
        } else {
M
initgid  
Mupceet 已提交
81
            INIT_LOGE("Failed to decode uid for %s", name);
Z
zhong_ning 已提交
82 83 84
            return -1;
        }
    }
M
Mupceet 已提交
85 86
    struct passwd *p = getpwnam(name);
    if (p == NULL) {
M
initgid  
Mupceet 已提交
87
        INIT_LOGE("Failed to decode uid for %s", name);
M
Mupceet 已提交
88 89 90
        return -1;
    }
    return p->pw_uid;
M
Mupceet 已提交
91
#else
Z
zhumingxian 已提交
92
    (void)name;
M
Mupceet 已提交
93 94
    return -1;
#endif
Z
zhong_ning 已提交
95 96
}

M
Mupceet 已提交
97 98
gid_t DecodeGid(const char *name)
{
M
Mupceet 已提交
99 100 101 102 103 104 105
#ifndef __LITEOS_M__
    INIT_CHECK_RETURN_VALUE(name != NULL, -1);
    gid_t gid = -1;
    if (CheckDigit(name)) {
        if (!StringToUint(name, &gid)) {
            return gid;
        } else {
M
initgid  
Mupceet 已提交
106
            INIT_LOGE("Failed to decode gid for %s", name);
M
Mupceet 已提交
107 108 109
            return -1;
        }
    }
C
cheng_jinsong 已提交
110 111 112 113
    struct group *data = getgrnam(name);
    if (data != NULL) {
        return data->gr_gid;
    }
M
Mupceet 已提交
114 115 116 117 118 119 120 121 122
    while ((data = getgrent()) != NULL) {
        if ((data->gr_name != NULL) && (strcmp(data->gr_name, name) == 0)) {
            gid = data->gr_gid;
            break;
        }
    }
    endgrent();
    return gid;
#else
Z
zhumingxian 已提交
123
    (void)name;
M
Mupceet 已提交
124 125
    return -1;
#endif
M
Mupceet 已提交
126 127
}

S
sun_fan 已提交
128
char *ReadFileToBuf(const char *configFile)
Z
zhong_ning 已提交
129
{
S
sun_fan 已提交
130 131
    char *buffer = NULL;
    FILE *fd = NULL;
Z
zhong_ning 已提交
132
    struct stat fileStat = {0};
X
add ut  
xionglei6 已提交
133
    INIT_CHECK_RETURN_VALUE(configFile != NULL && *configFile != '\0', NULL);
Z
zhong_ning 已提交
134 135 136
    do {
        if (stat(configFile, &fileStat) != 0 ||
            fileStat.st_size <= 0 || fileStat.st_size > MAX_JSON_FILE_LEN) {
Z
zhong_ning 已提交
137
            INIT_LOGE("Unexpected config file \" %s \", check if it exist. if exist, check file size", configFile);
Z
zhong_ning 已提交
138 139 140 141
            break;
        }
        fd = fopen(configFile, "r");
        if (fd == NULL) {
Z
zhong_ning 已提交
142
            INIT_LOGE("Open %s failed. err = %d", configFile, errno);
Z
zhong_ning 已提交
143 144
            break;
        }
S
sun_fan 已提交
145
        buffer = (char*)malloc((size_t)(fileStat.st_size + 1));
Z
zhong_ning 已提交
146
        if (buffer == NULL) {
Z
zhong_ning 已提交
147
            INIT_LOGE("Failed to allocate memory for config file, err = %d", errno);
Z
zhong_ning 已提交
148 149 150 151 152 153 154 155 156 157 158 159
            break;
        }

        if (fread(buffer, fileStat.st_size, 1, fd) != 1) {
            free(buffer);
            buffer = NULL;
            break;
        }
        buffer[fileStat.st_size] = '\0';
    } while (0);

    if (fd != NULL) {
160
        (void)fclose(fd);
Z
zhong_ning 已提交
161 162 163
        fd = NULL;
    }
    return buffer;
S
sun_fan 已提交
164 165
}

C
cheng_jinsong 已提交
166 167
void CloseStdio(void)
{
C
cheng_jinsong 已提交
168
#ifndef STARTUP_INIT_TEST
C
cheng_jinsong 已提交
169 170 171 172 173 174 175 176 177 178
#ifndef __LITEOS_M__
    int fd = open("/dev/null", O_RDWR | O_CLOEXEC);
    if (fd < 0) {
        return;
    }
    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, STDERR_HANDLE);
    close(fd);
#endif
C
cheng_jinsong 已提交
179
#endif
C
cheng_jinsong 已提交
180 181
}

X
xionglei6 已提交
182 183 184 185 186 187 188
char *ReadFileData(const char *fileName)
{
    if (fileName == NULL) {
        return NULL;
    }
    char *buffer = NULL;
    int fd = -1;
M
Mupceet 已提交
189 190
    fd = open(fileName, O_RDONLY);
    INIT_ERROR_CHECK(fd >= 0, return NULL, "Failed to read file %s", fileName);
C
cheng_jinsong 已提交
191
    buffer = (char *)calloc(1, MAX_SMALL_BUFFER); // fsmanager not create, can not get fileStat st_size
M
Mupceet 已提交
192 193 194
    INIT_ERROR_CHECK(buffer != NULL, close(fd);
        return NULL, "Failed to allocate memory for %s", fileName);
    ssize_t readLen = read(fd, buffer, MAX_SMALL_BUFFER - 1);
M
Mupceet 已提交
195
    INIT_ERROR_CHECK((readLen > 0) && (readLen < (MAX_SMALL_BUFFER - 1)), close(fd);
M
Mupceet 已提交
196 197 198
        free(buffer);
        return NULL, "Failed to read data for %s", fileName);
    buffer[readLen] = '\0';
X
xionglei6 已提交
199 200 201 202 203 204
    if (fd != -1) {
        close(fd);
    }
    return buffer;
}

205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
int IterateNameValuePairs(const char *src, void (*iterator)(const NAME_VALUE_PAIR *nv, void *context), void *context)
{
    int cnt = 0;
    const char *seperator;
    NAME_VALUE_PAIR nv;
    if ((src == NULL) || (iterator == NULL)) {
        return -1;
    }

    do {
        // Find space seperator
        nv.name = src;
        seperator = strchr(src, ' ');
        if (seperator == NULL) {
            // Last nv
            nv.value_end = src + strlen(src);
            src = NULL;
        } else {
            nv.value_end = seperator;
            src = seperator + 1;
        }

        // Find equal seperator
        seperator = strchr(nv.name, '=');
        if (seperator == NULL) {
            // Invalid name value pair
            continue;
        }
        if (seperator > nv.value_end) {
            // name without value, just ignore
            continue;
        }
        nv.name_end = seperator;
        nv.value = seperator + 1;

        iterator(&nv, context);
        cnt += 1;
    } while (src != NULL);

    return cnt;
}

X
xionglei6 已提交
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
int GetProcCmdlineValue(const char *name, const char *buffer, char *value, int length)
{
    INIT_ERROR_CHECK(name != NULL && buffer != NULL && value != NULL, return -1, "Failed get parameters");
    char *endData = (char *)buffer + strlen(buffer);
    char *tmp = strstr(buffer, name);
    do {
        if (tmp == NULL) {
            return -1;
        }
        tmp = tmp + strlen(name);
        while (tmp < endData && *tmp == ' ') {
            tmp++;
        }
        if (*tmp == '=') {
            break;
        }
        tmp = strstr(tmp + 1, name);
    } while (tmp < endData);
    tmp++;
    size_t i = 0;
    size_t endIndex = 0;
    while (tmp < endData && *tmp == ' ') {
        tmp++;
    }
    for (; i < (size_t)length; tmp++) {
        if (tmp >= endData) {
            endIndex = i;
            break;
        }
X
xionglei6 已提交
276
        if (*tmp == ' ' || *tmp == '\n' || *tmp == '\r' || *tmp == '\t') {
X
xionglei6 已提交
277
            endIndex = i;
X
xionglei6 已提交
278
            break;
X
xionglei6 已提交
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
        }
        if (*tmp == '=') {
            if (endIndex != 0) { // for root=uuid=xxxx
                break;
            }
            i = 0;
            endIndex = 0;
            continue;
        }
        value[i++] = *tmp;
    }
    if (i >= (size_t)length) {
        return -1;
    }
    value[endIndex] = '\0';
    return 0;
}

297
int SplitString(char *srcPtr, const char *del, char **dstPtr, int maxNum)
S
sun_fan 已提交
298
{
X
add ut  
xionglei6 已提交
299
    INIT_CHECK_RETURN_VALUE(srcPtr != NULL && dstPtr != NULL && del != NULL, -1);
S
sun_fan 已提交
300
    char *buf = NULL;
301
    dstPtr[0] = strtok_r(srcPtr, del, &buf);
S
sun_fan 已提交
302
    int counter = 0;
X
xionglei6 已提交
303
    while ((counter < maxNum) && (dstPtr[counter] != NULL)) {
S
sun_fan 已提交
304
        counter++;
X
xionglei6 已提交
305
        if (counter >= maxNum) {
X
xionglei6 已提交
306
            break;
X
xionglei6 已提交
307
        }
X
xionglei6 已提交
308
        dstPtr[counter] = strtok_r(NULL, del, &buf);
S
sun_fan 已提交
309
    }
S
sun_fan 已提交
310
    return counter;
S
sun_fan 已提交
311
}
Z
zhong_ning 已提交
312

313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
void FreeStringVector(char **vector, int count)
{
    if (vector != NULL) {
        for (int i = 0; i < count; i++) {
            if (vector[i] != NULL) {
                free(vector[i]);
            }
        }
        free(vector);
    }
}

char **SplitStringExt(char *buffer, const char *del, int *returnCount, int maxItemCount)
{
    INIT_CHECK_RETURN_VALUE((maxItemCount >= 0) && (buffer != NULL) && (del != NULL) && (returnCount != NULL), NULL);
    // Why is this number?
329
    // Now we use this function to split a string with a given delimiter
330 331 332 333 334 335 336 337 338
    // We do not know how many sub-strings out there after splitting.
    // 50 is just a guess value.
    const int defaultItemCounts = 50;
    int itemCounts = maxItemCount;

    if (maxItemCount > defaultItemCounts) {
        itemCounts = defaultItemCounts;
    }
    char **items = (char **)malloc(sizeof(char*) * itemCounts);
X
add ut  
xionglei6 已提交
339
    INIT_ERROR_CHECK(items != NULL, return NULL, "No enough memory to store items");
340 341 342 343 344
    char *rest = NULL;
    char *p = strtok_r(buffer, del, &rest);
    int count = 0;
    while (p != NULL) {
        if (count > itemCounts - 1) {
4
411148299@qq.com 已提交
345
            itemCounts += (itemCounts / 2) + 1; // 2 Request to increase the original memory by half.
X
xionglei6 已提交
346
            INIT_LOGV("Too many items,expand size");
347
            char **expand = (char **)(realloc(items, sizeof(char *) * itemCounts));
X
add ut  
xionglei6 已提交
348
            INIT_ERROR_CHECK(expand != NULL, FreeStringVector(items, count);
M
Mupceet 已提交
349
                return NULL, "Failed to expand memory");
350 351 352 353
            items = expand;
        }
        size_t len = strlen(p);
        items[count] = (char *)malloc(len + 1);
X
add ut  
xionglei6 已提交
354 355
        INIT_CHECK(items[count] != NULL, FreeStringVector(items, count);
            return NULL);
356 357 358 359 360 361 362 363 364 365 366 367 368
        if (strncpy_s(items[count], len + 1, p, len) != EOK) {
            INIT_LOGE("Copy string failed");
            FreeStringVector(items, count);
            return NULL;
        }
        items[count][len] = '\0';
        count++;
        p = strtok_r(NULL, del, &rest);
    }
    *returnCount = count;
    return items;
}

H
huangshan 已提交
369
void WaitForFile(const char *source, unsigned int maxSecond)
Z
zhong_ning 已提交
370
{
H
huangshan 已提交
371
    INIT_ERROR_CHECK(maxSecond <= WAIT_MAX_SECOND, maxSecond = WAIT_MAX_SECOND, "WaitForFile max time is 5s");
王liangliang's avatar
王liangliang 已提交
372
    struct stat sourceInfo = {0};
X
xionglei6 已提交
373
    unsigned int waitTime = 500000;
H
huangshan 已提交
374 375
    /* 500ms interval, check maxSecond*2 times total */
    unsigned int maxCount = maxSecond * 2;
C
cheng_jinsong 已提交
376 377 378
#ifdef STARTUP_INIT_TEST
    maxCount = 0;
#endif
Z
fix bug  
zhong_ning 已提交
379
    unsigned int count = 0;
M
Mupceet 已提交
380
    while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < maxCount)) {
Z
zhong_ning 已提交
381 382
        usleep(waitTime);
        count++;
M
Mupceet 已提交
383
    }
H
huangshan 已提交
384
    INIT_CHECK_ONLY_ELOG(count != maxCount, "wait for file:%s failed after %d second.", source, maxSecond);
Z
zhong_ning 已提交
385 386 387
    return;
}

S
sun_fan 已提交
388
size_t WriteAll(int fd, const char *buffer, size_t size)
S
sun_fan 已提交
389
{
X
add ut  
xionglei6 已提交
390
    INIT_CHECK_RETURN_VALUE(buffer != NULL && fd >= 0 && *buffer != '\0', 0);
S
sun_fan 已提交
391
    const char *p = buffer;
S
sun_fan 已提交
392
    size_t left = size;
X
add ut  
xionglei6 已提交
393
    ssize_t written;
S
sun_fan 已提交
394 395 396 397 398 399 400 401 402 403 404 405
    while (left > 0) {
        do {
            written = write(fd, p, left);
        } while (written < 0 && errno == EINTR);
        if (written < 0) {
            INIT_LOGE("Failed to write %lu bytes, err = %d", left, errno);
            break;
        }
        p += written;
        left -= written;
    }
    return size - left;
S
sun_fan 已提交
406 407
}

408
char *GetRealPath(const char *source)
S
sun_fan 已提交
409
{
X
add ut  
xionglei6 已提交
410
    INIT_CHECK_RETURN_VALUE(source != NULL, NULL);
411 412
    char *path = realpath(source, NULL);
    if (path == NULL) {
X
add ut  
xionglei6 已提交
413
        INIT_ERROR_CHECK(errno == ENOENT, return NULL, "Failed to resolve %s real path err=%d", source, errno);
S
sun_fan 已提交
414
    }
415
    return path;
S
sun_fan 已提交
416 417 418 419 420 421 422 423 424 425
}

int MakeDir(const char *dir, mode_t mode)
{
    int rc = -1;
    if (dir == NULL || *dir == '\0') {
        errno = EINVAL;
        return rc;
    }
    rc = mkdir(dir, mode);
X
add ut  
xionglei6 已提交
426 427
    INIT_ERROR_CHECK(!(rc < 0 && errno != EEXIST), return rc,
        "Create directory \" %s \" failed, err = %d", dir, errno);
S
sun_fan 已提交
428 429 430 431 432 433 434
    // create dir success or it already exist.
    return 0;
}

int MakeDirRecursive(const char *dir, mode_t mode)
{
    int rc = -1;
王liangliang's avatar
王liangliang 已提交
435
    char buffer[PATH_MAX] = {0};
S
sun_fan 已提交
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
    const char *p = NULL;
    if (dir == NULL || *dir == '\0') {
        errno = EINVAL;
        return rc;
    }
    p = dir;
    char *slash = strchr(dir, '/');
    while (slash != NULL) {
        int gap = slash - p;
        p = slash + 1;
        if (gap == 0) {
            slash = strchr(p, '/');
            continue;
        }
        if (gap < 0) { // end with '/'
            break;
        }
X
add ut  
xionglei6 已提交
453
        INIT_CHECK_RETURN_VALUE(memcpy_s(buffer, PATH_MAX, dir, p - dir - 1) == 0, -1);
S
sun_fan 已提交
454
        rc = MakeDir(buffer, mode);
X
add ut  
xionglei6 已提交
455
        INIT_CHECK_RETURN_VALUE(rc >= 0, rc);
S
sun_fan 已提交
456 457 458 459 460
        slash = strchr(p, '/');
    }
    return MakeDir(dir, mode);
}

M
Mupceet 已提交
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
void CheckAndCreateDir(const char *fileName)
{
#ifndef __LITEOS_M__
    if (fileName == NULL || *fileName == '\0') {
        return;
    }
    char *path = strndup(fileName, strrchr(fileName, '/') - fileName);
    if (path == NULL) {
        return;
    }
    if (access(path, F_OK) == 0) {
        free(path);
        return;
    }
    MakeDirRecursive(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
    free(path);
Z
zhumingxian 已提交
477 478
#else
    (void)fileName;
M
Mupceet 已提交
479 480 481
#endif
}

M
Mupceet 已提交
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
int CheckAndCreatFile(const char *file, mode_t mode)
{
    if (access(file, F_OK) == 0) {
        BEGET_LOGW("File \' %s \' already exist", file);
        return 0;
    } else {
        if (errno == ENOENT) {
            CheckAndCreateDir(file);
            int fd = open(file, O_CREAT, mode);
            if (fd < 0) {
                BEGET_LOGE("Failed create %s, err=%d", file, errno);
                return -1;
            } else {
                BEGET_LOGI("Success create %s", file);
                close(fd);
            }
        } else {
            BEGET_LOGW("Failed to access \' %s \', err = %d", file, errno);
            return -1;
        }
    }
    return 0;
}

S
sun_fan 已提交
506 507 508 509 510 511 512
int StringToInt(const char *str, int defaultValue)
{
    if (str == NULL || *str == '\0') {
        return defaultValue;
    }
    errno = 0;
    int value = (int)strtoul(str, NULL, DECIMAL_BASE);
X
add ut  
xionglei6 已提交
513
    return (errno != 0) ? defaultValue : value;
514 515 516 517 518
}

int ReadFileInDir(const char *dirPath, const char *includeExt,
    int (*processFile)(const char *fileName, void *context), void *context)
{
X
add ut  
xionglei6 已提交
519
    INIT_CHECK_RETURN_VALUE(dirPath != NULL && processFile != NULL, -1);
520 521
    DIR *pDir = opendir(dirPath);
    INIT_ERROR_CHECK(pDir != NULL, return -1, "Read dir :%s failed.%d", dirPath, errno);
C
cheng_jinsong 已提交
522
    char *fileName = calloc(1, MAX_BUF_SIZE);
523 524 525 526
    INIT_ERROR_CHECK(fileName != NULL, closedir(pDir);
        return -1, "Failed to malloc for %s", dirPath);

    struct dirent *dp;
M
Mupceet 已提交
527
    uint32_t count = 0;
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
    while ((dp = readdir(pDir)) != NULL) {
        if (dp->d_type == DT_DIR) {
            continue;
        }
        if (includeExt != NULL) {
            char *tmp = strstr(dp->d_name, includeExt);
            if (tmp == NULL) {
                continue;
            }
            if (strcmp(tmp, includeExt) != 0) {
                continue;
            }
        }
        int ret = snprintf_s(fileName, MAX_BUF_SIZE, MAX_BUF_SIZE - 1, "%s/%s", dirPath, dp->d_name);
        if (ret <= 0) {
            INIT_LOGE("Failed to get file name for %s", dp->d_name);
            continue;
        }
        struct stat st;
        if (stat(fileName, &st) == 0) {
M
Mupceet 已提交
548
            count++;
549 550 551
            processFile(fileName, context);
        }
    }
M
Mupceet 已提交
552
    INIT_LOGV("ReadFileInDir dirPath %s %d", dirPath, count);
553 554 555
    free(fileName);
    closedir(pDir);
    return 0;
S
sun_fan 已提交
556 557
}

558 559 560
// Check if in updater mode.
int InUpdaterMode(void)
{
M
Mupceet 已提交
561 562 563
#ifdef OHOS_LITE
    return 0;
#else
C
fix log  
cheng_jinsong 已提交
564 565
    const char * const updaterExecutableFile = "/bin/updater";
    if (access(updaterExecutableFile, X_OK) == 0) {
566 567 568 569
        return 1;
    } else {
        return 0;
    }
M
Mupceet 已提交
570
#endif
571
}
X
xionglei6 已提交
572 573 574 575 576 577 578 579 580 581 582

int StringReplaceChr(char *strl, char oldChr, char newChr)
{
    INIT_ERROR_CHECK(strl != NULL, return -1, "Invalid parament");
    char *p = strl;
    while (*p != '\0') {
        if (*p == oldChr) {
            *p = newChr;
        }
        p++;
    }
X
xionglei6 已提交
583
    INIT_LOGV("strl is %s", strl);
X
xionglei6 已提交
584 585
    return 0;
}
X
xionglei6 已提交
586

C
cheng_jinsong 已提交
587
void RedirectStdio(int fd)
M
Mupceet 已提交
588 589 590
{
#ifndef __LITEOS_M__
    const int stdError = 2;
C
cheng_jinsong 已提交
591 592 593 594 595 596 597 598 599
    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, stdError); // Redirect fd to 0, 1, 2
#endif
}

void OpenConsole(void)
{
#ifndef __LITEOS_M__
M
Mupceet 已提交
600 601 602 603 604
    setsid();
    WaitForFile("/dev/console", WAIT_MAX_SECOND);
    int fd = open("/dev/console", O_RDWR);
    if (fd >= 0) {
        ioctl(fd, TIOCSCTTY, 0);
C
cheng_jinsong 已提交
605
        RedirectStdio(fd);
M
Mupceet 已提交
606 607 608 609 610 611 612
        close(fd);
    } else {
        INIT_LOGE("Open /dev/console failed. err = %d", errno);
    }
    return;
#endif
}
M
Mupceet 已提交
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656

INIT_LOCAL_API int StringToLL(const char *str, long long int *out)
{
    INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
    const char *s = str;
    while (isspace(*s)) {
        s++;
    }

    size_t len = strlen(str);
    int positiveHex = (len > 1 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
    int negativeHex = (len > 2 && s[0] == '-' && s[1] == '0' && (s[2] == 'x' || s[2] == 'X')); // 2: shorttest
    int base = (positiveHex || negativeHex) ? HEX_BASE : DECIMAL_BASE;
    char *end = NULL;
    errno = 0;
    *out = strtoll(s, &end, base);
    if (errno != 0) {
        INIT_LOGE("StringToLL %s err = %d", str, errno);
        return -1;
    }
    BEGET_CHECK(!(s == end || *end != '\0'), return -1);
    return 0;
}

INIT_LOCAL_API int StringToULL(const char *str, unsigned long long int *out)
{
    INIT_ERROR_CHECK(str != NULL && out != NULL, return -1, "Invalid parament");
    const char *s = str;
    while (isspace(*s)) {
        s++;
    }
    BEGET_CHECK(s[0] != '-', return -1);
    int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? HEX_BASE : DECIMAL_BASE;
    char *end = NULL;
    errno = 0;
    *out = strtoull(s, &end, base);
    if (errno != 0) {
        INIT_LOGE("StringToULL %s err = %d", str, errno);
        return -1;
    }
    BEGET_CHECK(end != s, return -1);
    BEGET_CHECK(*end == '\0', return -1);
    return 0;
}
M
Mupceet 已提交
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676

void TrimTail(char *str, char c)
{
    char *end = str + strlen(str) - 1;
    while (end >= str && *end == c) {
        *end = '\0';
        end--;
    }
}

char *TrimHead(char *str, char c)
{
    char *head = str;
    const char *end = str + strlen(str);
    while (head < end && *head == c) {
        *head = '\0';
        head++;
    }
    return head;
}
C
cheng_jinsong 已提交
677 678 679 680 681 682 683 684 685 686

int GetParameterFromCmdLine(const char *paramName, char *value, size_t valueLen)
{
    char *buffer = ReadFileData(BOOT_CMD_LINE);
    BEGET_ERROR_CHECK(buffer != NULL, return -1, "Failed to read /proc/cmdline");
    int ret = GetProcCmdlineValue(paramName, buffer, value, valueLen);
    free(buffer);
    return ret;
}