zirias

joined 1 week ago
 

#POSIX #C #programming

So, you want to launch some external tool. Ok, fork()/exec() is simple enough.

But you don't want to "care" for it (wait()) if it's running longer. Ok, just fork some intermediate child, init will adopt it when this child exits.

But wait ... you do want to know if execution itself fails ... or if the tool exits "somewhat quickly" with an error. Okay, this will be interesting ...

Seriously, I'm quite unsure whether this code here is correct. But it's surprisingly large for that "simple" job.
https://github.com/Zirias/xmoji/blob/master/src/bin/xmoji/xdgopen.c#L56

[–] [email protected] 1 points 1 week ago

Only slightly related: #fvwm gave me another thing to consider with its "pages" that aren't virtual desktops (which fvwm can also handle), but an automatically managed larger viewport instead. I just added a commit implementing "bring to the current fvwm page", by looking at the window's position and comparing that to the size of the screen πŸ€” ...
https://github.com/Zirias/xmoji/commit/a3a041af7d41f901b8e795ccb93e8380f03da873
(@[email protected] does that look somewhat sane to you?)

Overall lots of stuff to do (some of that using the magical pager forces 😏) when a secondary instance is started:

  • map window (to leave iconic state if necessary)
  • determine current virtual desktop, move window there (pager-force!)
  • raise window with EWMH-request (pager-force!)
  • just in case (no EWMH or not correctly working), raise it again with a "normal" configure request
  • check window tree to find top-level window (assuming a reparenting WM)
  • check position of that, adjust it if "off screen"

puh ... πŸ™ˆ

 

#X11 #programming #tales – the magic pager powers! 🀩

There's a general problem with windowing systems and desktop environments. You can do stuff with windows like, bring them to the front, activate them, move them to a different virtual desktop, and so on. That's nice until something bad happens like a user accidentally typing sensitive stuff into a wrong window ... or maybe just annoying the user.

