HN user

rand_flip_bit

68 karma
Posts1
Comments32
View on HN

You could already do this before the port change, you just need a USB-C to Lightning cable (which has been included in the box for a few years now). Being able to use the same cable is nice and all, but in practice I want two or more cables anyway to charge multiple devices at the same time. If one of those cables happens to have a different connector on one end it isn't the end of the world.

I'd suggest that the people who make "full use" of vsc-over-ssh are satisfied with vscode, so it would be unwise to target the full featureset.

Remote SSH + Dev Containers and their seamless integration (even stacking one on the other) are the only features that keep me using VS Code. I would love to see the full implementation of these in an editor as fast and light weight as Zed.

Both the git log and git bisect commands accept the --first-parent flag, which eliminates the complexities of dealing with merge commits in the history.

It's not like you paid for it.

There are individuals that pay ~$4/month for GitHub Teams, plus other services (Copilot, CI, LFS, Packages, etc). They may not have public repos, but that shouldn't matter.

I think part of this stability stems from the upstream repos being more stable themselves (cheaper and easier than ever to run CI, quality of tools, etc). It's not often that upstream packages break their stable releases, or heck even develop/master.

It also seems like the firehose of upgrades that is Sid/Experimental has slowed down a bit. Even Sid is still on nodejs 18 and not 20 or 21. The same version as both Testing and Stable.

I feel at home at home with Debian Testing, not as bleeding edge as Arch for sure, but I think that is more of a blessing than a curse. The Debian maintainers seem to know what they are doing and the distribution has a sense or maturity that some others lack. I just hope an update won't break GRUB on me :)

Only downsides to running Debian Testing is that it doesn't get security updates with the same speed as Sid or Stable, and third parties don't exactly put together and distribute pre-built packages for Testing specifically. I understand why, but it makes me wonder if things will break due some ABI compatibility issue down the line. Maybe once Debian 13 is released I'll just stick to stable.

But nothing about upscaling, nor frame generation, sounds like something that requires game engine support to me. The graphics card should have enough info to do that by having all the pixels.

Modern upscaling solutions (eg TAA) require not just the pixel outputs but various inter-frame/metadata such as depth, normals, motion vectors, last frame, etc. DLSS is more or less just the spiritual successor to TAA with machine learning sprinkled in. Integration with the game engine is needed because the non-color metadata needs to be provided to the DLSS and how each engine computes those things is a bit different.

Just to reiterate on this point: Pretty much every Vulkan game on Windows forgoes using Vulkan Swapchains in favor of presenting from compute and using native DXGI Swapchains. If you are shipping a production quality game or application, you really want to use the platforms native APIs to get the full capabilities.

Privacy.com allows you to use completely made up billing information - transactions won't get rejected if the name/address is a mismatch. You can just feed a fake name and address into each site, even if they wanted to, how would they identify you? Of course, this likely works best if you use an email aliasing service that hides your real email completely, and a VPN to obscure your physical IP address.

As another commenter pointed out, this is obsolete C, however: this is just not how modern compilers work. at all. Compilation is performed in phases, you have syntax analysis, semantic analysis, and then optimization and codegen. It’s trivial for a compiler to handle this code, heck C++ compilers (which your C compiler is under the hood) already do this for struct/classes (allowing member functions to be called before being declared). Pretty much every other language supports this too, but universally and not just in classes. We’ve come a long way since the 60’s.

100% the data you input to the ChatGPT 4 prompt window is being used to train ChatGPT 5, there is a reason a lot of companies are placing bans on it and telling employees to never enter sensitive data.

I sincerely hope that LLMs won’t play a role in search, I don’t need a search engine trying to infer what I “meant” to type, Google and DDG started doing that and pushed me to Kagi as a result. Just take the words I type verbatim and search them in your index, don’t assume this is my first time using the internet.

Ughh, please don’t. The last thing I want in my search engine is AI, especially for a “privacy focused” one like Kagi. Paying to have all my search queries get routed through ChatGPT (and effectively used as training data) is absolutely not what I want. I suspect it’s too late though, Kagi has already drank the AI koolaid.

Huh? Windows 10 has been shipping the C standard library for quite a while now, you don’t need to ship any redistributables... yes you need to static link the C++ standard library but that is also a requirement if you ship on Linux since Debian/Ubuntu always have horrendously outdated copies, heck I have customers that still use Ubuntu 16 that I have to support.

At the end of the day none of this is any different from shipping containers or flatpaks, which bundle all the dependencies with them. In many ways Windows has escaped the DLL hell that plagued it in the past, whereas Linux still has some learning to do.

Depends on when you go. If you show up during lunch/hour when the line is getting long they absolutely will over scoop. It isn’t worth it for them to slow down the line when every customer asks them “can you scoop more” at every single step. They just over scoop to keep people quiet and keep the line moving. The difference is about 2x an online or off-peak order, and about 3x a late night order (hour before closing). Just my experience though.

There is no such thing that allows you to avoid the race condition. There are a few issues:

- You can't control every call to open, and thus enforce O_CLOEXEC on all files (by default)

- Because of this, most files will be leaked into the child, this is likely not desirable, especially since some distros have low open file limits for processes

- posix_spawn (the replacement for fork/exec) allows you to specify a list of file actions to perform, including opening and closing, this seems like a solution at first glance

