static inline int strtowhatever(char *cur_pos, char **end_pos, void *data, enum parsetype type) { float valf; double vald; int32_t vali32; int64_t vali64; char *new_pos = cur_pos; char *data_pos = (char *)data; switch (type) { case PARSE_FLOAT32: valf = strtofloat(cur_pos, end_pos); if (cur_pos == *end_pos) return 0; *((float *)data) = valf; return 1; case PARSE_INT32: vali32 = strtoint32(cur_pos, end_pos); if (cur_pos == *end_pos) return 0; *((int32_t *)data) = vali32; return 1; case PARSE_FLOAT64: vald = strtodouble(cur_pos, end_pos); if (cur_pos == *end_pos) return 0; *((double *)data) = vald; return 1; case PARSE_INT64: vali64 = strtoint64(cur_pos, end_pos); if (cur_pos == *end_pos) return 0; *((int64_t *)data) = vali64; return 1; case PARSE_STRING: while (*new_pos && !(*new_pos==' ' || *new_pos=='\t' || *new_pos=='\n')) { *data_pos = *new_pos; data_pos++; new_pos++; } if (new_pos==cur_pos) return 0; *data_pos = 0; *end_pos = new_pos; return 1; case PARSE_SKIP: while (*new_pos && !(*new_pos==' ' || *new_pos=='\t' || *new_pos=='\n')) new_pos++; if (new_pos==cur_pos) return 0; *end_pos = new_pos; return 1; } return 0; }
END_TEST START_TEST (test_strtoint32_pos_integer_intmax_base_10) { int32_t result; const char *input = "2147483647"; int32_t expected = INT32_MAX; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); }
END_TEST START_TEST (test_strtoint32_neg_integer_base_10) { int32_t result; const char *input = "-123"; int32_t expected = -123; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); }
END_TEST START_TEST (test_strtoint32_pos_integer_underflow_base_10) { int32_t result; const char *input = "-8589934592"; int32_t expected = INT32_MIN; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; CHECK_ERRNO(ERANGE, error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); }
END_TEST START_TEST (test_strtoint32_emptystring_base_10) { int32_t result; const char *input = ""; int32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); }
END_TEST START_TEST (test_strtoint32_mixed_alphanumeric_base_10) { int32_t result; const char *input = "12b13"; int32_t expected = 12; char *endptr; const char *expected_endptr = input+2; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); }
static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid) { int ret; char path[PATHLEN]; struct stat stat_buf; int fd; char buf[BUFSIZE]; char *p; char *e; char *endptr; uint32_t num=0; errno_t error; ret = snprintf(path, PATHLEN, "/proc/%d/status", pid); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "snprintf failed\n"); return EINVAL; } else if (ret >= PATHLEN) { DEBUG(SSSDBG_CRIT_FAILURE, "path too long?!?!\n"); return EINVAL; } fd = open(path, O_RDONLY); if (fd == -1) { error = errno; if (error == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "Proc file [%s] is not available anymore, continuing.\n", path); return EOK; } DEBUG(SSSDBG_CRIT_FAILURE, "open failed [%d][%s].\n", error, strerror(error)); return error; } ret = fstat(fd, &stat_buf); if (ret == -1) { error = errno; if (error == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "Proc file [%s] is not available anymore, continuing.\n", path); error = EOK; goto fail_fd; } DEBUG(SSSDBG_CRIT_FAILURE, "fstat failed [%d][%s].\n", error, strerror(error)); goto fail_fd; } if (!S_ISREG(stat_buf.st_mode)) { DEBUG(SSSDBG_CRIT_FAILURE, "not a regular file\n"); error = EINVAL; goto fail_fd; } errno = 0; ret = sss_atomic_read_s(fd, buf, BUFSIZE); if (ret == -1) { error = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", error, strerror(error)); goto fail_fd; } /* Guarantee NULL-termination in case we read the full BUFSIZE somehow */ buf[BUFSIZE-1] = '\0'; ret = close(fd); if (ret == -1) { error = errno; DEBUG(SSSDBG_CRIT_FAILURE, "close failed [%d][%s].\n", error, strerror(error)); } p = strstr(buf, "\nUid:\t"); if (p != NULL) { p += 6; e = strchr(p,'\t'); if (e == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "missing delimiter.\n"); return EINVAL; } else { *e = '\0'; } num = (uint32_t) strtoint32(p, &endptr, 10); error = errno; if (error != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "strtol failed [%s].\n", strerror(error)); return error; } if (*endptr != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "uid contains extra characters\n"); return EINVAL; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "format error\n"); return EINVAL; } *uid = num; return EOK; fail_fd: close(fd); return error; }