So, windowing systems started to do things to prevent this. E.g. they just ignore something an application wants to do ... or replace it with something different (hey, this window wants to be activated, let's flash it in the taskbar instead).

But then, there are very valid usecases where e.g. bringing a window to the front is most likely exactly what the user wants. While implementing single-instance mode (which I plan to make optional of course!) in #Xmoji, I had such a usecase. So, the user only wants to have a single instance of that app running. Yet the user starts it again ... πŸ€” the natural expectation would be that the already running instance appears on the screen as if it was newly started, which is, of course, on top ...

Well, enter #EWMH (which is used for communication with the window manager additionally to #ICCCM in all "modern" environments). They identified that pagers always have valid reasons to do anything to windows. So, they added a field to lots of requests, the "source identifier", which must be set to 1 if the request is issued by a "normal" application, and to 2 if it is issued by a pager. Window managers are required to always obey the pager.

Now for the magic trick: What if we just tell the window manager "hey, I'm a pager"? Oh, I love it! πŸ˜‚ (sudo make me a sandwich style, just better).

Of course that's sarcasm. The initial problem just can't be solved that way. It can only be solved in individual applications, that just shouldn't do unexpected nonsense with their windows. πŸ™„

Side note: #Windows does it differently. An application on a windows desktop can only "self-activate" if the currently active application explicitly passes permission. That's a lot more boring (I can't just pretend something and make the desktop obey me 😞), but also doesn't solve the problem. While I could certainly cover my usecase in Xmoji that way (I mean, the new instance can pass that permission to the already running one), I'm sure there are lots of other valid usecases for e.g. activating a window that just can't be done on a Windows desktop...

[–] [email protected] 1 points 1 week ago

Nice, that looks like the way to do it!

"Funny" how it even offers a libc for compatibility ... but I guess this helps getting it some more serious testing πŸ˜‰

[–] [email protected] -1 points 1 week ago (1 children)

When the answer to major draw backs with a language is use it better that’s a dead end for me.

Try browsing the list of somewhat recent #CVE rated critical, as I just did to verify. A majority of them is not related to any memory errors. Will you tell all them "just use a different programming language"?

And again with OOP. Why hack it into a language rather than use a language that supports it.

Have you seen existing C code? For anything non-trivial, most code uses some OOP, and it comes quite natural in C, certainly no "hacking". You don't need a class keyword to do that.

If it came out today you’d have an incredibly hard time convincing anyone to use it over other languages.

It doesn't come out today, it's been there for a long time, and it's standardized, proven and stable. Sounds like you seriously misunderstood my points, which were, in a nutshell: For applications and similar, just use whatever suits you; for operating systems do experiments in lab/research projects (as was done with Unix), because existing and established ones are relied upon by lots of software. Just to make that perfectly clear, that doesn't mean they should use C forever, it means they should wait for a potential replacement to reach a similar state of stability with independent standards and competing implementations.

[–] [email protected] -2 points 1 week ago (6 children)

I'd say if you're happy with #C, there's no need to choose any second language. 🀷

Before even looking at any alternatives, the question should be "why not C". Some of the typical complaints are:

  • memory safety – or, more generally, the fact that C is only partially defined, leaving a lot to the dangerous area of undefined behavior. There's no way to reliably detect undefined behavior by static code analysis, and it will often hide well at runtime. Especially errors regarding memory management often directly expose security vulnerabilities. In my experience, the risk can be reduced a lot by some good coding and design practices. Examples are avoiding magic numbers, using sizeof everywhere possible, preferably on expressions instead of type names, defining clear ownership of allocated objects (and, where not possible, add manual reference counting), making ownership explicit by using const where appropriate and naming your functions well, and so on. Given also there's no guarantee alternative languages will safeguard you from all the possible issues and there are also a lot of other ways to create security vulnerabilities, my take on this would be: partially valid.
  • programming paradigm – you can only program in classic procedural style. Well, that's simply not true. First of all, you can program whatever you want in any turing-complete language, so what we talk about shouldn't be what's directly supported by the constructs of the language, but what's practically usable. In C, using some simple OOP is commonplace. Well, you can apply OOP to assembler programming without too much hassle, so, it's not surprising you can do it in C, as it's a pretty thin abstraction on top of machine code. C helps further with its linkage rules, where everything in a compilation unit is by default inaccessible to other units, and its incomplete types, where only a type name is known, but neither its size nor inner structure, giving you almost perfect information hiding for free. If you want/need polymorphism, it gets a bit more complicated (you have to think about how you identify types and manage virtual tables for them), but still perfectly doable. You'll hit the practical limits of the language when you want to go functional. The very basics are possible through function pointers, but most concepts of functional programming can't be applied to C in a somewhat sane way. Unless that's what you need, my take would be: invalid.
  • limited standard lib. Indeed, the C standard library misses lots of things that are often needed, for example generic containers like lists, hashtables, queues, etc. It's straight-forward to build them yourself, but then, there are many ways to do that (with pros and cons). You'll find tons of different implementations, many non-trivial libraries bring their own, of course this also increases the risk to run into buggy ones ... I wouldn't consider it a showstopper, but I'd mark this complaint as: valid.

Then, the next question would be: For what purpose are you looking for a second language?

For applications and services, there's already a wide range of languages used, and I'd say do what everyone does and pick what you're most comfortable with and/or think best suits the job. IOW, it makes little sense to ask what would be "the future", there have always been many different languages used, just pick one that's unlikely to quickly disappear again, so you'd have to restart from scratch.

For systems programming "the future" has been C for many decades 😏 ... some people want to change that, actually for good reasons. IMHO, the current push for #Rust (I don't see anything similar regarding #Zig yet?) into established operating systems is dangerous. An operating system is very different from individual apps and services. It's required by these as a reliable and stable (in terms of no breaking changes) platform. It's complex and evolves over an extremely long period of time. It needs to interface with all sorts of hardware using all sorts of machine mechanisms (PIO, DMA, MMIO, etc pp). I conclude it needs a very stable, proven and durable programming language. You'll find C code from the 30 years ago that just still builds and works. IMHO a key factor is that there's an international standard for the C language, governed by a standards body that isn't controlled by any individual group. And correlated to that, there are many different implementations of the language. Before considering any different language in core areas of an established operating system, I'd like to see similar for that new language.

Now, C was developed more or less together with #Unix, so back then, nobody knew it would be such a success, of course there was no standard yet. But then, I think this is the sane way to introduce a new systems programming language: Use it in a new (research?) OS.

[–] [email protected] 2 points 1 week ago

Sure, that's yet another aspect. #Javascript (#ECMAscript to be precise) evolved a lot. Where we came from was a very limited standard and browsers doing their own incompatible thing, also adding "random" bugs, which btw triggered development of #jQuery, back then an extremely helpful thing, nowadays more or less obsolete. I'm sure writing a well-working #SPA with nothing but vanilla JS is perfectly possible these days, it just requires some planning and design, you'd probably end up with a (minimal and tailored to your needs) "framework" as part of your project. But from my experience, most "frontend devs" are indoctrinated into a strong belief you absolutely need super-fat frameworks for everything.

What I was talking about is that these you mentioned (React, Angular) are designed with nothing but SPA in mind. So, everything will end up being an SPA, which just makes no sense for 95% of "web apps". There's a nice set of architecture guidelines for web apps called #ROCA, which is in line with the initial design of #http and the web in general: https://roca-style.org/ -- and then, you decided in your organization to follow that, you have the need for some enhanced UI components in JS, and these frontend guys basically keep telling you "we need our awesome framework here". Oh boy. 🀦

In the end, I see the resident set of my local browser and have no questions left...

[–] [email protected] 4 points 1 week ago (2 children)

Side note, it's not so much React, Angular, Vue or whatever that sucks, it's the concept behind: #SPA. Or, more precisely, that concept used not in a niche where it belongs, but for every damn web site, or classic form-based web app. I remember getting into some very weird arguments with "frontend devs" over a simple demo class I wrote in vanilla JS to "enhance" a standard browser control (so, it still worked without a script). This class was pretty short and clean. Still they insisted it would be "hard" to program like that. It seems they can't do the simplest things any more without the help of their massive shitloads of "frameworks". And then, everything is a stupid SPA in the end, completely breaking the logical design of the web.

Ok, back to admiring the pure elegance of #C, sorry πŸ˜‚

CC: @[email protected] @[email protected]

[–] [email protected] 1 points 1 week ago* (last edited 1 week ago) (1 children)

I like it and I'd love to see much more clean and simple #C code for self-hosted web services (with #http). It looks like a project I might want to get involved, will certainly browse through the code soon. A quick question, what's the deal with all these xs_* modules? Is it about perl integration? πŸ€”

CC: @[email protected]