- However, there is a TOCTOU race here, as you need to first make a list of file actions with posix_spawn_file_actions and then call posix_spawn. Note that every file you want to close needs to have it's own file action, this means you need to determine all the files that are open and manually add each one. This alone introduces the problem of determining all open files in your process.

- In a multi-threaded program it is possible for another thread to open a file between the calls to posix_spawn_file_actions and before posix_spawn, thus creating the potential for files to leak into the child.

- Even in a single threaded program, it is possible for posix_spawn to to invoke functions established with pthread_atfork, and atfork handlers are allowed to call signal-safe functions, including but not limited to open. Implementations aren't required to call atfork handlers, and modern glibc doesn't, but this is by far no guarantee.

- Therefore, my argument is that posix_spawn cannot be used to create a process with a guaranteed minimal and clean state, and so you are back to square-one with fork/exec.

The defaults for working with these APIs are just completely wrong, and very hard to get correct. The issues with fork/exec are numerous and nuanced, and most people simply aren't aware of the issues or don't care. There is a specific song and dance that needs to be performed when using fork/exec and usually you want to hide all of that behind a library function... which will look something similar to CreateProcess.... sure you might use the builder pattern to make it look nicer, but you really don't want the fork/exec split.

Here are few other issues with fork/exec, non-exhaustive:

- Only signal-safe functions can be invoked between fork and exec. This means you need to be super careful with any stdlib code you invoke between these two (or better yet, just don't).

- Multithreaded programs cannot call fork without exec. period. The state of objects such as mutexes and condition variables will be inconsistent. This is implied by the above, but I wanted to specifically call this out.

- Detecting if exec failed instead of the program requires using an extra pipe marked with CLOEXEC, I have seen too much code using a magic exit code (which is wrong)

- Cleaning up the state of the child process and not accidentally creating a zombie is a bit tricky and there are some race conditions to be aware of. pidfd is not a solution if you need to support older kernels, although helps tremendously.

- Interaction with signals is a bit messy.

- When fork is called, all pages will be marked as copy-on-write, this can be slow for processes with lots of memory allocated, and is completely redundant if your goal is to call exec. If other threads exist and are writing to memory, the pages they touch will be copied unnecessarily.

- Like I harped on earlier, files are inherited by default, not the other way around. You should be required to manually list the fds that you want the child to inherit (likely stdin, stderr and stdout only for 99% of cases).

- Distinguishing exec failure from exceeding but the process failing requires a CLOEXEC pipe

- If exec fails, _exit must be called! you cannot terminate the child in any way that might run destructors, of invoke callbacks/handlers as these can perform I/O and would thus be observable.

CreateProcess is just much better, and the whole "it takes 12 parameters how awful" argument against it is 100% a non-issue. It isn't 1960 anymore, it's okay to have a function with a name longer than 6 letters and more than 3 parameters.

Pedantically, C’s runtime doesn’t parse the command line arguments, CommandLineToArgvW does, and that function lives in shell32.dll, not the C runtime (Nor is it dependent on the C runtime). Ofc the C runtime is free to ignore that routine and implement parsing itself using the results from GetCommandLine. Either way though, yeah, it has to parsed in the child process. But that isn’t a huge bottleneck.

It’s fair to say the initial surface area of the API is more complex (at first glance). However, fork/exec don’t really scale that well beyond toy examples you see in blogs or CS101. Thing is, if you are using fork/exec, you are likely also calling a few other functions for things like redirecting IO, dealing with exec failing (creating a pipe with O_CLOEXEC, and you need to remember to use _exit instead of exit (or anything else) if exec fails. Plus there is all the complexity of dealing with the child pid, signals, not accidentally creating a zombie, etc. Ohh not to mention that all the pages in the processes memory need to be marked copy-on-write when fork is called, only for that to be reversed when exec is called. I hope you don’t have dozens or hundreds of gigabytes allocated in a multithreaded program, that will cost you. Ohh and of course, you can’t call anything between fork and exec that isn’t signal safe, so you need to be really careful, especially in languages with implicit allocation or exceptions. Ohh bonus points for the fact that it’s ill-formed for multithreaded programs to call fork without exec since that can leave things like locks in inconsistent states.

The way both APIs handle file inheritance is absolutely horrendous, especially since most libcs don’t set the necessary flags. posix_spawn doesn't solve this either, since posix_atfork can open more files in the child, and multithreaded programs can have a TOCTOU bug if another thread opens files between the call to posix_spawn_file_actions and posix_spawn. TBF Windows is actually worse in this regard, since it’s race condition is a little more subtle. Ironically the best to way manage all of this nonsense is to create a child process first thing in main (another binary), which isn’t multithreaded, closes almost all files (uses a whitelist of fds) upfront, and spawns processes on behalf of the parent when requested (IPC). Ideally you would write this in C, minimize usage of libc, and avoid allocating tons of memory.

Curious why you think CreateProcess is worse than fork/exec. Sure it takes about a dozen parameters but is that really the end of the world?!? It’s much much easier to use correctly and doesn’t have nearly as many of the pitfalls as fork/exec. Especially in large processes with lots of memory allocated. I genuinely don’t understand why people dislike it so much.

Sadly, this actually isn’t true, and can cause some dangling/use-after-free issues. An empty string_view has a length of zero, but it’s representation might contain a null/non-null pointer + zero or two pointers that “compare equal”. I put compare equal in quotes because pedantically, after delete/free are called, they will not be required to compare equal.