frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

1•johngai•25s ago

CRDTs #2: Turtles All the Way Down

https://jhellerstein.github.io/blog/crdt-turtles/
1•pfarago•5m ago•0 comments

Silly job interview questions in Haskell

https://chrispenner.ca/posts/interview
1•behnamoh•7m ago•0 comments

STS-61

https://en.wikipedia.org/wiki/STS-61
1•sarego•13m ago•0 comments

Show HN: I made a zero-setup back end API to launch apps without coding back end

https://github.com/broadwayinc/skapi-js
1•skapi_api•14m ago•0 comments

Mistral Document AI

https://mistral.ai/solutions/document-ai
2•ianhawes•18m ago•0 comments

Banana Pi BPI-Forge1 Is a Low-Cost RK3506J-Based SBC Compatible with RT-Thread

https://linuxgizmos.com/banana-pi-bpi-forge1-is-a-low-cost-rk3506j-based-sbc-compatible-with-rt-thread/
1•PixelN0va•21m ago•0 comments

Our Problem with Backlogs

https://www.octomind.dev/blog/our-problem-with-backlogs
1•thunderbong•21m ago•0 comments

Tariff Exemptions Are Terrible News for Electronics Repairability

https://www.ifixit.com/News/110121/tariff-exemptions-are-terrible-news-for-electronics-repairability
1•gnabgib•25m ago•0 comments

Ask HN: How do you feel about using AI tools on your phone? Privacy vs. Utility

1•fallinditch•42m ago•1 comments

Good Performance for Bad Days

https://brooker.co.za/blog/2025/05/20/icpe.html
1•SchwKatze•44m ago•0 comments

Kling 2.0: ready to turn your ideas into motion

https://twitter.com/wavespeed_ai/status/1925049015126970378
1•sylm•47m ago•0 comments

Bodybuilding star Nikita Tkachuk dead at 35

https://www.the-sun.com/sport/14296862/bodybuilding-star-nikita-tkachuk-dead-muscle-growth-injections/
2•wslh•53m ago•0 comments

US Treasury to stop producing pennies next year

https://www.bbc.com/news/articles/cx2j07858lno
2•DarkContinent•53m ago•0 comments

Show HN: I created a tool intro.new – Make your intro page in seconds

https://intro.new/
1•hellohacker007•53m ago•0 comments

A wave of new owners brings fresh energy to independent bookselling

https://apnews.com/article/independent-bookstores-growth-younger-owners-28ac30a97fbb44a848bc858cdfe8cc16
1•petethomas•55m ago•0 comments

Drop your discounts for founders or users

1•tommat32•59m ago•0 comments

A.I. Is Poised to Revolutionize Weather Forecasting. A New Tool Shows Promise

https://www.nytimes.com/2025/05/21/climate/ai-weather-models-aurora-microsoft.html
2•bookofjoe•1h ago•1 comments

New method for creating large 3D models of urban areas is faster and cheaper

https://techxplore.com/news/2025-05-action-movies-urban-method-large.html
2•PaulHoule•1h ago•0 comments

Should I teach my kids to use AI?

https://www.vox.com/even-better/413703/kids-ai-chatbot-cheating-chatgpt-children-parenting
1•lr0•1h ago•0 comments

New DSL "MassQL" lets scientists query mass spectrometry data

https://news.ucr.edu/articles/2025/05/12/new-computer-language-helps-spot-hidden-pollutants
2•jacklondon•1h ago•3 comments

DuckDB 1.3.0

https://duckdb.org/2025/05/21/announcing-duckdb-130.html
4•friendly_deer•1h ago•0 comments

Building Twice: A clone of Once

https://stanko.io/building-twice-a-clone-of-once-gJKxLYCe26Ak
11•Kerrick•1h ago•0 comments

Big Banks Explore Venturing into Crypto World Together with Joint Stablecoin

https://www.wsj.com/finance/banking/crypto-stablecoin-big-banks-a841059e
5•pdecker•1h ago•0 comments

Why is your open source project still hosted on GitHub?

https://unixdigest.com/articles/why-is-your-open-source-project-still-hosted-on-github.html
2•cratermoon•1h ago•3 comments

