From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 5357 invoked from network); 10 Jul 2021 14:07:15 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 10 Jul 2021 14:07:15 -0000 Received: (qmail 32314 invoked by uid 550); 10 Jul 2021 14:07:06 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 12144 invoked from network); 10 Jul 2021 05:32:09 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=insomnia247.nl; s=mail; t=1625895117; bh=5crpZy/l0nEPaHSonYa/QQd850Wq5E0Fv2qlCa9XpH4=; h=To:Subject:Cc:Date:From:From; b=U/0CGVjxCiPswHcrU9eNtN6hVN3I4d4ktHolkR+FZvCxsnK8Itf4dgEgKkkIzmHzJ tcAuGGPVwzkLAFJtAX5udkfdqoKBbk6xTRff6d/EKt2eiBDlLDBel7yAF6pzURglpB SedpzUNCKerqeRVdu9ZHOeXwmMUM0LUGY5+62xXc= To: musl@lists.openwall.com, vincent.donnefort@arm.com Cc: jason@insomnia247.nl MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit Message-Id: <20210710053157.4F16D22215EC@gateway02.insomnia247.nl> Date: Sat, 10 Jul 2021 07:31:57 +0200 (CEST) From: jason Subject: Re: [musl] [PATCH v3] sysconf: add _SC_NPROCESSORS_CONF support Here's a simpler bit of code to do the same thing. The differences: - Doesn't bother using stdio. /proc and /sys reads like this don't sleep and so don't return short or EINTR or any of that hair. - Check for the terminating newline, and use it in the parsing loop to trigger completing a range, just like ','. The previous code never actually ensured that the buffer was '\0' terminated. :-( - Use one "current number being parsed" variable rather than two. Just copy n to prev_n on finding a '-'. (Feel free to bikeshed the variable names to "range_start" or something if you prefer.) If you do want to use a FILE *, musl should probably have an internal API for reading into the stdio buffer and parsing straight from there, avoiding the separate stack buffer. (Or even allocating the FILE on the stack and avoiding the malloc.) This is probably far from the last small config file (/proc or /sys or perhaps something like /etc/hostname) that someone will want to access. (You could even get ambitious and make it reallocate the buffer as required to get the whole file into memory Probably something other code would be interested in, like timezone parsing.) #include #include #include long get_nrprocessors_conf1(void) { int fd = open("/sys/devices/system/cpu/possible", O_RDONLY | O_NOCTTY | O_CLOEXEC); if (fd < 0) goto failure; char buffer[128]; /* Some reasonable size. */ ssize_t ss = read(fd, buffer, sizeof buffer); /* * Short reads, EINTR, etc. can't happen with /sys files. * We could in theory preserve the read's errno in case the close * overwrites it, but that seems excessive. */ if (close(fd) < 0 || ss < 0) goto failure; if (ss < 2 || buffer[ss-1] != '\n') goto parse_error; /* * The possible CPUs are given as a comma-separated list of ranges, * with each range being either a single decimal integer ("1") or * a hyphen-separated range ("1-10"). * * Q: How careful do we want the parsing to be? For now, assume * the kernel can be trusted not to give us "1-2-3" or ",," or * other strangeness. */ char const *p = buffer; unsigned prev_n = -1u; unsigned n = 0; unsigned total = 0; for (;;) { char c = *p++; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (n > (-1u - 9)/10) goto parse_error; n = 10 * n + c - '0'; break; case '-': prev_n = n; n = 0; break; case ',': case '\n': if (n > prev_n) total += n - prev_n; total++; if (c == '\n') return (long)total; /* Success! */ prev_n = -1u; n = 0; break; default: goto parse_error; } } parse_error: errno = ENOTSUP; /* What's a good error to return? */ failure: return -1; }