What's the best AV1 encoder in 2025? I encoded four thousand GIFs to find out

https://catskull.net/libaom-vs-svtav1-vs-rav1e-2025.html
3•catskull•1h ago•0 comments

Self-hosted GitHub Actions runners aren't free

https://depot.dev/blog/self-hosting-github-actions
1•Telstrom90•1h ago•0 comments

Jupiter Was Twice Its Current Size, Scientists Discover

https://www.sciencealert.com/jupiter-was-twice-its-current-ginormous-size-scientists-discover
4•toss1•1h ago•2 comments

Google faces a dilemma: improve Google Search or go beyond it?

https://eshumarneedi.com/2025/05/21/google-eats-everyones-lunch-at.html
7•freediver•1h ago•0 comments

Mitre ATT&CK: Enterprise Techniques

https://attack.mitre.org/versions/v17/techniques/enterprise/
3•stefankuehnel•1h ago•0 comments
Open in hackernews

Ratatoi is a C libary that wraps stdlib's strtol (as atoi does), but it's evil.

https://github.com/rept0id/ratatoi
30•rept0id-2•1d ago

Comments

rept0id-2•1d ago
Ratatoi is a C libary that wraps stdlib's strtol (as atoi does), but it's evil.

If an overflow is detected, it calls abort(), you crash and get Aborted (core dumped).

This way, you prioritize memory safety over silently running in a wrong state, without needing to call strtol and check errors manually everywhere.

timewizard•1d ago
"This way, you open yourself up to DDoS attacks, instead of just handling your own errors correctly."
kstrauser•1d ago
I prefer this approach. It's kind of like using `.expect()` or `.unwrap()` in Rust when there's no plausible way the call should fail. Like if my program writes out a JSON file and then reads it back in, and the file isn't value JSON, panicking is a reasonable way to deal with the situation. Someone the world got itself into a strange state I can't reasonably recover from.

Well, same here. If you're using strtol on data that must be well-formed, and it's not, and you're at an earlier stage of startup like parsing the config file, go ahead and blow up. That's almost certainly better than plowing ahead with invalid data.

LukeShu•1d ago
> Like if my program writes out a JSON file and then reads it back in, and the file isn't value JSON, panicking is a reasonable way to deal with the situation.

Like how if I hit ctrl-C at just the right moment during the build, the next time I build, cmake will segfault and I have to delete the build directory.

threeducks•1d ago
I think strtol is just a badly designed function. The return value should have been an error code and the actual long should have been "returned" via a pointer. Checking the return value is much easier than checking endptr and errno and remembering to set errno before calling strtol.

The fact that the strtol example in the manual is 50 lines long, of which most is error handling, speaks for itself. https://man7.org/linux/man-pages/man3/strtol.3.html#:~:text=...

That being said, I can't imagine many applications where crashing is a good solution.

wahern•1d ago
OpenBSD added strtonum to <stdlib.h>. It's quite opinionated, but fits the usage patterns OpenBSD developers prefer.

> 50 lines long, of which most is error handling

That's a little exaggerated considering the example is an entire C program, including main. It's more like 14 lines, ignoring the '\0' check (which isn't necessary if you don't want to parse additional items), and even that includes whitespace and stderr logging.

I agree the biggest headache is reliance on errno and the nuanced--albeit conventional, consistent[1], and documented--semantics of only setting errno on error. Some POSIX APIs, at least those defined from scratch (e.g. pthreads, as opposed to incorporated common extensions) prefer returning the error code directly as you recommend. But this would technically only save you a single line, though it might save alot of confusion about semantics.

However, in this case I might keep returning the value directly and take an error pointer, similar to OpenBSD's strtonum. Otherwise you would need separate routines for char, short, int, long, and long long. Though there's still the issue of unsigned integers, and using _Generic it might be possible to at least hide all the type-specific variants behind a single interface.

And there's still the issue of needing to check for trailing garbage, or dropping the ability to use the interface inline with other parsing code. There's alot of dimensions to the problem. Parsing integers may be conceptually simple[2], but designing an interface that's easy to integrate into applications across a variety of contexts is much less simple.

[1] Consistent across libc interfaces, excepting those that may invoke syscalls internally, like printf, where errno may be incidentally modified even on success.

[2] I personally often prefer to just write a simple loop to manually parse integers. It's sometimes easier to integrate the desired error checking inline, or even elide it altogether (garbage-in, garbage-out).

roelschroeven•1d ago
> conventional, consistent[1], and documented--semantics of only setting errno on error.

From that man page:

> The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).

There are error cases where the implementation may set errno to EINVAL. There's not even a guarantee. I did a quick test. errno is only set if you pass an invalid base, or if the string does contain a number but it is out of range. If you pass a string which doesn't even remotely look like a number, errno is not set. You have to check endptr.

  #include <errno.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  int main(void)
  {
    const char *s = "this is not a number";
    printf("strtol(\"%s\")\n", s);
    errno = 0;
    long a = strtol(s, NULL, 10);
    printf("errno: %d; strerror: %s\n", errno, strerror(errno));
    printf("result: %d\n", a);
    return 0;
  }
Output:

  strtol("this is not a number")
  errno: 0; strerror: Success
  result: 0
https://godbolt.org/z/TbEKss8zM

That's just rubbish design. In what is in my opinion the most common error case, namely that the string doesn't represent a number while you expect that it does, errno is not set.

spyrja•1d ago
Personally I'd just go the wrapper approach and ignore errno entirely.

  #include <assert.h>
  #include <ctype.h>
  #include <limits.h>
  #include <stdbool.h>
  #include <stdint.h>
  #include <stdlib.h>

  bool copy_str_to_long_long(const char* str, long long* ptr) {
    while (isspace(*str))
      ++str;
    if (*str == 0)
      return false;
    char* parsed = NULL;
    long long value = strtoll(str, &parsed, 0);
    while (isspace(*parsed))
      ++parsed;
    if (*parsed != 0)
      return false;
    *ptr = value;
    return true;
  }

  long long str_to_long_long(const char* str) {
    long long result;
    assert(copy_str_to_long_long(str, &result));
    return result;
  }

  bool copy_str_to_long(const char* str, long* ptr) {
    long long buffer;
    if (!copy_str_to_long_long(str, &buffer) || buffer < LONG_MIN || buffer > LONG_MAX)
      return false;
    *ptr = buffer;
    return true;
  }

  long str_to_long(const char* str) {
    long result;
    assert(copy_str_to_long(str, &result));
    return result;
  }

  /*
    ...define copy_str_to_short, copy_str_to_int32, etc...
  */
gpderetta•1d ago
C can actually return structs by value and small structs are actually handled quite efficiently in some ABIs, so a pair result/error would be quite convenient although I guess not idiomatic.
PaulDavisThe1st•1d ago
> The return value should have been an error code and the actual long should have been "returned" via a pointer.

Oh, you mean like:

    int ret = sscanf (str, "%d", &value);

?
sltkr•1d ago
Yes, that API is actually great, but the problem with (s)scanf() is that reading an invalid value is undefined behavior. So you can't use it if you don't already know the result fits in &value, which is exactly the situation where you'd use strtol() instead.
CamperBob2•1d ago
Presumably 'undefined behavior' means you'll get an undefined int value back -- which you will (of course) range-check -- not that it will wipe out the next 600KB of memory starting at &value or do something similarly hazardous.
roelschroeven•1d ago
No, that's very much not what undefined behavior means. Undefined Behavior (the man page on my system actually capitalizes both words) means that there are no guarantees at all about the behavior of the whole program. It can very much wipe out whole chunks of memory, or crash (not necessarily in or around the sscanf call), or get stuck in an infinite loop, or whatever.
PaulDavisThe1st•1d ago
From the man page on my system:

> Use of the numeric conversion specifiers produces Undefined Behavior for invalid input. See C11 7.21.6.2/10 ⟨https://port70.net/%7Ensz/c/c11/n1570.html#7.21.6.2p10⟩. This is a bug in the ISO C standard, and not an inherent design issue with the API. However, current implementations are not safe from that bug, so it is not recommended to use them. Instead, programs should use functions such as strtol(3) to parse numeric input. This manual page deprecates use of the numeric conversion specifiers until they are fixed by ISO C.

CamperBob2•1d ago
If the CRTL maintainers don't care, why should I? Such behavior is broken, not "undefined."

As the other poster points out, the bug is in the spec, and I'd be astonished if the library function itself actually misbehaves with any given input.

roelschroeven•3h ago
The bug is in the spec, but as the other pointer also points out:

> However, current implementations are not safe from that bug, so it is not recommended to use them. Instead, programs should use functions such as strtol(3) to parse numeric input. This manual page deprecates use of the numeric conversion specifiers until they are fixed by ISO C.

In other words, sscanf itself is not safe to use for numeric conversions.

Why should you care? Depends. Do you care about writing correct programs? If not, there's no need to care.

duneroadrunner•1d ago
So I don't write much C code these days, but I recently encountered strtol() again and am I mistaken or does the interface also violate const correctness? I mean it takes a const char* as the first parameter and then gives you back a (non-const) char* potentially pointing into the same string, right? Like, does strtol() get a pass because it's old, or is const correctness (still) not generally a concern of C programmers?
jefftk•1d ago
There are unfortunately a lot of old C library functions that violate const correctness. Consider dirname: https://www.jefftk.com/p/dirname-is-evil
spyrja•1d ago
More than a few C library functions do that kind of thing. Like `strstr`, which takes const strings as arguments but returns a readily modifiable pointer to char. Const-correctness just wasn't on the top of the list when they standardized this stuff, I guess. (Heck, back in those days, most PROGRAMS for that matter weren't written with much care for it.)
wahern•1d ago
It's a consequence of the peculiarity of C type semantics, which disallows implicit conversions of pointer-to-pointer to pointer-to-pointer-to-const. C23 6.5.16.1 EXAMPLE 3 explains why:

  const char **cpp; char *p;
  const char c = ’A’;
  cpp = &p;   // constraint violation
  *cpp = &c;  // valid
  *p = 0;     // valid

  The first assignment is unsafe because it would allow the 
  following valid code to attempt to change the value of the 
  const object c.
There are proposals on the table for C2y to redefine various APIs, including strtol, strchr, memcpy, etc, to preserve const correctness. Implementations might make use of _Generic (there are some issues there, though), newly specified language features, or possibly use internal extensions not available in the language proper, to accomplish this.
tedunangst•1d ago
The idea is that if the input was not const, it's really inconvenient to get a const endptr back out. If your intention is to break your program, there are easier ways to do so than washing the pointer through strtol.
hedora•1d ago
Crashing on error is almost always the right default behavior. If you do anything else by default, then you get in to the land of data corruption and security holes.

If you do this, and then find your thing crashes in production, then that means you didn't test it well enough.

Before someone mentions safety critical systems, consider the fact that the first apollo landing's computer crashed when it detected it was violating realtime bounds ("alarm 1201" means the OS detected CPU exhaustion + rebooted without clearing process state). At that point, it went into a reboot loop, and got close enough to the surface for Neil Armstrong to nudge the lander to a safe landing.

https://apollo11space.com/apollo-11-computer-problem/

bmink•1d ago
I love the Apollo 11 computer stories but by today’s standards it was more of an MCU than a computer. And sure, in the embedded space it is true that in a lot of cases error recovery doesn’t make a whole lot of sense and it makes more sense to reset quickly.

But there are many systems today that take a long time to restart so you can’t just abort if you have a chance to recover.

AlotOfReading•22h ago
The Apollo guidance computer specifically had a pretty unusual definition of "crashing" too. What it would do is save all the critical data, turn everything off, reinitialize the hardware, and restart all the jobs from designated reentry points. Very unlike what we think of as crashing. Regardless, a modern boot chain is much more complicated than anything the Apollo computers had to deal with, where rebooting (as opposed to the safe restart procedure above) simply involved setting the program counter to some default value.
lunar-whitey•21h ago
The LM computer’s recovery routines for this scenario are more accurately described as “checkpoint/restore” than “crash” (as most people would understand the latter). The former technique is still used in high availability systems today.
lunar-whitey•22h ago
This summary of events is incorrect. The LM guidance computer’s executive routines detected an overload (which occurred because Buzz Aldrin had left the rendezvous radar on) and continued to operate in a degraded state where lower priority work was not performed. These faults were reported and the landing proceeded with the computer remaining responsive to inputs despite the concerns the alarms produced. Armstrong’s control changes near the end of the descent were made for reasons unrelated to the rendezvous radar error.

Modern systems use more formal techniques to achieve the same goal: graceful degradation.

For a detailed account of computer operations during the Apollo 11 landing, you can read this analysis from an engineer who worked on the program:

https://www.doneyles.com/LM/Tales.html

ksherlock•1d ago
Your errno checks aren't correct.

errno is only set on an error. It's not cleared on success. If errno was previously set, the function will always abort(). So you need to do something like:

    int saved_errno = errno;
    errno = 0;
    ....
    errno = saved_errno;
    return aInt;
ben0x539•1d ago
Doesn't it set errno to 0 first thing?
ksherlock•1d ago
ahh, you're right. It's still polite to save and restore though :)
rantouan•11h ago
not bad, check my suggestion for pull request, above
kazinator•1d ago
No ISO C standard library function sets errno to zero, but functions not in the standard library are not so obliged.

Functions that clobber errno to zero make it impossible to call several functions and use a nonzero value of errno to conclude that one or more of them went wrong.

If you don't think that such code is a good idea (for instance because you believe that every function that can fail should be checked for its specific error), then you probably have nothing against functions which clobber errno to zero.

rantouan•11h ago
hello, errno is set to 0 first thing.

I added now a "/** * * */" separator to make it even more clear.

I don't know, but I like separating things like that, I think it's handy for cases like now that setting the errno was kind of mixed with vars initialization.

```

    errno = 0;

    char *strtolEndptr;
    ...

```

->

```

    errno = 0;

    /*** * * ***/

    char *strtolEndptr;
    ...
```
rantouan•11h ago
For the restoring part, could you make a pull request please ? Open source strength is that we work together on things.
snarfy•1d ago
pun driven development
cmovq•1d ago
Interestingly, a complete implementation of strtol [1] is shorter than this wrapper. If you don't like strtol's API or error handling, just implement your own.

[1]: https://github.com/gcc-mirror/gcc/blob/master/libiberty/strt...

> If an overflow is detected, it calls abort()

An aside, but this doesn't detect overflows on Windows due to both long and int being 32 bits (you'd want strtoll for that).

kazinator•1d ago
Where is it documented that atoi wraps strtol?
rantouan•12h ago
https://www.gnu.org/savannah-checkouts/gnu/libc/index.html : The project website can be found here: https://sourceware.org/glibc

->

https://sourceware.org/ Links table on the left -> "GLIBC" button

->

https://sourceware.org/glibc/ Top menu -> "sources"

->

https://sourceware.org/glibc/sources.html "gitweb" link

->

https://sourceware.org/git/?p=glibc.git Top menu -> "tree" link

->

https://sourceware.org/git/?p=glibc.git;a=tree Tree -> "stdlib" link

->

https://sourceware.org/git/?p=glibc.git;a=tree;f=stdlib;h=93... Tree -> "atoi.c" row -> "raw" link

->

https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdli...

``` /* Convert a string to an int. / int atoi (const char nptr) { return (int) strtol (nptr, (char *) NULL, 10); } libc_hidden_def (atoi) ```

eqvinox•1d ago
"long" is not guaranteed to be larger than "int", and in fact it isn't on 64-bit Windows. (Let alone 32-bit platforms in general.)

https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_m...

You need to use "long long" or "intmax_t" (and matching strtoll/strtoimax)

rantouan•11h ago
overflow problems, which I try to avoid, start only if its bigger than int.

So I had assumed that in my case I'm alright. Do you see any change needed that I can't see ?

---

Maybe a good idea would had been to go by platform or architecture and use some macros to do the check only if it's really needed. What do you think of it ? How would you implement it ?

You can make a pull request as well.

eqvinox•9h ago
If strtol reliably sets errno to ERANGE, you're fine (you'll get a compiler warning for "if (aLong < INT_MIN || aLong > INT_MAX) {" though, because it can never be true.)

I have no idea what the cross-platform reliability of strtol() is, regarding errno. Should be fine, I hope.