Re: [dev] [dwm][st] why use ints over bools?

2024-06-21 Thread Markus Wichmann
Am Thu, Jun 20, 2024 at 11:53:45PM +0200 schrieb Страхиња Радић:
> Given that, why complicate code by introducing a separate, superfluous,
> type?

Let me offer a counterpoint: Expressiveness. If I make a function return
a bool, then everyone from the world's worst junior dev to Ken Thompson
himself will be able to see at the very first glance that the function
is returning a boolean value. If I make a function return an int, that
is not so clear.

That said, if a function returns bool and is longer than one or two
statements, it is probably already doing something wrong. I have seen
bool used as error code, and it is such a missed opportunity to return
an enum of error codes to say what actually went wrong.

> Every new iteration of C after C99 introduced more unnecessary cruft.
> C99 is the best version, although it has its rough edges, one of which
> is the _Bool type.
>

All versions of C after C89 added more stuff that wasn't there before.
That is mostly the point. You cannot remove things without introducing
an incompatibility. So the only thing I can remember that was ever
removed was gets(), which was a bad idea from the start, and finally
removed in C11.

I don't know, to me statements like "C99 is the best version" are always
funny. Not so long ago, this very list opined that C89 is the only true
C standard and everything that came after is "not C", as I recall. Which
is literally wrong, of course (C is whatever WG14 says it is, whether
you like it or not).

Isn't it all about familiarity in the end? Or can you articulate what
parts of C11 and C23 you find objectionable?

Ciao,
Markus



Re: [dev] [dwm][st] why use ints over bools?

2024-06-17 Thread Markus Wichmann
Am Sat, Jun 15, 2024 at 06:10:50PM +0200 schrieb Vincent Lefevre:
> IMHO, this has been poorly designed. There should have been a macro
> taking a parameter N (an integer constant expression), where the
> type would have been valid for any N up to the maximum width (thus
> at least 64). For portability, the existence of the macro could have
> also been tested with #ifdef, allowing a fallback.

Well, there is INT_LEAST${N}_MAX from stdint.h, telling you that type
int_least${n}_t exists. And C23 has the new _BitInt(N) types, if that
helps any.

Of course, you can also just face up to reality and notice that you will
likely never work on a machine with CHAR_BIT != 8, and even if you do,
it will be unlikely to have CHAR_BIT % 8 != 0. Therefore, any
int_least${n}_t with $n % 8 != 0 is unlikely to exist.

Ciao,
Markus



Re: [dev][ubase] passwd runtime error on musl

2024-03-22 Thread Markus Wichmann
Am Thu, Mar 21, 2024 at 06:01:25PM -0300 schrieb Brian Mayer:
> Hello.
>
> I compiled ubase using GCC and musl, but using passwd gives me an error 
> message:
>
> $ passwd root
> passwd: getpass: No such device or address
>
> Any ideas?
>
> Thanks
>

Looking at the getpass() source, it looks like open("/dev/tty") fails.
You can verify this by running passwd in strace (although you may have
to run both inside sudo, since debuggers disable setuid).

Ciao,
Markus



Re: [dev] [st] XTSMGRAPHICS query

2024-02-17 Thread Markus Wichmann
Am Sat, Feb 17, 2024 at 09:45:44PM -0500 schrieb Tim Culverhouse:
> Hello - I am the author of a TUI library and received a bug report regarding
> cursor placement on exiting an application.
>
> I was able to narrow down a simple reproducer to how st a XTSMGRAPHICS query:
>
>   echo -e "\x1b[?2;1;0S"
>
> This can also be seen when using a notcurses application which *doesn't* enter
> the altscreen (ie `ncls`). notcurses does the XTSMGRAPHICS query in the alt
> screen (which is also the solution I will be using), but `ncls` uses notcurses
> direct mode, which never enters the alt screen thus this bug appears there as
> well.
>
> I checked the source and it looks like the parser is not checking for a 
> private
> indicator when handling a CSI with final character S. In that case, this query
> gets parsed as a SU sequence. I think that ought be modified to ensure there
> isn't a '?' private indicator in the sequence before handling as SU.
>
> Not much of a C programmer but I could take a shot at this if the solution
> sounds ok.
>
> --
> Tim
>

Had to research what this is supposed to do: XTerm replies to it with
the screen size. Except the docs explicitly warn you that it is not
necessarily the screen size.

I wonder why a TUI application needs to know the screen size in pixels.
If a screensize in characters is acceptable, then just use
tcgetwinsize() or ioctl(TIOCGWINSZ). Yes, I know that in theory it could
tell you the pixels as well, but in practice those never did get
implemented after all.

Ciao,
Markus



Re: [dev] [Bug][sbase] make install borked since commit ddde8021

2023-10-29 Thread Markus Wichmann
Am Sun, Oct 29, 2023 at 06:00:18PM +0100 schrieb Страхиња Радић:
> mkdir returning EISDIR is definitely not a part of POSIX.[1]
>
> [1]: 
> https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html#tag_16_325_05

That's where you're wrong. Any function can fail for any reason unless
POSIX specifically states "this function shall not fail with...". Only
if the error conditions listed in the definition of the function apply,
they have to return those error codes. Or as XSI chapter 2.3 puts it:

| Implementations may support additional errors not included in this list,
| may generate errors included in this list under circumstances other than
| those described here, or may contain extensions or limitations that
| prevent some errors from occurring.
|
| The ERRORS section on each reference page specifies which error
| conditions shall be detected by all implementations (``shall fail") and
| which may be optionally detected by an implementation (``may fail"). If
| no error condition is detected, the action requested shall be
| successful. If an error condition is detected, the action requested may
| have been partially performed, unless otherwise stated.

For example, execve() can fail with ENOENT even though the file exists.
On Linux this happens when the file names an interpreter that does not
exist.

Ciao,
Markus



Re: [dev] [Bug][sbase] make install borked since commit ddde8021

2023-10-29 Thread Markus Wichmann
Am Sat, Oct 28, 2023 at 01:48:07PM -0600 schrieb Randy Palamar:
> This is a problem with mkdir in sbase. It probably shouldn't error out
> when mkdir(3p) fails and sets errno to EEXIST or EISDIR. I'll send a
> patch to hackers@ soon.
>
> - Randy
>

That is one of the jobs of the -p switch to mkdir. However, without -p,
mkdir is not allowed to ignore failure like that.

Plus I didn't know mkdir could fail with EISDIR. My manpage is not
documenting that case.

Ciao,
Markus



Re: [dev] getting rid of cmake builds

2023-09-21 Thread Markus Wichmann
Am Thu, Sep 21, 2023 at 04:05:17PM +0200 schrieb David Demelier:
> Hi,
>
> It's near to impossible to convert a CMake project to make
> automatically, CMake is almost like a scripting language given the
> numerous of things you can do with it.
>
> Keep in mind that plain make (POSIX) is enough for really simple
> projects but can come limited when going portable. Although the use of
> pkg-config helps there are various places where you will need to pass
> additional compiler/linker flags. For those I like GNU make even though
> its syntax is somewhat strange at some points.
>

Leaving aside the question of whether POSIX Make is enough for complex
projects, I do concur that it is not a good fit for a cmake conversion.
If I was tasked with this, I would probably attempt to build a parser
for cmake files (in what language is undecided). And that parser can
then output a shell script that does the same thing as what cmake would
do, i.e. generate a makefile. If necessary, find other packages by
whatever rules and write the results into the makefile.

I've switched to ninja-build for some of my projects, and that is pretty
awesome. Very fast compared to make. The developers basically took the
suckless approach and cut everything out of make that made it slow. The
result is incompatible but so much faster. I mention this because the
approach of generating a makefile is highly encouraged with ninja, so I
just use a shell script for that (and I do my best to keep it portable).

That said, portability is really not my goal. I don't actively prevent
my stuff from running on non-Linux platforms, but I don't actively seek
to have them run and tested, either. So maybe someone with experience on
that field should speak up.

Ciao,
Markus



Re: [dev] [license] gpl issues

2023-06-20 Thread Markus Wichmann
Am Tue, Jun 20, 2023 at 04:44:44PM +0200 schrieb Страхиња Радић:
> On second thought, I think Markus may be right. It is GPL which would forbid
> non-compatible sublicensing (which is changing the license of derived works
> *completely*), not Expat. Under Expat, you can sublicense *your copy/fork* to
> any license, including the proprietary licenses. (This is one of the reasons
> why I think that GNU GPL is superior--it stays true to the original intent.)
>

Exactly.

> Of course, the copyright holder(s), or original authors, can always choose to
> retain the original license on their software, or relicense their work in any
> way they choose (IMHO this wouldn't retroactively impact the forks made when
> the program's license allowed free-software-licensed forks).
>

That does seem to be the case. When Jörg Schilling changed the license
of his cdrtools to CDDL, the Debian project created cdrkit based on a
fork of the most recent GPL licensed cdrtools version, just to avoid
issues. Of course this lead to patches from Jörg not being picked up in
cdrkit and vice versa.

Ciao,
Markus



Re: [dev] [license] gpl issues

2023-06-18 Thread Markus Wichmann
Am Sun, Jun 18, 2023 at 11:44:18AM +0200 schrieb Hiltjo Posthuma:
> Hi,
>
> I think you can relicense only your own changes to GPL, so you'd have to keep
> both the MIT and GPL license with the original copyright information.
>
> And probably explain very clearly to which new parts the GPL license applies.
>

This is false. When you create a program, call it foo, and release it
under the MIT license, then you give permission to anyone to re-release
it with or without changes. Great.

Now I come along, create a program bar, and base it upon foo. bar is a
derivative work of foo, and so I as creator of bar need permission from
you as creator of foo to create it. Luckily I have your permission. It
is in the license (license and permission mean substantially the same
thing).

So I can release all of bar under the GPL. All I have to do is write
into the documentation:

bar, Copyright Markus Wichmann, released under the terms of the GPL, see
file COPYING. Based on foo, Copyright Hiltjo Posthuma, released under
the terms of the MIT license, see file COPYING.foo.

That way, I have fulfilled the terms of your license and am therefore
allowed to create a derivative work (which I would class under a mix of
"use", "copy", "modify", and "merge"). And for my own work, I can use
whatever license I wish, and I choose the GPL. I could also choose a
commercial license. So long as I fulfill the terms of your license, that
is all OK for me to do, since that is what you have given me permission
to do.

The other way around would not work, since if I create a work and
license it under the GPL, then I do not give you permission to rerelease
the work without restriction. I only allow you to do so under the same
license terms.

Summary: Words have meaning.

Ciao,
Markus



Re: [dev] [st] st+vifm+nvim or st+mutt+nvim wrong terminal geometry

2023-01-25 Thread Markus Wichmann
On Wed, Jan 25, 2023 at 04:35:39PM +0100, German Hammerl wrote:
>  Hi there,
>
>  I am new to this mailing list and have problems to search the
>  archives, therefore I dare to ask, even though this question may
>  already have been asked and answered before:
>
>  In vanilla dwm, by, e.g., starting mutt or vifm via
>
>  st -e mutt
>  st -e vifm
>
>  I receive a fullscreen terminal window correctly displaying
>  the content of mutt or vifm, but if I then
>  open a mail in mutt or a file in vifm invoking nvim,
>  the terminal geometry in nvim is acually that size
>  of a single floating window of st, resulting in a scrambeled display
>  of the mail or file in nvim. Ctrl+L will not fix the display, but
>  only a switch to 'monocl' and back to 'tile'.
>
>  Is there any way to correct the terminal geometry after
>  opening the st terminal?
>
>  Any help would be appreciated.
>
>  Thanks in advance
>  German
>

My guess: Timing problem. dwm resizes st during startup, and then st
changes its window size, and either of the affected applications does
not update the window size when this happens.

I would run mutt or vifm under strace to see if they get a SIGWINCH, and
if they react to it by re-reading the window size. If not, they may have
a problem if SIGWINCH occurs too early (they ought to register the
SIGWINCH handler first and read the window size second, not the other
way around).

HTH,
Markus



Re: [dev] st: no need for scrollback patch or program by using -o option

2023-01-14 Thread Markus Wichmann
On Fri, Jan 13, 2023 at 07:53:41PM -0600, Dave Blanchard wrote:
> I experimented with st for a week or so, before finally realizing that
> it's poorly-written trash. It has no advantages over XTerm at all.
>

So where's the patch?

Given that a terminal emulator is a necessary part of the Trusted
Computing Base if the system has X11, I'd prefer it to be as simple as
possible, so that it is not exploitable. st is simple enough to be able
to roughly gauge whether it has memory bugs or not. XTerm is such
overwritten tripe I cannot gauge that at all.

Ciao,
Markus



Re: [dev] Replace ranlib(1) calls?

2022-08-03 Thread Markus Wichmann
On Wed, Aug 03, 2022 at 05:14:20PM +0200, Laslo Hunhold wrote:
> I have one question here: Doesn't ranlib(1) need to understand the
> ar-format to be able to add the symbol-table-file?
>

Not if it uses "ar r" to add the symbol table to the archive. Although
that is contingent on the symbol table having a valid file name, which I
don't know.

Ciao,
Markus



Re: [dev] Replace ranlib(1) calls?

2022-08-03 Thread Markus Wichmann
On Wed, Aug 03, 2022 at 03:21:30PM +0200, Laslo Hunhold wrote:
> In a way, ar(1) is merely an archiver, but POSIX added a function that
> only applies to exclusively object-file-containing-archives, but stays
> away from specifics[0]:
> [...]

Yeah, POSIX be like that sometimes. You can have a perfectly simple
model of how a program is supposed to work, then POSIX comes along and
specifies one thing that fits in about as elegantly as a blue whale into
a stationary cupboard.

Another example would be the interactive mode for cp/mv/rm, applications
which have absolutely no business reading from terminal being forced to
do it. Or alternatively, you just sod this one aspect of it.

In this case, a simple archiver is supposed to do special things based
on the content of the files it is archiving. Or, alternatively, you say
no to that requirement, implement ar as a simple archiver, and ranlib as
a program that reads the archive, makes a symbol table, and adds it to
the archive. Possibly even by calling the ar program.

That design would afford some flexibility to the whole business: ar
doesn't need to know the object file format and ranlib doesn't need to
know the ar file format. Indeed ld could read the symbol table and
object files from the archive by calling ar, then nothing in the system
would depend on the precise format of the ar files. That would be
modular. I daresay, it would suck less than what POSIX wants you to do.

But those are just the 2 cents of a grumpy old millenial.

Ciao,
Markus



Re: [dev] Replace ranlib(1) calls?

2022-07-24 Thread Markus Wichmann
On Sun, Jul 24, 2022 at 08:04:05PM +0200, Страхиња Радић wrote:
> On 22/07/23 11:06, Tom Schwindl wrote:
> > Again, you'd have to rely on a tool which isn't defined.
> > If a system says it's POSIX compliant, we can assume that the `-s' option
> > exists, but there is no standard which tells us whether ranlib(1) is 
> > available
> > or not.
>
> Standards are not the Holy Grail.
>
> https://harmful.cat-v.org/standards/

Plus there is what Georg Jellinek called the "normative force of the
factual": ranlib is de-facto standard on all UNIX variants I know of
(and I know weird ones line Cygwin and Solaris). It's a bit like
vfork(), gone but not forgotten, and every once in a blue moon something
comes along that still uses it.

On many systems, ranlib is even just implemented as a call to ar. But we
don't need to care about that. The important fact is that in practice,
ranlib is on all systems anyone has cared to use our software on so far,
and future systems are more likely to hack in a version of ranlib that
to send patches to get rid of it.

And if they decide to have ar generate a symbol table irrespective of
the "-s" option, and link ranlib to true, that is also fine.

Ciao,
Markus



Re: [dev] [surf] webkit

2022-07-10 Thread Markus Wichmann
On Sun, Jul 10, 2022 at 08:20:04AM +0200, Roberto E. Vargas Caballero wrote:
> I use surf in this way too. It works but it has problems with some pages.
> It is hard to kow the patches that you distribution adds to the upstream
> project.
>
>

Solvable problem:

$ apt-get source webkitgtk
$ cd webkitgtk-*
$ ls debian/patches

In my case, seems to mostly improve support for rarely used
architectures (Sparc, ARM 32, i386 without SSE support,...).

Ciao,
Markus



Re: [dev] Disk encryption

2022-06-16 Thread Markus Wichmann
On Thu, Jun 16, 2022 at 08:18:16PM +0300, an2qzavok wrote:
> >do not roll your own crypto
> I believe this refers only to inventing your own algorithm, just
> writing your own implementation of existing and tested algorithms is
> fine.
>

As I tried to point out with the MAC example, cryptography is full of
subtleties. Even using proven algorithms and plugging them together
inexpertly can create an insecure system. In that example, someone had
used AES in CBC mode with FIPS padding and some SHA-2 HMAC. All of these
were state of the art when the system was designed, and some still are.

> Though, is encrypted root partition even desirable?
> Since it only keeps your data safe when your machine is powered off, I
> always thought of system disk encryption as snake oil at worst and at
> best just not worth the effort.
>

Snake oil refers to a means that does not do what it says it will. Virus
scanners are snake oil because they cannot possibly detect all malware
prior to execution, and then the system is compromised. Malware removal
is snake oil, because it attempts to fix a compromised system while you
don't know what components have been compromised. So how can you have
any confidence in the result? Anything the program uses to find malware
may also have been compromised.

Disk encryption is not a snake oil. It will prevent your data from being
stolen when the system is off. This is useful, for example, for a
laptop, or in case you are worried about burglars or law enforcement
taking your computer. It will not help you with exploits targetting any
software you have running, yes, but there are other tools for that.

Ciao,
Markus



Re: [dev] Disk encryption

2022-06-16 Thread Markus Wichmann
On Wed, Jun 15, 2022 at 07:59:34PM -0500, T Taylor Gurney wrote:
> Are you familiar with loop-AES?

Not specifically, but I had heard of loop-device based encryption
before. The manpage for losetup states that support for such was removed
in favor of dm-crypt.

> My understanding is that the project provides a replacement "loop.ko"
> kernel module that gives loop devices support for block-level
> encryption. But then userspace still does not know how to set up
> encrypted loop devices, set encryption-related mount options, etc., so
> they also offer patches for the losetup and mount programs to make
> this functionality available.
>

Sorry, I thought losetup already had the support. In any case, you can
write your own losetup; it is not the most complicated program in the
world. And for the root, you wouldn't need the support in the mount
program at all. Just set up the loop right, then mount the loop.

But then, with dm-crypt, it is mostly just setting up the devmapper,
then mounting it.

I also dislike the "loop" mount option, as it entangles another two
commands for the sake of convenience, where a simple shell script would
have sufficed.

> To me it sounds much nicer than the complexity of dm-crypt+LUKS. It
> pre-dates them as well. I wonder why it has been kept out of the
> kernel tree all this time. It's an old project but I'm not familiar
> with the history.
>
> Taylor
>

My guess is that the cryptoloop solution was judged to be too limited in
the past, and now that dm-crypt exists, it is also superfluous.

I'm also weary of "rolling your own crypto". Unless you are a
cryptographer, I have never heard that go well. Hell, I have heard that
go bad even with cryptographer support. The simplest decisions can come
back to bite you. Do you calculate the MAC over the plaintext or the
ciphertext? Turns out, if you choose the plaintext here, you are
vulnerable to a padding oracle attack.

So that's why I would probably just go with LUKS or Truecrypt and tank
the added complexity. It is probably there for a reason, and I might not
understand the reason but it may be important, anyway.

Ciao,
Markus



Re: [dev] Disk encryption

2022-06-15 Thread Markus Wichmann
On Wed, Jun 15, 2022 at 12:49:07PM -0500, T Taylor Gurney wrote:
> All,
>
> Working on another statically-linked Linux distro.
>
> Getting an encrypted root partition is a problem. The kernel has built-in 
> support for this and I am plenty familiar with it. But the supporting 
> userspace tool, cryptsetup, is way too bloated and has too many dependencies, 
> including OpenSSL.
>
> Anyone know of a more minimal alternative solution, or even have any 
> half-baked ideas for one? loop-AES looks most promising so far, but patching 
> the kernel and util-linux programs is not my preference.
>
> Taylor
>

This is really where the devil is in the details, isn't it? The kernel
has builtin support for disk encryption, but it does not have built-in
support for LUKS. LUKS is a crypto-header solution that adds some kind
of header to the volume which establishes (with help of the correct
password, of course) the disk key. Truecrypt works in a similar fashion.

This means, the setup utility has to do at least some crypto on its own,
and then you can really only pick your poison. I just wanted to check
what other backends cryptsetup supports, but the package requires
autohell, and naturally it failed on me right out the gate. Apparently,
however, libgcrypt can be used instead of OpenSSL. I don't know if that
helps any.

If you are willing to forego LUKS, you can roll your own dm-crypt
solution, of course, just as soon as you have figured out how to
securely make a key from a password. You can use PBKDF2 for that, or
bcrypt. In theory, that ought to be secure. But consider the downsides.
For example, if you generate the key directly out of the password, then
you cannot change the password. Ever. Doing so would wipe the drive.
Adding a layer of indirection here (encrypt drive with random key, save
random key encrypted in first sector) would remedy the issue but also
increase complexity. Again, pick your poison.

Why would you need to patch util-linux for loop-AES? And would it work
with dm-crypt?

Ciao,
Markus



Re: [dev] ii: how to process out in a pipeline and still page with less

2022-05-29 Thread Markus Wichmann
On Sun, May 29, 2022 at 10:20:05PM +, Rodrigo Martins wrote:
> It was thus said that the Great Markus Wichmann once stated:
> > And you fundamentally cannot change anything about the userspace of another 
> > program, at least not in UNIX.
>
> When I open file descriptors and exec(3) the new program inherits
> those. Is that not chaning the userspace of another process?
>

Program, not process. And no, it is changing the kernelspace of another
program. For userspace, file descriptors are just numbers. They attain
meaning only from the kernel interface.

> It was thus said that the Great Markus Wichmann once stated:
> > Having one special-case program is better than changing all the general 
> > ones, right?
>
> Sure is. Too bad the stdbuf(1) uses such a fragile mechanism.
>

Well, I cannot think of anything else they could have done.
Fundamentally, setting environment variables and hoping the target
program will interpret them correctly is about the extent of what an
external filter is capable of, here.

> What if instead of changing every program we changed the standard
> library? We could make stdio line buffered by setting an environment
> variable.
>

The problem you run into here is that there is more than one standard
library, and indeed it is even thinkable that some programming language
may shirk libc entirely. Golang has been trying their damndest at that
for a long time, just didn't go all the way and still wanted to use
libpthread. Haskell/GHC would be another candidate, as would be Pascal.

The only way to roll out a change that would affect all programs at the
same time would be a kernel update, but as discussed, this is a
userspace problem to solve.

Plus, the environment variable idea breaks with programs with elevated
privilege, but that is probably a good thing here.

Ciao,
Markus



Re: [dev] ii: how to process out in a pipeline and still page with less

2022-05-28 Thread Markus Wichmann
On Sat, May 28, 2022 at 07:19:24PM +, Rodrigo Martins wrote:
> Hello, Markus,
>
> Thank for filling in the details. I should do more research next time.
>
> I tried to write a program that does the same as stdbuf(1), but using
> setbuf(3). Unfortunately it seems the buffering mode is reset across
> exec(3), since my program did not work. If it did that would be a
> clean solution.
>

But it cannot possibly happen that way, because the buffering set with
setbuf(3) is solely in userspace. And you fundamentally cannot change
anything about the userspace of another program, at least not in UNIX.

> Does the buffering happen on the input or on the output side? Or it
> that not the right way to look at it? Are these programs doing
> something wrong or is this a limitation by the specifications?
>

There is too much buffering and changing according to file mode going on
here. I had a program I called "syslogd" (on Windows) that would simply
listen to the syslog port on UDP and print all the packages that
arrived. Running just "syslogd" on its own would print all packages as
they came in, but running "syslogd | tr a A" would print blocks of data
long after the fact, making it useless for my usecase.

Why? Because for one, syslogd's output buffering mode had changed to
"fully buffered", now that the output was a pipe rather than a terminal.
tr's input buffering mode was also fully buffered now, but that doesn't
much matter, since the data is usually passed on quickly. It's just that
the data is only actually sent on from syslogd when syslogd's buffer is
full. Cygwin by default defines a BUFSIZ of 1024, so that's the buffer
that has to be filled first.

tr's buffer on input doesn't much matter, because the input buffer is
refilled on underflow, and then filled only as far as is possible in one
go. And tr's output buffer is line buffered in the above application,
making it perfect for the application. No, the problem was the change in
output mode for my own application happening as part of being in the
middle of a pipeline.

> Is modifying each program the best solutions we have? Granted it is
> not an invasive change, especially for simple pipeline-processing
> programs, but making such extensions could bring portability issues.
>

Modifying all programs is typically a bad solution. It is what the
systemd people are doing, and most here despise them for that if nothing
else. It just appears there is no simple solution for this problem other
than writing specialized programs. Having one special-case program is
better than changing all the general ones, right?

Ciao,
Markus



Re: [dev] ii: how to process out in a pipeline and still page with less

2022-05-28 Thread Markus Wichmann
On Sat, May 28, 2022 at 06:09:04PM +, Hadrien Lacour wrote:
> Now, I wonder how it'd be fixed ("it" being how does the read end of the pipe
> signal to the write one the kind of buffering it wants) in a perfect world.

The problem ultimately stems from the mistaken idea that buffering is
invisible to the user. Which is true if the pipeline ultimately
terminates in a disk file or some such, but not if the pipeline
ultimately terminates on the terminal. But who knows if that is the
case? Pipelines ending in a call to "less" will terminate on the
terminal, pipelines ending in a call to "nc" will not. So the shell
can't know, only the last command can know.

So to make this work automatically, the last command would have to be
able to somehow inform all commands in the pipeline of its intentions.
Sadly, pipes are unidirectional, and in general it is impossible to
figure out the process on the other side of the pipe.

But even if that was possible, now what? Send a signal to the other side
to please unbuffer your output? That might actually work, but would
require each and every program to make intelligent decisions about how
to handle that signal. More importantly, it would require each and every
UNIX programmer to agree. Both on a signal and the behavior there, and
on the necessity of it all. Frankly, I have little hope for that ever
happening.

In a perfect world, yes, it could be done, but in a perfect world we'd
have brain-computer-interfaces so that the machines understand our
intentions. We'd not be stuck on emulations of 1960s teletypes to do the
same.

Besides, adding more automagic code that works different based on the
type of output device is going to make debugging shell scripts even
harder than it already is.

Ciao,
Markus



Re: [dev] ii: how to process out in a pipeline and still page with less

2022-05-28 Thread Markus Wichmann
On Sat, May 28, 2022 at 08:38:49AM +, Hadrien Lacour wrote:
> On Sat, May 28, 2022 at 03:33:16AM +, Rodrigo Martins wrote:
> > Hello,
> >
> > The problem here is I/O buffering. I suspect it to happen in the C
> > standard library, specifically on the printf function family.

You know, that is the sort of claim that ought to be researched. First
of all, it is stdio that is providing buffering, if any. For reasons I
won't go into, musl's printf functions will provide a temporary buffer
on unbuffered files, but the buffer is then flushed before the functions
return (else the buffer would be invalid).

> > If I
> > recall, the C standard says stdio is line-buffered when the file is
> > an interactive device and let's it be fully buffered otherwise.

Not quite. I looked it up in both POSIX and C, and found that
- stderr is not fully buffered
- stdin and stdout are fully buffered if and only if they are
  determined to not be interactive streams.

This means the standard allows "line buffered" and "unbuffered" for
stderr, and also those two modes for stdin and stdout for interactive
streams.

But yes, in practice we usually see stderr be entirely unbuffered, and
stdin and stdout be line buffered on terminals and fully buffered on
everything else.

> You can use stdbuf(1) to modify that aspect without touching the
> program source itself.
>

Had to look up the source for that. I had heard of stdbuf, but I always
thought that that was impossible. How can one process change a
process-internal detail of another program? One that is not inherited
through fork() or exec(), I mean. Well, turns out it is impossible.
stdbuf sets LD_PRELOAD and execs the command line, and the changing of
the buffer modes happens in the library.

That means that whole thing only works if:
- you have the target program linked dynamically
- you have stdbuf and the target program linked against the same libc
- the target program doesn't change buffering modes later, anyway
- the target program does not have elevated privilege.

Ciao,
Markus



Re: [dev] [dwm] Incorrect resolution when turning on dual monitors

2022-05-07 Thread Markus Wichmann
On Fri, May 06, 2022 at 10:27:32PM -0400, Christopher Brown wrote:
> Hello,
>
> I have been intermittently encountering an issue where dwm messes up
> my monitor resolutions when powering on my two monitors. Frequently,
> both screens will be combined on one monitor while the other monitor
> does not receive input. The "Two independent outputs" section of the
> multi monitor dwm documentation seems to describe what I am
> experiencing. I tried using the xrandr options it mentions, but I will
> still sometimes encounter the issue. Does anyone know how to prevent
> this from happening?
>
> Thank you,
> Christopher
>

dwm is unlikely to be the culprit here, although it also doesn't help
any. dwm only consumes the Xinerama information, it does not perform any
settings itself. So whatever is going wrong is likely to be with the
startup of your X server. I would suggest you investigate how the server
starts in your case, and how it attempts to deal with multiple displays.

Ciao,
Markus



Re: [dev] Special target ".POSIX" in Makefiles

2022-01-03 Thread Markus Wichmann
On Sat, Jan 01, 2022 at 08:09:38PM +0100, Mattias Andrée wrote:
> .POSIX:
>
> CC = c99
> # Required as POSIX doesn't mandate that it is defined by default
>
> OBJ =\
>   alpha.o\
>   beta.o\
>   gamma.o
>
> LINUX_AMD64_OBJ = $(OBJ:.o=.linux-amd64-o)
> OPENBSD_AMD64_OBJ = $(OBJ:.o=.openbsd-amd64-o)
>
> all: myproj-linux-amd64 myproj-openbsd-amd64
>
> myproj-linux-amd64: $(LINUX_AMD64_OBJ)
>   $(CC) -o $@ $(LINUX_AMD64_OBJ) $(LDFLAGS_LINUX_AMD64)
>
> myproj-openbsd-amd64: $(OPENBSD_AMD64_OBJ)
>   $(CC) -o $@ $(OPENBSD_AMD64_OBJ) $(LDFLAGS_OPENBSD_AMD64)
>
> .c.linux-amd64-o:
>   $(CC) -c -o $@ $< $(CFLAGS_LINUX_AMD64) $(CPPFLAGS_LINUX_AMD64)
>
> .c.openbsd-amd64-o:
>   $(CC) -c -o $@ $< $(CFLAGS_OPENBSD_AMD64) $(CPPFLAGS_OPENBSD_AMD64)
>
> .SUFFIXES:
> .SUFFIXES: .c .linux-amd64-o .openbsd-amd64-o
>
> # NB! Cannot use .linux-amd64.o and .openbsd-amd64.o
> # as POSIX requires a dot at the beginning but
> # forbids any additional dot
>
>

OK, that is one way. I do wonder how you would handle configurable
dependencies. I have always been partial to the Linux Kconfig way of
doing it, but it requires +=:

obj-y = alpha.o beta.o gamma.o
obj-$(CONFIG_FOO) += foo.o
obj-$(CONFIG_BAR) += bar.o
obj-$(CONFIG_BAZ) += baz.o

dir.o: $(obj-y)
ld -r -o $@ $^

With your scheme, this one in particular would blow up due to
combinatorics (need a list for none, FOO, BAR, BAZ, FOO+BAR, FOO+BAZ,
BAR+BAZ, and FOO+BAR+BAZ. Now imagine this for the hundreds of options
Linux has)

But with the advent of ninja (yes, I know this list's opinion of C++ and
Google in particular, but you cannot deny that Ninja is FAST), I have
come around to the idea of configure scripts creating makefiles (or
similar). And then you can generate makefiles in as complicated a manner
as you like.

Indeed, if the makefile is generated, there is little need for suffix
rules at all. You can just make direct rules for everything. Repetition
is no problem if the code generating the Makefile is readable. And then
you can even build with make -r, because you don't need the default
database, either. And -r saves time in some implementations.

Ciao,
Markus



Re: [dev] tcvt: very useful for seeing more at once

2021-10-14 Thread Markus Wichmann
On Thu, Oct 14, 2021 at 12:28:52PM -0400, Greg Reagle wrote:
> FYI
>
> Useful, but a lot of wasted screen space on my monitor:
> man dwm
>
> MUCH better!  I see the entire man page:
> tcvt -c 4 man dwm
>

You know, if you were trying to shill the program, you might have done
better if you had provided the homepage. I searched for "tcvt", and all
I found was a Dutch site for something to do with VTOL, and a registry
for the TransCatheter Valve Treatment. I am reasonably sure you meant
neither.

Ciao,
Markus



Re: [dev] Wayland compositors

2021-09-16 Thread Markus Wichmann
On Thu, Sep 16, 2021 at 08:26:27AM +0200, Laslo Hunhold wrote:
> The gaslighting regarding Wayland wasted me a lot of time, as I'm told
> or I read every year that _now_ would be the time to switch to Wayland.

Just like _this_ year is the year of the Linux desktop? And then, when
the market share inevitably fails to materialize, they will claim they
meant next year.

In any case, I believe the idea behind Wayland to be sound, just the
current implementation is not. They just have "a few issues to work
out", and have been doing that for years now. But on the other hand, I
had tried switching to Linux a few times before I actually could stay on
it (even the prettiest pictures cannot make up for lacking hardware
support, and I had problems with Wifi for the longest time), and that
was at some time during the 2.6 line. So maybe Wayland needs another
decade to ripen and mature.

Ciao,
Markus



Re: [dev] [st] Thoughts on kitty keyboard protocol

2021-05-22 Thread Markus Wichmann
On Sat, May 22, 2021 at 06:50:51AM +, Tobias Bengfort wrote:
> I just found out about this protocol:
>
> https://sw.kovidgoyal.net/kitty/keyboard-protocol.html
>
> Basically it provides a way to send unambigous esc and other keys as well as
> key release events to terminal programs while being mostly backwards
> compatible.
>
> It sounds like a reasonable proposal to me. What do you make of it? Should
> this be implemented in st?
>
> tobias
>

Independent of the content of the proposal, I already see that it is
going to be a hard sell to people looking to reduce the amount of code
they have to trust. This new way of sending key events to terminal
applications will require support from terminal emulators and TUI
applications alike. Meaning a new mode for st to send keycodes the new
way, and a new mode for vim/mutt/zsh/... to read those. In the interest
of compatibility (and if I've learned anything about the computer
industry, then that compatibility is the name of the game), the old
modes would need to remain available. So now we end up with useless code
in the applications we have to trust, for we are either not using the
old or the new way. And that tends to lead to code rot one way or
another.

The proposal is indeed not really backwards compatible, it merely
includes a legacy mode that can be turned off. The new mode is entirely
bespoke and would require a significant reworking of most applications.
Now, if the applications were well written, the input system would be
entirely encapsulated from the rest of the application. However, I have
seen reality recently, and it does not look like that. In all
probability, adding a completely new input decoding mechanism (and
abstracting away the differences between the old and new ways) is going
to be significant work.

Next problem is going to be user acceptance. This is entirely
inter-process communication we are talking about here (terminal emulator
<-> TUI application). Ideally the user would not notice. However, the
current way of doing things appears to be "good enough". Most TUI users
know enough about terminals to avoid pressing too many buttons after
hitting , due to the ambiguous way the current encoding works. In
practice, it is not a big issue for many.  If you now add the likely
possibility of bugs in early rollouts of the new protocol, it will be a
hard sell for most TUI users as well. The current way is working well
enough.

The proposal itselfs seems sound to my untrained eyes, but for the above
reasons, I fail to see how an implementation of that protocol in
addition to the escape sequences already implemented will accomplish
anything useful. Of all the goals given at the top of the linked page,
only number 5 looks really enticing to me, but I am not willing to spend
the effort to fix what is a mild annoyance at most.

Ciao,
Markus



Re: [dev] Checksums and Sig files for release gzip

2021-04-13 Thread Markus Wichmann
On Tue, Apr 13, 2021 at 09:58:56PM +0300, Sergey Matveev wrote:
> *** Markus Wichmann [2021-04-13 20:17]:
> >Y'know, while we're bikeshedding, why not just use SHA-3?
>
> Answer is: https://www.imperialviolet.org/2017/05/31/skipsha3.html

I don't care about the speed of a hash function. Speed of a hash
function matters only in two cases: Doing lots of hashing (e.g. password
cracking or bitcoin mining), or hashing large files. I don't hash large
files often enough for speed to matter, I think bitcoin mining is
pollution, and in case of password cracking, having a slower hash
function is an advantage for me, as I would be on the side of the
defenders.

> and answer for that: 
> https://cryptologie.net/article/400/maybe-you-shouldnt-skip-sha-3/
> SHA3 is good, but "offers no compelling advantage over SHA2 and brings
> many costs". SHA2 is not so bad.

I am not a cryptographer. From what I understand about SHA-3, it offers
a better HMAC function (the whole padding thing is not needed anymore,
since hash extension attacks are not possible).

I am dependent on the advice of cryptographers for the selection of
hashing algorithms. Cryptographers had a big old competition over the
"best" hashing algorithm (and I realize that multidimensional
optimization is, in general, impossible), and in 2012, Keccak (in a
64-bit variant) won. Now of course, since then, nine years have passed,
and newer developments have not seen such a competition.  But I lack the
skills to evaluate any of the other possibilities for anything except
speed, which is the one thing I don't care about. So until SHA-4 comes
along, or another comparable competition, I will stick to SHA-3.

And I will continue to advocate for its use exclusively over SHA-2 to
keep the zoo of hash functions small. SHA-3 should be used for its HMAC
property alone, and it is adequate for all other tasks, so there is also
no reason to keep SHA-2 around.

Ciao,
Markus



Re: [dev] Checksums and Sig files for release gzip

2021-04-13 Thread Markus Wichmann
On Tue, Apr 13, 2021 at 05:08:31PM +0200, Mattias Andrée wrote:
> On Tue, 13 Apr 2021 16:57:39 +0200
> Sagar Acharya  wrote:
>
> > Sure, any good signature. SHA512 is stronger than SHA1, MD5 and SHA256. It 
> > shouldn't take a second more than others. Why use a weaker checksum?
>
> SHA512 is actually more than twice as fast as SHA256 on 64-bit machines.
> (I don't know which is stronger).
>

Y'know, while we're bikeshedding, why not just use SHA-3? Keccak has
been out for a while now, and it is also available in 256 and 512 bit
variants. I keep wondering why people keep using SHA-2 variants. Do you
want to wait until it is cracked?

SHA-3 would have the benefit of always being a 64-bit algorithm (unlike
SHA-2, which is 32-bit in the 192 and 256 bit variants, and 64-bit in
the 384 and 512 bit variants, necessitating two very similar processing
functions in C). Its design also makes HMAC easier, though this is not
of import for this application.

> I see no point in having checksums at all, except for detecting bitrot.
> Signatures are of course good.
>

Signatures only help if you have a known-good public key. Anyone can
create a key and claim it belongs to, say, Barack Obama. I have no
public key of anyone affiliated with suckless, and no way to verify if
any key I get off of a keyserver is actually one of theirs.

Security is hard.

Ciao,
Markus



Re: [dev] st: enlarge font

2021-03-30 Thread Markus Wichmann
On Mon, Mar 22, 2021 at 03:15:35PM -0400, Sebastian LaVine wrote:
> The Suckless community is international, and many of course do not speak
> English -- in particular American English -- as a primary language. But as
> an American, the word used in that email address is beyond vulgar, and
> extremely -- uniquely -- offensive. I agree with Wesley that that email
> address should be removed from the list.
>

As a non-American, I wonder what it matters what people set their e-mail
addresses to. Although, yes, I am getting 12-year-old vibes from that
address (similar to the classic bash.org quote, where a guy with the
nickname "h1tler" asks how everyone knew they were 12 years old).

On a more practical note, I have not received the original mail at issue
here. Was it not addressed to dev@? Or was the address so offensive,
some mail provider on the way already filtered it?

Ciao,
Markus



Re: [dev] st: enlarge font

2021-03-25 Thread Markus Wichmann
On Wed, Mar 24, 2021 at 11:12:29PM +0100, Страхиња Радић wrote:
>   Didn't know that, thanks. What is the reasoning behind having a separate
> .def.h in the first place then? Wouldn't editing a local copy of config.h from
> the cloned repository suffice?

The idea is that you keep your config.h around when you update the
repository, and then just merge the changes to config.def.h into
config.h. You'd basically carry your config.h forward between versions.


Ciao,
Markus



Re: [dev] [st] Patch/feature request - redraw terminal on resize

2020-10-25 Thread Markus Wichmann
On Sat, Oct 24, 2020 at 07:44:43PM +0100, Daniel Littlewood wrote:
> Hi all,
>
> I have noticed a feature from tmux that I would like to have in vanilla st.
> The behaviour is that when the screen resizes, the window is redrawn
> to fit the new size.
> In vanilla st, if I make the window smaller then output that was
> previously drawn there is blank.

st implements the terminal screen as a 2D array of character cells
(slightly more complex than that). On resize, it reallocates that array
to fit the new dimensions, and all the cells that are now off-screen are
lost. Other terminal emulators implement the terminal screen as an array
of lines, and resizing merely has the effect of moving the line break.
There are pros and cons to either approach, really.

> If I'm running a program like "man" in the terminal, then the lines
> are broken in a strange place and I have to restart it to get them
> correct.

man formats the manpages with a troff pipeline. Redrawing the screen
would mean re-running the pipeline.

> This sounds like the perfect sort of thing for a patch, but I can't
> see anything in the patches section of the FAQ about this idea.
> Does anybody know if such a patch exists, or where to start
> implementing it myself?

If I understand you correctly, tmux is doing something on resize that
you would like to see in st itself. That means, you have to figure out
what it is tmux is doing on resize that affects the applications running
in st, and then add that behavior into st. I am guessing it is reacting
to SIGWINCH somehow, but for instance man-db does not react to that
signal. and the pager itself is not powerful enough to re-run the troff
pipeline. My guess would be that tmux pushes a CTRL-L into the input
pipeline, as that is the line feed character, and that usually causes
TUI applications to redraw. but those are merely educated guesses.

Ciao,
Markus



Re: [dev] [st] BadLength

2020-05-20 Thread Markus Wichmann
On Wed, May 20, 2020 at 12:24:00PM +1000, Александр Рянин wrote:
> I use Arch Linux, dwm and st. Got st through the git clone. Got it without 
> patches. Just make && sudo make install. When trying to run mutt st falls 
> with an error output:
>
> $ st
> erresc: unknown csi ESC[22;0;0t
> erresc: unknown csi ESC[23;0;0t
> erresc: unknown csi ESC[22;0;0t
> erresc: unknown csi ESC[23;0;0t
> erresc: unknown csi ESC[22;0;0t
> erresc: unknown csi ESC[23;0;0t
> erresc: unknown csi ESC[22;0;0t
> X Error of failed request:  BadLength (poly request too large or internal 
> Xlib length error)
>   Major opcode of failed request:  139 (RENDER)
>   Minor opcode of failed request:  20 (RenderAddGlyphs)
>   Serial number of failed request:  9282
>   Current serial number in output stream:  9354
>
> What's that supposed to mean and how do we fix it to make st work steadily?
>

That would be the well-known Xft bug in conjunction with color emoji.
Only known bug fix is to prevent Xft from seeing fonts with color emoji.
This can be done by uninstalling the relevant fonts. Or else you might
wish to research fontconfig.

I wanted to do neither, and since tilix was installed on this machine by
default, I simply switched to using it for mutt, though I keep st for
most other things requiring a terminal emulator. BTW, don't use tilix,
it is an ungodly mess written in D of all languages, basically using the
backend of gnome-terminal, but dynamically loading it, so the source
code doesn't even contain the core logic.

It appears to me that on Linux, only ca. three ways to render fonts
remain: One is to use xlib and its fonts, but this does not work very
well with Unicode. Then there is Xft and fontconfig, requiring XML
config files, and while it does work well in many cases, Xft has had
this particular bug open for ages and they fail to do anything about it.
And finally, you can use Pango, Cairo, Pangocairo, GDK, and whatever
else you need to keep this stack stable. And all of that stuff is
basically C++ without the compiler support, thus managing to be worse
than C++. But at least it's fully featured, and more to the point,
doesn't crash on arbitrary inputs. At least I think it doesn't.

All software sucks.

Ciao,
Markus



Re: [dev] [sbase] chmod -R and symbolic links

2019-12-22 Thread Markus Wichmann
On Sat, Dec 21, 2019 at 07:05:45PM -0800, Michael Forney wrote:
> - Most BSD chmod(1) have -H, -L, and -P options (defaulting to -P),
> and the filesystem *does* record the mode of a symlink, but this mode
> has no affect on the kernel's access checks.

Well, most Linux FSes have the capacity to record symlink mode as well,
and Linux has the capacity to return that mode with lstat() (which is
evident whenever you list directories from the /proc file system), it
just has no interface to change the mode and no use for a symlink's
mode.

So, almost like the BSDs, just without a way to change symlink mode.

> So currently, if sbase chmod -R encounters a dangling symlink, it always 
> fails.
>
> I can think of two possibilities here:
>
> 1. Remove the -H, -L, and -P options from chmod, always set r.follow =
> 'H', and call chmod(3) conditional on !S_ISLINK(st->st_mode).
> 2. Keep the -H, -L, and -P options, but use fchmodat(3) instead of
> chmod(3) with AT_SYMLINK_NOFOLLOW depending on r->follow and r->depth.
> If fchmodat fails with EOPNOTSUPP, ignore that and continue.
>
> Does anyone have a strong preference for 2? I'm leaning towards 1
> since it doesn't seem like those options are used commonly.
>
> -Michael
>

Removing nonstandard (thus unreliable[1]) options would appear the most
sensible to me as well. Also the least sucky, since it removes unused
features. JM2C.

Ciao,
Markus

[1] By this I mean, I cannot write scripts relying on the existance of
these options, since they might not.



Re: [dev] [quark] Performance issues

2019-09-25 Thread Markus Wichmann
On Wed, Sep 25, 2019 at 04:32:45PM +0200, Laslo Hunhold wrote:
> please excuse the ignorant question, but why would you want to access
> /dev/null? The problem with /dev/urandom is well-known, which is why
> OpenBSD has arc4random(3).
>

You might not, but a library you use might. I remember musl testing for
open FDs 0, 1, and 2 and opening /dev/null to make up for missing FDs.
And crashing (deliberately) if that fails. But then, that only happens
for elevated security contexts, i.e. setuid or "secure" mode (which on
Linux means "file capabilities set").

/dev/null has the distinction of being the only device POSIX actually
requires. I don't know what you might use it for. (/dev/tty is
defined, but optional.)

Ciao,
Markus



Re: [dev] [quark] Performance issues

2019-09-25 Thread Markus Wichmann
On Wed, Sep 25, 2019 at 08:20:52AM +0200, Laslo Hunhold wrote:
> chroot() should never be optional. unveil() might bring the same
> effect, but the unveil()-wrapper in quark doesn't do anything on Linux.
>

chroot() has several detrimental effects, most importantly making it
impossible to access /dev/null and /dev/urandom. Unless, of course,
measures are taken to replicate these devices underneath the new root.

It is also not a security device. If a service in a chroot is exploited
with root privileges, it can mount procfs wherever, and access
/proc/1/root. It can also mount another instance of the rootfs wherever
and escape the jail that way.

>
> With best regards
>
> Laslo
>

Ciao,
Markus



Re: [dev] [surf] Zombies when forking

2019-09-17 Thread Markus Wichmann
On Tue, Sep 17, 2019 at 12:15:59PM +0200, C.J. Wagenius wrote:
> Hi.
>
> I'm using surf on void linux (musl). I get a whole lot of zombies (sh 
> ) when spawning child processes (Go & Find). I don't know where the 
> optimal place is to put a waitpid for them but this works for me.
>
> # --- Start patch
> index 2b54e3c..ef1309b 100644
> --- a/surf.c
> +++ b/surf.c
> @@ -1327,6 +1327,7 @@ winevent(GtkWidget *w, GdkEvent *e, Client *c)
> {
>     int i;
>
> +   waitpid((pid_t)-1, NULL, WNOHANG);
>     switch (e->type) {
>     case GDK_ENTER_NOTIFY:
>     c->overtitle = c->targeturi;
> # --- End patch
>
> Thanks for awesome software.
>
> /cjw
>

You know, if no place in the code ever calls wait* except this line,
might be simpler to just set SIGCHLD to SIG_IGN during initialization.

Ciao,
Markus



Re: [dev] Re: json

2019-06-16 Thread Markus Wichmann
On Sat, Jun 15, 2019 at 09:28:05PM +0200, Mattias Andrée wrote:
> `long double` is able to exactly represent all values exactly
> representable in `uint64_t`, `int64_t` and `double` (big float
> can be used for other languages).

Not guaranteed. What exactly a long double is, is different for each
architecture. On the PC, you get an 80-bit IEEE 754 extended double
precision number (the minimum necessary to qualify for that title is 79
bits, and the Intel engineers threw in a completely useless "explicit
integer" bit in to make it a round number).

On AArch64, you get an IEEE 754 quad precision number (128 bits).
Unfortunately, in the absence of hardware support for that, any use of
the type adds large libraries to the runtime. And as of yet, I am not
aware of any hardware implementation of that type.

On PowerPC 64, you can get an IEEE 754 double-double. That is, a pair of
double precision numbers. Their sum is the actual value that is being
represented. No hardware support for that format directly, but since
there *is* hardware support for double, the library needed is a rather
thin wrapper.

I said you *can* get a double-double on PPC, because you can also use a
compiler flag to make long double equal to double. Musl for instance
requires this, as double-double is not a supported long double
representation.

On almost all other platforms (arm32 I know, the others I'm not sure
about) you get IEEE 754 double precision. Which doesn't have a large
enough significand to store all 64 bit values.

> In most cases, the
> program know what size and precision is required.
>

That leaves one problem: Big Number support. Should the JSON library
require a big number library be present, even for applications that
don't need or want it? If not, how to avoid that? With dynamic linking
that is impossible, to my knowledge. With static linking, you could get
around it.

But another, more organizational problem: If you have a JSON parser with
bignum support from another library, most applications don't want to
just load such a number, they will want to actually use it. And thus the
JSON library is suddenly mandating the bignum library to use. Worse, if
you have an application tying a JSON library and a cryptographic library
together, then both of these have to agree on the bignum library in
order to be compatible, or else the application has to link against
*two* bignum libraries (yay for duplicate code), and the application has
to translate between them. Because that's how I want my CPU cycles
spent.

Leaky abstractions are a b.

Ciao,
Markus



Re: [dev] [dwm] Need help about gray windows of Java applications

2019-05-15 Thread Markus Wichmann
On Wed, May 15, 2019 at 01:15:43PM +0200, Przemek Dragańczuk wrote:
> LG3D was a WM written in Java, which maximises the irony.

OK, I didn't know that one. Awesome.

> Java apps
> know how to work on it, so they work fine when they think they are
> running on it. The issue has something to do with reparenting, (which
> I don't know nearly enough about to explain) that some WMs (xfwm4, Gnome
> etc.) do the way Java expects, while others (dwm, qtile, LG3D) do it in
> a different way (or don't do it at all, I'm not sure).
>

Other WMs like to draw a title bar above the window, with some controls,
probably because Windows 3.11 did it this way, and some programmers are
nothing if not sticklers for tradition. But how to implement this in
X11?

Simple: When an application creates a window, it will create the new
window as child of the root window. The WM gets the event for that, and
creates a new window itself, that is a bit bigger than the window just
created. Then the WM tells X11 to make the new application window a
child of the WM's window - that is the reparenting step.

Tiling window managers often don't do this, and the result is a bare
window, only maybe embelished with a border.

I have no idea, how exactly the absence of this event causes Java apps
to blank. I tried to research it once and gave up -- OpenJDK is not the
nicest source code on Earth. Then again, Java is not the nicest language
on Earth. Event-wise it shouldn't make much of a difference either way.

> TL;DR: Java apps are stupid and have to be tricked into thinking
> they're on another WM to work.
>

Worse, the error is in a commonly used library for Java GUI apps (was it
AWT?). Therefore, the application developers can't do anything about
this. It's similar to the problem we have with libxft and colored fonts.
Until libxft is fixed, we're just going to have to crash dwm and dmenu
and st a whole lot.

Except in the latter case we could actually do something about this.

Ciao,
Markus



Re: [dev] key-value config reader

2019-05-12 Thread Markus Wichmann
On Sun, May 12, 2019 at 01:30:10AM -0700, Michael Forney wrote:
> What about _Generic in C11? This allows you to choose an expression
> based on the type of another expression.

God dammit, looks like I need to get some C11 training under my belt.
Completely forgot _Generic was a thing.

Ciao,
Markus



Re: [dev] key-value config reader

2019-05-12 Thread Markus Wichmann
On Sat, May 11, 2019 at 08:52:32PM +0100, Piotr Oleskiewicz wrote:
> I would prefer to
> write
>
>   X(int, i, 1)
>
> rather than
>
>   X(int, i, atoi, "%d", 1)
>
> Many thanks,
> Piotr
>

That is going to be tough, as in C in a macro, there is no way to really
determine what type name you were given. The only thing standard C has
to offer to help is "sizeof", but that doesn't help you, obviously.
(sizeof(float) == sizeof(int)).

In C++, you'd have "typeid", but then you'd also have C++, so that's a
hard pass.

However, would you be willing to settle for

X_INT(i, 1)

?

Ciao,
Markus



Re: [dev] lex and yacc

2019-03-09 Thread Markus Wichmann
On Sat, Mar 09, 2019 at 06:59:38PM +, sylvain.bertr...@gmail.com wrote:
> Hi,
> 
> I am coding a little/simple custom language parser, and I was wondering if 
> there
> are "suckless" grade alternatives to flex and bison, anyone? But wait...
> 
> That said and as of today, I still don't agree with myself on the usefullness
> of lex/yacc in the first place. For instance, I am puzzled by line/column
> tracking, which can be tricky (for instance C preprocessor/compiler accurate
> line/column tracking with line-return escaping with lex/yacc??)
> 
> Maybe it's not an implementation issue of lex and yacc... they may actually
> be _not_ suckless at all. Any thoughts on this?
> 
> -- 
> Sylvain
> 

Well, other people have made that point before: Why use a regex to
identify a token when a simple loop will do?

So for lexing, usually a simple token parser in C will do the job
better. And for parsing, you get the problem that yacc will create an
LALR parser, which is a bottom-up parser. Which may be faster but
doesn't allow for good error messages on faulty input ("error: expected
this, that, or the other token before this one"). That's why top-down
recursive-descent parsers (or LL(1) parsers) are superior. Maybe
supplemented with a shunting-yard algorithm to get the binary
expressions right without having to call layer after layer of functions.

Ciao,
Markus



Re: [dev] xml parser

2019-02-03 Thread Markus Wichmann
On Sat, Feb 02, 2019 at 06:15:26PM +, sylvain.bertr...@gmail.com wrote:
> Hi,
> 
> I am looking at xml parsers.
> 
> I am about to go expat, but I am wondering if there are some interesting
> alternatives I did miss?
> 
> -- 
> Sylvain
> 

At work, we're using libxml2. Since we are also using static linking,
this has caused our firmware package to go from 20MB to 60MB unzipped.
So I hope this helps you find a good package, by showing you where it
isn't.

Ciao,
Markus



Re: [dev] Let's talk about Go, baby

2019-01-30 Thread Markus Wichmann
On Tue, Jan 29, 2019 at 02:34:19PM -0600, Cág wrote:
> Well, I assumed most people on this list do write C for a living, isn't
> that so?
> 

I certainly do. Working in embedded stuff.

> Can you web development in C?
> 

You can, since you can do anything in C. But why would you want to? Web
dev is usually about databases and string manipulation, both of which
aren't exactly C's strong suit.

Ciao,
Markus



Re: [dev] Let's talk about Go, baby

2019-01-25 Thread Markus Wichmann
On Fri, Jan 25, 2019 at 08:41:54PM +0100, Silvan Jegen wrote:
> The opinions on Go are mixed on this list from what I remember.

Oh boy, that again. If you wait a minute, someone will tell you that Go
is bloated because a Hello World clocks in at 2MB or something.

I have a different problem with Go: Their insistence on reinventing the
wheel. I am also subscribed to the musl mailing list, and recently
there's been a thread about a Go program going into a deadlock.
Investigation revealed that the Go runtime does not use the libc
functions for sigfillset() or sigprocmask(), but rather, fills a buffer
with 1-bits and wraps the system call directly, respectively. Which of
course blocks libc internal signals. They made it work on glibc by
somehow exempting SIGRT32 and SIGRT33, but musl also needs to be able to
use SIGRT34. Wouldn't be a problem if they just used the defined
interfaces, but they don't.

Would also not be a problem if the Go runtime entirely supplanted the
libc. Go whole hog or not at all, is my opinion. The current in-between
solution suffers from the worst of both worlds.

Ciao,
Markus



Re: [dev] Coding style: why /* */ and not //?

2019-01-10 Thread Markus Wichmann
On Thu, Jan 10, 2019 at 08:11:57PM +, sylvain.bertr...@gmail.com wrote:
> Expect POSIX to add significant technical cost over time, like ISO, ANSI,
> the most monstruous being the w3c.

You ever try to write POSIX utilities according to the standard? Believe
me, POSIX of all standards doesn't need to add anything to incur
significant technical cost. Just say "cat -u". I mean, -v is considered
harmful, but what about -u? Considered useless? system() is supposed to
return 127 if the command interpreter could not be launched. That's
mighty specific. cp -i is a thing. Etc. pp.

However, for ISO C it is actually pretty easy to spot MS contributions.
In this case, look at Annex K. C89 contained a lot of badly designed
interfaces in Clause 7, so C95 added a few better designed alternatives
(or bodges on the original design, depending on your view). And then M$
came along and added Annex K, where they added _s to a lot of functions
and said "Use these henceforth. Just go through your code with a
find-and-replace and then sin no more." And nobody, absolutely nobody
bought it. These functions are also badly designed, but for other
reasons than the C89 functions.

Thankfully that whole nonsense is confined to an optional annex of the
standard, that next to nobody implements. M$ does of course, but Visual
Studio is not really relevant when it comes to C implementations. They
still only implement C95, with cherry-picked features from C99, mostly
ones that are also in C++.

Ciao,
Markus



Re: [dev] [dmenu] running shell scripts in dmenu

2019-01-04 Thread Markus Wichmann
On Fri, Jan 04, 2019 at 02:17:12PM -0200, Caio Barros wrote:
> That's it! Yes, I'm unfotunately still runing a display manager:
> lightdm. I'm slowly getting rid of the bloat [...]

It was never my intention to advise you of how bloated or unbloated your
system can be. To be honest, I don't know if having a redundant shell
session hang around is more bloated than an additional program in the
background. I refuse to run a DM because I have had bad experiences with
those in the past (namely, that the default X11 configuration would
crash the machine, but on Debian there was no easy way of preventing the
system from starting it with a DM installed). But you do you. Whatever
makes you happy.

Honestly, starting from console and typing in "startx" brings back
memories of starting up my 486 and typing in "win". Makes the experience
feel a bit unevolved.

Ciao,
Markus



Re: [dev] [dmenu] running shell scripts in dmenu

2019-01-04 Thread Markus Wichmann
On Fri, Jan 04, 2019 at 10:20:42AM -0200, Caio Barros wrote:
> Em qui, 3 de jan de 2019 às 23:22, Martin Tournoij  
> escreveu:
> 
> > Note there is a typo in that hashbang,
> 
> oops! I was typing as I went :D. Actually in the original script I
> didn't add the shebang #!/bin/sh, but I did it now
> 
> > Just reboot your system if you're unsure.
> 
> Hum, still doesn't work. If I understand correctly, dwm uses the scipt
> dmenu_path to know which are the available commands. When I look to my
> ~/.cache folder it doesn't have my scripts in there. Maybe it is the
> way I added the folder to path? I think I just added the following
> lines to my ~/.bashrc file:
> 
> PATH="/home/caio/scripts:${PATH}"
> export PATH
> 

How are you starting dwm? If you are using a display manager (a
graphical login), check on how it logs you in. It is possible it doesn't
start a shell to start dwm, so then the bashrc is never run. I have no
idea how to solve that problem. I think you might try to put that into
~/.profile, but I'm not sure.

I run dwm from startx. So I know all the variables present in the first
shell started from the login will be present in dwm, and therefore also
in dmenu.

Ciao,
Markus



Re: [dev] Make cleanup

2018-12-30 Thread Markus Wichmann
On Sat, Dec 29, 2018 at 08:32:13PM -0500, stephen Turner wrote:
> If one was going to rewrite a cleaner make what would be the recommended 
> approach?
> [...]
> I am not skilled enough to start from scratch [...]
> 

Maybe start with that. Make is a pretty simple algorithm: You build a
dependency graph (which is a directed acyclic graph), then you find the
target you are supposed to make (i.e. the first target or the command
line arguments), rebuild its dependencies, then rebuild the target
itself.

So you need a way to represent an acyclic directed graph where each node
has a name and a variable number of edges. You need to be able to check
if it is indeed acyclic.

Next is to handle expansion. Most make targets contain variables you
need to replace. Then you can just hand the resulting line to system().
I am ordinarily no great fan of system(), but for make it is probably
appropriate.

And finally, you should probably add parallelism. There are a few ways
to deal with it. I do have an idea, though: Each node in the graph gets
a thread ID, a mutex, and a condition. A worker thread will then grab
the mutex of its own node, iterate over its dependencies, grabbing the
mutex of the dependent node, checking if the thread of the dependent
node was spawned, spawn it if not, then wait on the condition variable
(then release the mutex, obviously). Then, once all the dependencies
are done, run the command associated with your own node, broadcast on
the condition variable, release the mutex and exit. If all the threads
are detached, there will not be a need for a pthread_join() (else you'd
need an ownership model).

Since the graph is acyclic, the dining philosophers problem will not
occur. And I see no other way for a deadlock.

Anyway, once these are all done, getting your make to be standards
compliant should be simple matter of adding a bit of fluff around
everything (for instance, the Makefile and all included files are
usually implicitly remade before everything else, if they are out of
date. And even if you have n+1 threads running, you need to limit the
number of subprocesses to whatever the argument to "-j" was, which you
can do with a semaphore. And then there's all the stuff GNU make added
to the expansion mechanism.)

Actually, now you got me started, gonna try to rig up at least a POC.


> 
> I see in a slightly older 2012 release of the code entries for windows
> 32 and amiga. I’m questioning why!
> 

Are you talking about GNU make? Because I can tell you from experience
that the GNU utilities are not a great learning ressource. You will
likely miss the forest for the trees. Or miss the interesting parts for
all the GNU fluff around it.

> Would it be worth while to strip make of these items and then attempt
> to clean the code section by section? Diff a legacy and perhaps gnu
> exclusive version against a newer release, or perhaps another
> approach?
> 

Nah, that would be like trying to polish a turd at this point.

> In the past I have learned coding by jumping into an existing item and
> rewriting, not sure if this is a task I will take on but the thought
> has crossed my mind.
> 

You should probably try to learn a bit about the computer science behind
these projects. Granted, there isn't a whole lot of CS that goes into
cp, but for some of the more interesting programs, like make or diff,
the coding can obscure the actual algorithm that makes it work. diff
isn't about opening and reading files, even though that is part of the
algorithm. :-) (The same way gingerbread isn't about the flour.)

> Thanks,
> Stephen

Ciao,
Markus



Re: [dev] GPL free Linux

2018-11-13 Thread Markus Wichmann
On Mon, Nov 12, 2018 at 01:14:38PM -0800, Michael Forney wrote:
> Usually how it works is either the display server itself needs to be
> setuid to open those input devices, or some other program (commonly
> systemd-logind) needs to open it on its behalf. I believe Xorg with
> systemd disabled will need to be setuid because of this.
> 

I lack the words to describe how broken I think it is, to make an
application setuid because you couldn't be arsed to set file permissions
properly. Or at least, the words to do so in a civilised manner.

Ciao,
Markus



Re: [dev] GPL free Linux

2018-11-12 Thread Markus Wichmann
On Mon, Nov 12, 2018 at 11:17:49AM +, Alessandro Pistocchi wrote:
> On 12 Nov 2018, at 05:28, Markus Wichmann  wrote:
> > 
> > That's why you have an iPhone?
> 
> You would be surprised. I still use an old phone with the numeric keys
> as a mobile phone.
> 

Those are great: If you get mugged, you can try dialling 911 in your
pocket. Try doing that with touch screen buttons.

> 
> I would use some help to make it work with X ( does it work with
> Wayland? ). There are not many docs I found about it...
> 

Ah, that old chestnut. As far as I know, the X input driver "evdev"
depends on the paths of the event devices being in /dev/input, and on
you having read access to them. I don't know if smdev puts them there by
default, nor how it sets the permissions on those files. Also, there's a
dependency on libudev in there somewhere. I don't know if that can pick
up files from smdev.

The files should be named according to the links in /sys/class/input.
You should also be able to see the error messages in X11's log file.
That should tell you what's wrong. And if all else fails: strace.

I have no experience with Wayland but I suppose it requires a similar
setup. Not having read permission on a device file is a showstopper no
matter the codebase.

> > Well, that means all of nothing. Walking can be a credible
> > alternative to driving in some circumstances, but not if the
> > distance is 400km. What do you want out of a desktop machine?
> 
> I want to have a windowing system, compilers and libraries mainly.
> Also I need make and I would like to have flex and bison.  Maybe a web
> browser and a graphical IDE for source code editing but I am not even
> sure about that.
> 

I was going to ask "Why not just use sta.li?" but that project
apparently doesn't exist anymore.

And that is pretty much exactly what I want from a distribution as well,
and I just use Debian (you know you can just remove systemd from Debian,
right?)

> > 
> > Also, are you aware that creating and maintaining a Linux distribution
> > is a whole lot of work? The city of Munich recently discovered this, and
> > that's why they are switching back to Windows. That, and corruption of
> > course; this is public admin we're talking about.
> 
> Yes if you want a lot of functionality to manage a city.
> Doing what I am trying to do is way way simpler and could never be
> used by the city of Munich without a lot of additional work.
> 

I was mostly referring to the need to keep your software up-to-date, if
for no other reason then to benefit from security patches. This appears
to have been the biggest failing of the two lads who lead the project.
See, with Debian, an army of maintainers does all the work for me, and I
just need to "apt-get upgrade" once in a while. And then delete systemd
again.

> 
> Ok sorry, wrong example.
> 
> Like I said above, I want a windowing system, compilers, libraries,
> and IDE and a library to make desktop apps as easily as possible.  I
> want to be able to make and play games and to experiment with coding.
> 

Please, do tell if you find such a library. The ones I found were either
the wrong language (Tk, Qt, FLTK), or hopelessly obtuse (gtk). Or pretty
much no assistance at all (xaw, motif).

Ciao,
Markus



Re: [dev] GPL free Linux

2018-11-11 Thread Markus Wichmann
On Mon, Nov 12, 2018 at 03:01:02AM +0100, Alessandro Pistocchi wrote:
> Hi everyone,
> 

Hi Alessandro,

> I am new to suckless.org. I have seen some of your projects and I
> think I share a vision with you guys to make things as simple as
> possible but not simpler.
> 

That's why you have an iPhone?

> I am working on a project to remove gpl stuff from Linux userspace ( I
> am ok with GPL executables but not with GPL or LGPL libraries ) and I
> see that your projects tend towards more open licenses.
> 

Why would you do something so pointless? First of all, licences only
matter if you plan on redistribution, so most here won't care. Second,
all the GPL demands is that you distribute the source, which any good
distribution should do, anyway, right?

The reason some here choose to replace GPL'ed code with alternatives is
less the licence and more the code quality. The utilities from GNU are
correct and all, but some here don't understand why it is necessary for
the true program to have command line options.

And for some reason, featuritis and GPL seem to be correlated. I won't
look for the causality here, though.

> Particularly, I want to replace udev with smdev. 
> 
> I was wondering if anybody would be interested in helping me.
> 

What's to help? You download the source, install it, remove udev from
your init system and add smdev to it. Maybe add some configuration, but
the defaults seem to work pretty well.

> My aim is to create a Linux distribution that is simple to get started
> with but at the same time is a credible alternative to windows and
> macos as a desktop machine.
> 

Well, that means all of nothing. Walking can be a credible alternative
to driving in some circumstances, but not if the distance is 400km. What
do you want out of a desktop machine?

Also, are you aware that creating and maintaining a Linux distribution
is a whole lot of work? The city of Munich recently discovered this, and
that's why they are switching back to Windows. That, and corruption of
course; this is public admin we're talking about.

> I want something like a modern version of a home computer like the
> Amiga was many years ago but with current features like GPU and all
> the goodies we have now.
> 

And what does that all entail? From some perspective, Linux running a
terminal program is just a modern version of DOS; an opinion I don't
share, but that is bandied about regardless. But what is "a modern
Amiga" to you? I'm afraid I was born too late for that one.

> Best, Alessandro Pistocchi
> 
> Sent from my iPhone

Ciao,
Markus



Re: [dev] [st][PATCH] better plumbing on linux: find child shell cwd without shell gymnastics

2018-11-01 Thread Markus Wichmann
On Thu, Nov 01, 2018 at 04:12:40PM +0100, John Soros wrote:
> Yes! This is much, much better! Thanks. Pity that it still doesn't work
> on OpenBSD.

If the info I gathered over the course of the last hour is correct, then
the way to query CWD in OpenBSD is

#include 
char cwd[PATH_MAX];
size_t sz = sizeof cwd;
int name[3] = {CTL_KERN, KERN_PROC_CWD, pid};
sysctl(name, 3, cwd, , 0, 0);

Also, if my understanding of Linux /proc is correct, then realpath()
might be overkill, and readlink() would already suffice. The links in
/proc aren't really symlinks. For instance, dietlibc's realpath() will
actually use readlink() on /proc/self/cwd to do its job... though, it
could just use readlink() on /proc/self/fd/XX, then it wouldn't need to
chdir()... I digress.

The question is how to incorporate such code. Do we create OS specific
source files and compile in the ones needed, or do we go for conditional
compilation? The former is more complicated, as it involves mapping out
an interface that each OS source file has to follow. And in the long
run, it might start sucking, as the OSes aren't as orthogonal as
originally thought, and we end up copying some functions, and then
having to copy bugfixes... sucks a bit. Conditionals also suck a bit, as
we end up seeing a lot of what amounts to commented-out code. Giving up
on unportable features also sucks, as it precludes useful features like
the one in this submission. So, which option sucks least?

Ciao,
Markus



Re: [dev] [st][PATCH] better plumbing on linux: find child shell cwd without shell gymnastics

2018-11-01 Thread Markus Wichmann
On Thu, Nov 01, 2018 at 09:33:37AM +0100, Quentin Rameau wrote:
> Hello John,
> 
> > +   DIR* srcdir = opendir("/proc/self/task");
> 
> Is that a Linux‐only patch?
> 

The subject line would indicate thus. Funnily enough, *that* dependency
could be removed. What can't be removed is the dependency on
/proc/XXX/cwd. Is that available on whatever OS you care about (I know
it was one of the BSDs, just don't remember which)?

Ciao,
Markus



Re: [dev] [st][PATCH] better plumbing on linux: find child shell cwd without shell gymnastics

2018-11-01 Thread Markus Wichmann
On Thu, Nov 01, 2018 at 08:46:06AM +0100, John Soros wrote:
>  config.def.h |  6 +
>  x.c  | 76 
>  2 files changed, 82 insertions(+)
> 
> diff --git a/config.def.h b/config.def.h
> index 87ebdbb..265a4ff 100644
> --- a/config.def.h
> +++ b/config.def.h
> @@ -467,3 +467,9 @@ static char ascii_printable[] =
>   " !\"#$%&'()*+,-./0123456789:;<=>?"
>   "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
>   "`abcdefghijklmnopqrstuvwxyz{|}~";
> +
> +/*
> + * plumber_cmd is run on mouse button 3 click, with argument set to
> + * current selection and with cwd set to the cwd of the active shell
> + */
> +static char *plumber_cmd = "plumb";
> diff --git a/x.c b/x.c
> index 4345892..f319129 100644
> --- a/x.c
> +++ b/x.c
> @@ -5,6 +5,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -644,6 +647,77 @@ xsetsel(char *str)
>   setsel(str, CurrentTime);
>  }
> 
> +char *
> +subprocwd()
> +{
> + struct dirent* dent;
> + DIR* srcdir = opendir("/proc/self/task");
> + char path[PATH_MAX];
> + FILE *fp;
> + int chpid;
> +
> + if (srcdir == NULL)
> + {
> + return NULL;
> + }
> +
> + while((dent = readdir(srcdir)) != NULL)
> + {
> + struct stat st;
> + char newdir[PATH_MAX];
> +
> + if(strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") 
> == 0)
> + continue;
> + if (snprintf(newdir, PATH_MAX, "%s/%s", "/proc/self/task",
> dent->d_name) < 0)
> + return NULL;
> + if (stat(newdir, ) < 0)
> + continue;
> +
> + if (S_ISDIR(st.st_mode)) break;
> + }
> + closedir(srcdir);
> + if (snprintf(path, PATH_MAX, "/proc/self/task/%s/children",
> dent->d_name) < 0)
> + return NULL;
> + if (!(fp = fopen(path, "r")))
> + return NULL;
> + if (fscanf(fp, "%d", ) != 1) {
> + fclose(fp);
> + return NULL;
> + }
> + fclose(fp);
> + if (snprintf(path, PATH_MAX, "/proc/%d/cwd", chpid) < 0)
> + return NULL;
> + return realpath(path, NULL);
> +}
> +

You know, you can have that one cheaper: /proc/self/task will contain a
directory named for the TIDs of each thread of the process. As st is a
single-threaded process, that TID must always equal the PID. So the
first loop can be replaced with.

snprintf(path, PATH_MAX, "/proc/self/task/%d/children", getpid());

Also, your code assumes the shell to be the only child of st, but spawns
other children of st. How about you iterate over all processes, finding
the ones with a PPID equaling st's PID and having an exe pointing to the
shell (maybe remember the shell spawned in a global variable)? Speaking
of remembering things, might it not be easier to just remember the
shell's PID from the point it was spawned in the first place? Then you
don't need to iterate over rarely-available system interfaces.

> +void
> +plumb(char *sel) {
> + if (sel == NULL)
> + return;
> + char *cwd;
> + char *cmd;
> + pid_t child;
> + cwd = subprocwd();
> + if (cwd == NULL)
> + return;
> +

So, if it all failed somehow, you won't even spawn the command in st's
current directory? Nor give any indication of failure to the user.

> + switch(child = fork()) {
> + case -1:
> + return;
> + case 0:
> + if (cwd == NULL)
> + exit(1);
> + cmd = malloc(PATH_MAX+100);
> + if (snprintf(cmd, PATH_MAX+100, "(cd %s ; %s %s)", cwd, 
> plumber_cmd,
> sel) < 0)
> + exit(1);
> + free(cwd);
> + execvp("sh", (char *const []){"sh", "-c", cmd, 0});
> + exit(0);

This won't work if there is a space in cwd. Which there might be. Also,
why change dir in the shell? Just change dir in the process. You have
the directory right there, just call chdir() and call it a day.

Also, do you want word separation to take place? Because if not, I see
no reason for the shell at all.

Ciao,
Markus



[dev] Some questions about sdhcp

2018-10-11 Thread Markus Wichmann
Hi all,

I recently read the source code of sdhcp, and it does seem to be a nice
tool, but I couldn't help but notice a few things. Now, maybe I'm dense,
and none of the things I'm about to bring up matter for some reason, and
if so, that would be really cool. But some of these really do seem like
major issues, so here goes:

1. Timeout based on alarm()
---

That is, in principle, not a bad way to do it, but unsuitable for a
laptop application, which might see extended time spent in a sleep
state. This is mostly an issue during the Bound state, as I have no idea
if the alarms get adjusted for the time slept, and what happens if the
alarm times out during sleep.

That said, I also have no idea what happens to monotonic clocks, so what
the heck.

2. Signal handlers established with signal()


Unfortunately, the BSD-v-SysV war has destroyed that interface beyond
usability. On Linux, it depends on the libc, and for glibc also on the
compiler flags, whether you get oneshot behavior or persistent behavior.
So now we have to use sigaction() to establish signal handlers, or
always re-establish the handlers from within, just in case.

musl gives the BSD behavior always, BTW.

3. Broken timing model
--

The code reads the value from the Lease Time option into a variable
called "t1", and proceeds to use that variable as T1 (i.e. the time
after which the lease should be renewed). That is not what the lease
time is!

The RFC states that after the lease time has elapsed, the client must no
longer use the address granted to it, and failing to do so was the
reason why many Apple devices where banned from some Ivy League campus
network or other, some years back; which was a great source of humour
for me and others. Yet here we are, doing the same thing wrong.

The RFC states that T1 is specified in option 58, and T2 in option 59.
Failing these, T1 is 1/2 lease time, and T2 is 7/8 lease time. Apropos
failing:

4. Christian search routines


The Bible states "Seek and you will find" but it might not be a
great idea to implement this in a computer program. Unfortunately,
optget() has absolutely no way of communicating failure to find a given
option, and its callers don't seem to care much, either way. "Be lenient
in what you accept" is all well and good, but not when the most
important pieces of data are missing.

5. Absolutely no timeout in Renewing and Rebinding states
-

I couldn't find info on what happens after an alarm fires, but the only
behaviors that make any sense are (a) alarm() is oneshot, and (b)
alarm() is cyclical. Once sdhcp has made it into Bound state, an alarm()
for the lease time is registered. When that fires, no further alarm is
registered as sdhcp sends out a single request for renewal. If that
packet, or the acknowledgment of it, drops for any reason, we're stuck
in Renewing with either no timeout, if (a) is true, or one lease time
(typically something like 1 day) as timeout, if (b) is true.

The RFC states that the client should set the packet timeout in these
states to half the remaining time (until T2 or lease time), down to one
minute.

6. No XID reroll or comparison
--

The XID is rolled once, at the start of the process, and never rolled
again. Shouldn't a different XID be used for each separate transaction?
That might be down to taste, but this one is not: XID is never compared
to the XID of a received packet. And neither is the CID. Thus, sdhcp
ends up stealing people's leases! I mean, the whole protocol is
broadcast, we're bound to see a packet that wasn't meant for us.

7. Use of the realtime clock for time measurement
-

For some reason I don't quite get, DHCP clients are required to send the
time they spent working in the packet header. Well, not required; we
could just null the field. But since we do send something, we might as
well do it right. Currently, the time is measured by way of the time()
function, which returns the current realtime clock value. Thus, if we
were starting up on a system without battery backup, we would get a time
in 1970. If after getting a lease, the clock is then corrected with NTP,
suddenly we will tell the DHCP server that we spent almost 50 years
talking to it, which it might take exception to.

All of this could be solved by way of clock_gettime(CLOCK_MONOTONIC).
Just wrap it with an interface similar to time() first.

8. Race condition for timeouts
--

If an alarm should fire while we are not blocked in a syscall, it will
be ignored, and the program will hang. That could be solved with a
global flag that is set from the signal handler, but that will
significantly increase complexity (since we need to reset the flag after
taking notice of it) and is not without its pitfalls (cf. 

Re: [dev] [sbase] find and xargs different results than busybox

2018-07-20 Thread Markus Wichmann
On Thu, Jul 19, 2018 at 03:49:10PM -0400, Cág wrote:
> If you take a look at README (https://git.suckless.org/sbase/tree/README),
> you'll find out completeness of the programs and missing arguments; out
> of all I only wonder why multi-column output of ls(1) is intentionally
> left out. On Plan 9 it is one-column, too, though.
> caóc
> 
> 

Because ls's job is to list files. Not to columnate output. There's
another tool for that.

Unfortunately, GNU ls is capable of outputting color codes, but BSD
column is not capable of understanding them. I tried to write something
like this myself, once, and I wonder what's the easiest way to find out
the width a string will take up on a terminal. Because that's the info
you need to columnate the output properly, and short of implementing all
possible terminal control strings myself again, I don't know how to do
this. wcwidth() is of limited utility in this quest, as control codes
consist of multiple characters of which most do take up space if on
their own, but don't in this sequence.

Ciao,
Markus



Re: [dev] [sbase] find and xargs different results than busybox

2018-07-18 Thread Markus Wichmann
On Tue, Jul 17, 2018 at 07:28:25PM -0700, Eric Pruitt wrote:
> The suckless tools don't strictly follow POSIX. For example, sbase mv(1)
> and cp(1) don't support "-i". Furthermore it's pretty portable; find(1)
> on OpenBSD, FreeBSD, macOS and GNU find(1) all support using NUL bytes.
> It's the only sane way to securely support any legal filename.
> 
> Eric
> 

And that's where you're wrong. "find | xargs" is wrong for the same reason
"sudo su" is wrong, for the same reason "cat singlefile | whatever" is
wrong: You're doing it wrong. In your case "find -exec" does everything
you want. It also supports all possible file names.

Ciao,
Markus



Re: [dev] ASCII Delimited Text

2018-05-21 Thread Markus Wichmann
On Mon, May 21, 2018 at 07:12:46PM +0300, Adrian Grigore wrote:
> cc -lutf -o cat cat.o util.o
> cat.o: In function `main':
> cat.c:(.text+0x179): undefined reference to `chartorune'
> cat.c:(.text+0x1dd): undefined reference to `runetochar'
> cc: error: linker command failed with exit code 1 (use -v to see invocation)
> gmake: *** [Makefile:15: cat] Error 1

Try putting the library at the end. Some linkers display rather...
classic behavior when linking statically (i.e. only linking in the files
that are needed, but if you name a library as first thing, then no file
is needed at that point).

Ciao,
Markus



Re: [dev] [surf] [patch] strip uri leading whitespace when ctrl-p

2017-10-19 Thread Markus Wichmann
On Thu, Oct 19, 2017 at 12:19:13PM +0200, Quentin Rameau wrote:
> Hello Jianzhong,
> > It's easy for keyboard selection, but for mouse selection, precise
> > positioning is a little bit difficult.
> 
> I'd suggest you manage this outside of surf, either by training your
> mouse skills, or by stripping those leading whitespaces in your
> selecting application.
> 

No. For one thing, if he actually did this, I foresee a patch in the
near future, this time for st, to strip white space off of the
selection, and it will be rejected by you or someone like you, saying
"this should be handled by the target application". Sending people from
Pontius to Pilate like that is not very nice.

For two, in this case the target application is the one that knows
something about the text to be pasted, namely, that it's a URI. Since
those never start with white space, surf is actually in the better
position to perform any string manipulation, that if some other
application had to try and guess at the intent of the user.

> I'd suggest a simpler approach like this :
> 
> diff --git a/surf.c b/surf.c
> index 0f8b9c9..8a40a3b 100644
> --- a/surf.c
> +++ b/surf.c
> @@ -1685,9 +1685,14 @@ destroywin(GtkWidget* w, Client *c)
>  void
>  pasteuri(GtkClipboard *clipboard, const char *text, gpointer d)
>  {
> -   Arg a = {.v = text };
> -   if (text)
> +   Arg a;
> +
> +   if (text) {
> +   for (; *text && (*text == ' ' || *text == '\t'); ++text)
> +   ;
> +   a.v = text;
> loaduri((Client *) d, );
> +   }
>  }
> 

Thanks. I already thought the simple loop solution was never coming up.

Ciao,
Markus



Re: [dev] Privilege escalation on remote hosts. MANY remote hosts.

2017-09-26 Thread Markus Wichmann
On Sun, Sep 24, 2017 at 11:08:23PM -0400, Rendov Norra wrote:
> The archive shows silence and positivity on threads with go in the subject. 
> Unfortunately gmane is unusable, so there's no way to search bodies.

I guess everyone here is just too jaded to respond to those threads
anymore. Anytime someone posts something that is not in C, the core
posters in this ML get their panties in a twist and demand a rewrite.
Going so far as to call C++ an insidious infection that is slowly
spreading. Oh, the horror! Other people make different choices than you.
Imagine that! Especially if they have other priorities than you.

These threads always converge after finitely many steps to a discussion
about programming languages, which are as useful as discussions about
religion, and just as toxic. So these days, whenever someone comments on
programming languages, I just up the strategic popcorn reserves and
await the show.

Ciao,
Markus

P.S.: My stance is that whatever language gets the job done and works
for the developers involved is best, and don't let people from outside
the project convince you otherwise. I just noticed that all the
languages I learned except C don't get the job done for me.



Re: [dev] a

2017-02-02 Thread Markus Wichmann
On Thu, Feb 02, 2017 at 07:20:34PM +0100, willy wrote:
> Hello everyone,
> 
> While playing with sbase and musl, I encountered a strange bug: tar
> fails to extract bzip2 compressed archives when bzip2 is compiled
> against musl (I only tested static linking). Note that bzip2 uncompresses
> the files correctly. The error only occurs when the data flows through
> a pipe:
> 

If an error occurs only when a pipe is involved, then in principle only
two things could go wrong: bzip2 could be failing to handle short writes
correctly or tar could be failing to handle short reads correctly.

If it was the latter then I'd expect to see weird behavior regarding
blocks and the start thereof. Like, for instance:

>   chktar: invalid magic "ootfs, datadir, *argv);
>   if (action == ACTION_UPDATE)
>   r += update(rootfs, datadir, *argv);
>   if (action == ACTION_DELETE)
>   r += delete(rootfs, datadir, *argv);
>   argv++;
>   }
>   break;
>   case ACTION_INSPECT:
>   if (inspect(datadir, n) != 0)
>   retu"
>   musl/tar: malformed tar archive
> 

If it was the former, then I'd expect similar behavior, however not
exactly like this. If bzip was failing to notice that some decompressed
data isn't written, tar would be seeing start blocks too late, not
too early, as it does here.

So, looks like a tar bug.

Ciao,
Markus



Re: [dev] Some core tools

2017-02-02 Thread Markus Wichmann
On Thu, Feb 02, 2017 at 06:45:49PM +0100, Mattias Andrée wrote:
> Greetings!
> 
> I'm work on implementing make(1), and I have two questions for you:
> 
> 1) What extensions do you think I shall implement? I think I will
>add $(foreach), $(shell), and I will definitely add $(SHELL).
>$(SHELL) is the macro that use to select the shell to use, POSIX
>only standardises that the macro SHELL not affect or be affected
>by the environment variable SHELL. I need $(SHELL) be sh(1p) is
>not sufficient to use blind in a sane manner. I'm not sure that I
>will add support `-j jobs`, and I don't I will add `-l loadavg`,
>but it will recognise those options and, if not implementing
>them, ignore them.
> 

GNU make style patsubst rules, i.e.

%.o: %.c
$(CC) $(CFLAGS) -o $@ $<

Those are really useful. If I recall correctly, mk implements something
equivalent.

Ciao,
Markus



Re: [dev] [sbase] [tar] some errors

2016-12-24 Thread Markus Wichmann
On Fri, Dec 23, 2016 at 08:07:11PM +, Cág wrote:
> Hi,
> 
> I was trying to create an archive with my gtk themes with
> "tar -c themes | xz > themes.tar.xz"
> and it says "tar:strlcpy: input string too long".
> 
> The same happens without piping. BusyBox' tar did this
> fine.
> 
> Also, when trying to extract the created archive (tar -xvf),
> it says "malformed tar archive". I've tried creating an
> archive from a single file, tar does it but when trying to
> extract it I get the error above.
> 
> 
> Cág
> 

Hello,

the above error message appears if estrlcpy() is called with an input
string of greater length than the output buffer. estrlcpy() is called
three times from within tar.c (I am uncertain as to whether tar.c calls
library functions that might call estrlcpy(), but that is of little
consequence). One instance is 

estrlcpy(h->name,path,sizeof(h->name));

Well, that looks like it might be problematic, doesn't it? Especially
when you find out, that the size of h->name there is 100 bytes. path
contains, of course, the entire file path relative to the starting
directory. In short, you will get this error message whenever trying to
package files with a total relative path length of more than 100
characters.

sbase tar does not appear to implement any of the existing schemes for
handling long file names, probably because those "suck". Except of
course that a tar program which fails if tasked with abnormal workload
sucks way more than kludgy file formats.

Some further reading revealed GNU tar's trick to be to insert a file of
type 'L' (76), call it "././@LongLink" or something (name isn't really
important) and write the file name into that file's content. Then add
the file as normal, truncating the name to 100 characters. Is that a
viable option for sbase tar?

Ciao,
Markus



Re: [dev] [st] can't set reverse cursor

2016-10-19 Thread Markus Wichmann
On Wed, Oct 19, 2016 at 11:02:03AM +0100, Cág wrote:
> Hi,
> 
> I have 16 colours in config.h from my palette, from 0 to 15,
> with 0 (black) being defaultbg and 7 (white) being defaultfg.
> My cursor is 12 (brblue) and reverse cursor is set 7 (white).
> However, in reality reverse cursor is 0 (black), which is bg.
> Also, setting rcs to any other colour doesn't help and it
> remains the same, that of defaultbg.
> 
> Also, compiling gives me this:
> 
> st.c:3135:14: warning: 'width' may be used uninitialized in this function
> [-Wmaybe-uninitialized]
>   if (term.c.x+width < term.col) {
>   ^~
> 
> 
> 
> Cág
> 

That message is strange, because I thought GCC performed control flow
analysis to see if variables are initialized or not. But here there
appears to be a bug in it.

The statement in question appears in the function tputc(), which is
rather large. However, it starts with an if-else selection, The only way
to get past it without assigning some value to width is by having the
UTF-8 or SIXEL mode bits set and control be set to nonzero. If control
is set to nonzero then the function will return early directly after
"check_control_code:", so the statement in question here is never
reached.

So, GCC is talking bollocks here.

Ciao,
Markus



Re: [dev] ot: C Standard noreturn

2016-09-22 Thread Markus Wichmann
On Thu, Sep 22, 2016 at 08:04:44PM +0200, u...@netbeisser.de wrote:
> main.c:7:10: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before 
> ‘void’
>  noreturn void __stack_chk_fail(void);
> 

noreturn is already a return type (in as much as void is one, namely
syntactically), so remove the "void" and you should be fine.

> tried 
> void __stack_chk_fail(void) __attribute ((noreturn));
> instead.
> 

That however only works with gcc and compatibles.

Ciao,
Markus



Re: [dev] How do you do statistics?

2016-09-11 Thread Markus Wichmann
On Sat, Sep 10, 2016 at 08:09:41PM +0200, Antoni V. wrote:
> Hi everyone from suckless.
> 
> I wanted to know how you perform basic (and not so basic) statistics.
> There are programs like R, but they are generally too big and complex.
> 
> I'm aware of desc [1] but it's missing a lot of useful tools; plus appears to 
> be unmaintained.
> 
> Is R the only option?
> 
> Waiting for your input.
> Thanks.
> 
> [1] https://github.com/loicseguin/desc
> 
> 

Hi,

I just use perl if the data sets aren't too big. Works for my needs, but
I wrote all the necessary stuff myself. Oh, and gnuplot for plots, of
course.

Ciao,
Markus



Re: [dev] lnano[http|smtp] ipv6

2016-09-01 Thread Markus Wichmann
On Thu, Sep 01, 2016 at 10:14:18PM +0200, FRIGN wrote:
> On Thu, 1 Sep 2016 21:53:21 +0200
> Sylvain BERTRAND  wrote:
> 
> Hey Sylvain,
> 
> > Added IPv6 to lnanohttp and lnanosmtp:
> 
> how do you expect anyone to use your software when you ship your own
> "libc" called "ulinux"? Why would I use this piece of software when
> it's unportable and only available for x86 and x86_64 linux?
> 
> Cheers
> 
> FRIGN
> 
> -- 
> FRIGN 
> 

Oh come on, it's all of five minutes' work to compile this software
against any libc you want. And all of an hour's work to replace all the
printf() calls with something reasonable and reduce binary size way
further than this custom libc thing, BTW.

Ciao,
Markus



Re: [dev] [smdev] hotplugging

2016-06-25 Thread Markus Wichmann
On Sat, Jun 25, 2016 at 09:39:48PM +0100, Dimitris Papastamos wrote:
> Try echo `which smdev` > /proc/sys/kernel/hotplug

Erm... you want to add some more layers of evaluation? Why not just
this?

which smdev >/proc/sys/kernel/hotplug

JM2C,
Markus



Re: [dev] libzahl paper

2016-06-14 Thread Markus Wichmann
On Mon, Jun 13, 2016 at 11:32:11PM +0200, Mattias Andrée wrote:
> Proofreading and suggestions is greatly appreciated!
> 

Page 5: "Branches are incredibly cheap on modern CPUs." Not so! I wrote
a variety of CRC32 algorithms to benchmark (which will just measure my
personal CPU, I know, but it's better than guesswork), and had two
different bitwise versions:

for (i = 0; i < 8; i++)
{
c = crc & 1;
crc >>= 1;
if (c)
crc ^= 0xedb88320ul;
}

And:

for (i = 0; i < 8; i++)
{
crc = (crc >> 1) ^ (-(crc & 1) & 0xedb88320ul);
}

The second version had twice the throughput of the first. (Of course
that 4-bytes-at-a-time version had the highest throughput, after that
the times got bigger again, but that's beside the point.) That remained
even when writing the loop in assembly by hand (the compiler refused to
just write this:)

shr eax
jnc 1f
xor eax, edb88320ul
1:

And that even though the second version is longer in assembly. But
eliminating that branch really did increase the throughput immensly.

Although, I don't know what would happen on a different architecture.

Ciao,
Markus



Re: [dev] [lnanosmtp]

2016-06-09 Thread Markus Wichmann
On Thu, Jun 09, 2016 at 10:50:56PM +1100, Sylvain BERTRAND wrote:
> Hi,
> 
> Introducing a new minimal and naive smtp server à la suckless: lnanosmtp
> 
> https://github.com/sylware/lnanosmtp
> https://repo.or.cz/lnanosmtp.git
> 
> cheers,
> 
> -- 
> Sylvain
> 

Dear Lord, it's been a while since I've seen such nice code make so
bafflingly bad design choices. Where to start?

1. The whole ulinux thing smacks a bit of NIH syndrome to me. And of
course, it kisses portability goodbye, but then that wasn't your goal at
all. With only i386 and AMD64 supported, I wonder why this isn't in
assembler.

2. You immediately block all signals on entry. That means:
- SIGINT, SIGQUIT, SIGTSTP, SIGTTOU, SIGTTIN: There is no way to
  control the process from a terminal. You have to get another
  terminal out to kill it.
- SIGSEGV, SIGILL, SIGBUS: Undefined behaviour if your code does
  anything to warrant the sending of those signals.
- SIGCHLD: Zombies and no way of knowing about them. Why don't you
  just ignore it?
- SIGXCPU, SIGXFSZ: No way to gracefully close on reaching ulimits.

And so on, and so forth. And for what? So you can handle signals using
signalfd. That would be good if you actually did that. However, that
only happens if the client never stalls out on you.

3. smtp_line_send() can't handle short writes, because the pointer that
is handed in as second argument to write() is never advanced, nor is the
unwritten part memmove()d to the front, as ridiculous as that would be.

4. Synchronous communication, no forking, no threading --> One client at
a time. So you're using epoll on the same two sockets all the time,
which means you might as well not have bothered.

Still, it could easily be salvaged: Drop all the setup code for the
server socket and make the code read from stdin and write to stdout.
Then this server can be run from inetd, or through any ucspi
implementation. That will also remove the glaring issue that the program
must be run as root and doesn't drop privileges even when it's done
doing privileged things.

5. Exiting at the drop of a hat: Your only error handling is to exit,
unless it was an expected error (usually EINTR). That's the opposite of
PHP, I guess, but that doesn't make it better.

6. You do know that if you used a C library, you'd have access to
strchr(), strcpy(), and the like, right? Because you seem to be having a
jolly good time rewriting those over and over again.

7. What's with the S_IFMT constants? You're binding hard to the syscall
interface, you can use 0666, it's not getting any less portable now.

8. You do know that C has more loop contructs than just the endless one,
right? Because I'm seeing a lot of endless loops that are basically
do-while loops, or counting loops... C has structured programming. Use
it! Please...

9. Oh wait, I see that you have strcpy(), you just don't use it.
Alrighty then.

And that was just what I saw in lnanosmtp.c. And I didn't check the
protocol.

Ciao,
Markus



Re: [dev] [sbase] diff

2016-01-28 Thread Markus Wichmann
On Wed, Jan 27, 2016 at 11:22:55PM +0100, Mattias Andrée wrote:
> Perhaps I should describe how the program works
> (although it is very simple.) The documents are
> compared just like of they were words, but with
> lines rather than characters, and only add and
> remove are valid changes, not substitution. This
> is implemented using dynamic programming. It
> procedure fills in two matrices. One that describes
> how many changes have to be made to get from the
> old document to the new document. In the other it
> is registered changes have to be made. This can be
> extrapolated from the first matrix, but to keep it
> simple it is written to the another matrix.
> For any index-pair (i, j) in the matrices, the
> corresponding element describes the changes to get
> from the i first lines of old document to the j first
> lines of the new document. The next part of the
> program is just print the differences. Any time an
> edit is about to be printed, it is cached, then when
> all directly subsequent edits have been cached, it
> prints the line removals followed by the line
> additions. This is to make the output more readable.
> 

Some comments on this:

First, we allow C99 extensions, right? C99 has not only variadic arrays,
but pointers to them as well, so your matrix could be declared and
allocated as

size_t (*matrix)[a + 2][b + 1] = malloc(sizeof(size_t[a + 2][b + 1]));

Then access array elements as (*matrix)[i][j] and you're done. This
saves you the trouble of allocating the pointer block, or allocating a
single-dimensional array with enough elements and doing the arithmetic
by hand.

Second, wikipedia describes this algorithm to initialize the topmost
line and the leftmost column with zero, not with their indices.

Third, this algorithm needs quadratic space, i.e. on a 32-bit machine,
it is incapable of comparing two 200,000 line files (it would need
40,000,000,000 machine words for that, and that would just die). So
instead I'm going to explain what busybox diff does:

The two files to be compared are loaded into memory, whereby each line
is annotated with its line number (actually, that's a lie, busybox only
saves a hash of the line and really, really hopes, there are no
collisions, but hush). Then both files are sorted by line content first
and line number second. Then a mapping is calculated, that maps each
line of the old file to its corresponding line in the new one, if any.
This is done by merging the two files, i. e. (pseudocode)

memset(map, -1, sizeof map)
new file pointer = first new line
for every old line:
while (*new file pointer < old line)
new file pointer ++
if (*new file pointer == old line)
map[old line number] = new line number

Afterwards the files are reread (to undo any transformation that might
have happened to the lines. E.g. if "ignore whitespace" was requested,
the whitespace was actually filtered out back in step 1) and then
basically the mapping is printed: If the current old line has no
mapping, or maps to a line before the current new line, it was deleted,
if it maps to the current new line it stayed the same, and if it maps to
a new line after the current one, all new lines between the current one
and the mapped one were added.

I can't prove that this algorithm will conclusively always calculate the
longest common subsequence, but as long as the common subsequence
arrived at in this way is at least up there with the longest, the number
of useless changes (where a line was removed and then added verbatim)
should be pretty low, so this would only be a minor problem over all.
But that algorithm only requires the memory to hold both files with line
numbers, and the map.

Comments?

Ciao,
Markus



Re: [dev] [PATCH 1/1] remove useless dup()

2015-07-08 Thread Markus Wichmann
On Wed, Jul 08, 2015 at 12:00:35PM +0200, Roberto E. Vargas Caballero wrote:
 
  We are ignoring return value of dup(), so just remove it.
 
 
 From dup(3):
 
The  dup()  system  call  creates  a copy of the file descriptor oldfd,
using the lowest-numbered unused descriptor for the new descriptor.
 
 

Yes, but can't dup() fail? Shouldn't we at least check or that?

Ciao,
Markus



Re: [dev] [st] ICCCM compatible selection handling

2015-04-12 Thread Markus Wichmann
Sorry, forgot to include my work so far.

Ciao,
Markus
From 96c65781f6d0d7b4f914156f520efe86ce193975 Mon Sep 17 00:00:00 2001
From: Markus Wichmann nullp...@gmx.net
Date: Sat, 11 Apr 2015 21:21:34 +0200
Subject: [PATCH] Implement most ICCCM rules for selection handling.

ICCCM mandates the use of real timestamps to interact with the
selection, to rule out race conditions if the clients are run at
different speeds. I have implemented the low hanging fruit, putting the
timestamps into text selection. Also, ICCCM mandates a check for whether
XSetSelectionOwner() worked. Not sure my version is correct, though.
---
 st.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/st.c b/st.c
index b2bcfe9..18e8542 100644
--- a/st.c
+++ b/st.c
@@ -423,7 +423,7 @@ static void xsettitle(char *);
 static void xresettitle(void);
 static void xsetpointermotion(int);
 static void xseturgency(int);
-static void xsetsel(char *);
+static void xsetsel(char *, Time);
 static void xtermclear(int, int, int, int);
 static void xunloadfont(Font *);
 static void xunloadfonts(void);
@@ -449,7 +449,7 @@ static void selinit(void);
 static void selnormalize(void);
 static inline bool selected(int, int);
 static char *getsel(void);
-static void selcopy(void);
+static void selcopy(Time);
 static void selscroll(int, int);
 static void selsnap(int, int *, int *, int);
 static int x2col(int);
@@ -984,8 +984,8 @@ getsel(void) {
 }
 
 void
-selcopy(void) {
-	xsetsel(getsel());
+selcopy(Time t) {
+	xsetsel(getsel(), t);
 }
 
 void
@@ -997,7 +997,7 @@ selnotify(XEvent *e) {
 	XSelectionEvent *xsev;
 
 	ofs = 0;
-	xsev = (XSelectionEvent *)e;
+	xsev = e-xselection;
 	if (xsev-property == None)
 	return;
 	do {
@@ -1083,6 +1083,9 @@ selrequest(XEvent *e) {
 	xev.selection = xsre-selection;
 	xev.target = xsre-target;
 	xev.time = xsre-time;
+if (xsre-property == None)
+xsre-property = xsre-target;
+
 	/* reject */
 	xev.property = None;
 
@@ -1125,11 +1128,13 @@ selrequest(XEvent *e) {
 }
 
 void
-xsetsel(char *str) {
+xsetsel(char *str, Time t) {
 	free(sel.primary);
 	sel.primary = str;
 
-	XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, CurrentTime);
+	XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
+if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
+selclear(0);
 }
 
 void
@@ -1146,7 +1151,7 @@ brelease(XEvent *e) {
 			selclear(NULL);
 		} else {
 			getbuttoninfo(e);
-			selcopy();
+			selcopy(e-xbutton.time);
 		}
 		sel.mode = 0;
 		tsetdirt(sel.nb.y, sel.ne.y);
-- 
2.1.3



[dev] [st] ICCCM compatible selection handling

2015-04-11 Thread Markus Wichmann
Hi all,

I recently read the ICCCM regarding selection handling and noticed we
are doing it wrong. Basically, we're supposed to provide real timestamps
in all the calls to selection functions and check for success.

Now, when requesting selection ownership, that's easy, because xsetsel()
is only called from selcopy(), and selcopy() is only called from
brelease, so we can just add a Time argument to selcopy() and xsetsel(),
that we then hand to XSetSelectionOwner() and initialize from the time
element of the XButtonEvent that starts the whole process. So, that's
copying covered. What remains is clipcopy(), clippaste() and selpaste():
Those are recipes, meant to be called from the configuration. Now I
wonder whether the best solution would be to keep a global variable for
the current timestamp that's always updated in the event handlers for
event types that carry time information, or whether a better solution
exists.

Use case for this is rather slim: The way it currently stands, if the
user selects text in st and then somewhere else, and st takes longer to
get to XSetSelectionOwner() than the other application, then st takes
the selection although the other application should. That's probably
only possible using network transport. But I still think st should work
under any circumstances, not just most of them.

Ciao,
Markus



Re: [dev] sed breaks utf8 in [ ]

2015-03-30 Thread Markus Wichmann
On Mon, Mar 30, 2015 at 08:50:11AM -0700, Evan Gates wrote:
 The problem is using glibc's regex engine without first calling
 setlocale to ensure a UTF-8 locale. This causes it to remain in the
 C/POSIX locale. This will effect the same problem in all tools that
 use the libc's regex engine (expr, grep, nl, sed). No good clean
 solution comes to mind yet, I'll keep thinking about it. Any ideas?
 

How about simply calling setlocale()? Or was that too simple? If the
user has set a non-UTF-8 locale and then uses UTF-8, that's on them!

 -emg
 



Re: [dev] sed breaks utf8 in [ ]

2015-03-30 Thread Markus Wichmann
On Mon, Mar 30, 2015 at 08:33:48PM +0200, FRIGN wrote:
 On Mon, 30 Mar 2015 19:05:19 +0200
 Markus Wichmann nullp...@gmx.net wrote:
 
  How about simply calling setlocale()? Or was that too simple? If the
  user has set a non-UTF-8 locale and then uses UTF-8, that's on them!
 
 POSIX locales are an insane concept.

How? I heard that assertion before but never found anyone willing to
explain that one more.

The only thing I can think of, is that struct nl_langinfo does have
quite a lot insane parts to it (especially haunting was the member that
described thousands-separation), and that supporting a large repository
of locales would always require dynamic loading, parsing, or a huge lib,
which no-one really wants.

 Unicode has already gone a long
 way to define sane international collation and sorting sequences which
 make sense.

Unfortunately, your oppinion on that will have to contend with all the
other ones on the topic. And stuff like this is largely decided by
majority concencus, even if it is insane.

There is also an ISO standard for formatting dates and times. No-one
prefers it over their local customary one.

 The idea of localized differences has its origin in the
 sick minds of the POSIX-authors.
 

Localized differences do exist in reality.

 sbase and ubase are one part of a protest against all this locale-
 madness.

Hold your horses here. sbase and ubase protest against GNU's
bloatedness, and GNU manages bloatedness very fine on its own. Locales
are but a fraction of GNU's insanity. (Because to these guys, dynamic
linking and loading is AWESOME!)

Also, POSIX over-specifies these things. I once read the POSIX manpage
of cp(1) and it basically defined that it could only be written in
Haskell if you were willing to jump through some large hoops.

 I agree there should be localized date-formats, but everything
 beyond that is mostly insane.

Why? That is inconsistent! There is an ISO standard on date formats, so
why not just use that? Isn't it simplicity in all things you strive for?
Surely you can manage to learn a different date format then, if it makes
the program easier to write!

Now obviously, that was sarcasm. If I recall correctly, computers exist
to serve humans, not the other way around.

 We assume a UTF-8-locale and that's it.

Yes, we do. And it would be awesome if we would just tell the libc about
that as well.

 setlocale is just ugly and imho
 not the solution to this issue.
 

But it is! The issue at hand is that glibc is unwilling to handle UTF-8
in regexs unless it is set to UTF-8 mode. And the only way to do that is
to call setlocale().

I suppose you could drive your religious hatred of setlocale() so far as
to write your own UTF-8 aware regex engine.

Look at it from a pragmatic side: It'll only really affect the people
who use sbase and ubase linked against glibc, anyway. setlocale() in
musl is pretty much a no-op; I don't know if it exists in dietlibc, but
a) dietlibc's a toy, and b) it couldn't have a complete locale support
in that little code; and who uses uclibc these days anyway? Remains
klibc and libc5, which I can't comment on.

The point is, I don't understand your reasoning here: You are faced with
a problem you know the solution of, yet you are unwilling for no good
reason to implement the solution. Other than I don't want to!.

Ciao,
Markus



Re: [dev] wego: a weather app for the terminal written in go

2015-01-14 Thread Markus Wichmann
On Wed, Jan 14, 2015 at 10:42:07PM +0100, Markus Teich wrote:
 Heyho,
 
 since I was tired of fetching lots of unneeded html and js and images just to
 get a weather forecast, I wrote wego[0]. Comments welcome.
 

When I tried to run it, it would just print Malformed response. I
added a line to dump the URL to stderr before that and tried to get it
with wget, and the response I get is 403 Forbidden. What am I doing
wrong?

Ciao,
Markus



Re: [dev] [sbase] [PATCH-UPDATE] Rewrite tr(1) in a sane way

2015-01-10 Thread Markus Wichmann
On Sat, Jan 10, 2015 at 08:51:03PM +0100, FRIGN wrote:
 On Sat, 10 Jan 2015 02:52:09 +0100
 Dmitrij D. Czarkoff czark...@gmail.com wrote:
 
   +#define UPPER A-Z
   +#define LOWER a-z
   +#define PUNCT !\#$%'()*+,-./:;=?@[\\]^_`{|}~
  
  These definitions hugely misrepresent corresponding character classes.
 
 I interpreted the character classes by default for the C locale. What do
 you mean by hugely misrepresenting? They are just fragments to build the
 classes later on.
 

You wanted to be Unicode compatible, right? Because in that case I
expect [:alpha:] to be the class of all characters in General Category L
(that is, Lu, Ll, Lt, Lm, or Lo). That includes a few more characters
than just A-Z and a-z. And I don't see you add any other character to
that class later.

So, what I'm saying is, you can't have it both ways: Either you support
Unicode or not.

Regarding implementation: That is going to be tricky, considering that
the characters fitting the various classes are strewn across the Unicode
code range. And of course, it would routinely use up way more memory by
using code points from further back in the code range, thus using more
of the map.

I really don't see a way to achieve this without including a database of
sorts into tr itself. Because other than that, the only thing available
is the character classification functions from C99 (iswalpha() et al.),
which only provide you with one bit of information: Whether a given
codepoint is in a category... wait, this can work! If we had a variable
iterate from 1 to Unicode maximum and call iswalpha() for every one,
we'd get the set of all alphabetic characters. Can this work for us?

Ciao,
Markus



Re: [dev] [dmenu] [PATCHES 1-5] Changes and cleanup

2014-12-26 Thread Markus Wichmann
On Thu, Dec 25, 2014 at 04:02:35PM +0100, k...@shike2.com wrote:
 I don't use ctags. It's simple, if you use the correct code style you don't
 need aditional tools.
 

ctags tells me the place where all the functions are defined. It also
tells me where all the defines are and where all the structure members
are. It tells me the location of the tag types and the typedefs and so
on. All of that is available to me using a single shell command and a
single button press in vim. OK, that last one was a lie, because the
default button combination for follow tag is C-], which I have to
type as CTRL-ALT GR-9 on Linux and CTRL-+ on Windows. But the point
remains.

How many search commands do you have to memorize? If you want to even
just read the code of another project, maybe even a big one, how many
sed-scripts do you have to run over the existing code base in order to
navigate? Or even programs? Or are you content with only reading the
code you directly control the style of?

Nothing against minimal solutions, I like those. But they have to
actually solve the problem without creating equally big new ones.

Ciao,
Markus



Re: [dev] [dmenu] [PATCHES 1-5] Changes and cleanup

2014-12-26 Thread Markus Wichmann
On Fri, Dec 26, 2014 at 10:24:27AM +0100, FRIGN wrote:
 no matter how big the codebase is, in my opinion, if you need tools like
 that there's something wrong with the code. And I've worked with really
 big codebases (good and bad) in my time.

I'm talking about stuff like musl: I don't want to know that qsort() is
defined in src/stdlib/sort.c. I just want to see the function. And if
you're used to getting that in an instant, manually navigating it is
just tedious.

 You can get bigger than that, but a nice example is the ioquake3-engine,
 which is very modular.
 Modularity in general is what C is about and there's no reason to have
 a very complex problem separated into several smaller problems instead
 of writing one single big monolith you need ctags for to navigate.
 

See above. ctags() is useful even for small and suckless code bases.

 It's no wonder the initial developer of ctags, Ken Arnold, is a die-hard
 Java-proponent, a language we all know is designed to bloat problems up
 unnecessarily.
 

Argumentum ad personam. Great! I'd rather discuss the meritts of ctags
based on the program, please.

Ciao,
Markus



Re: [dev] [dmenu] [PATCHES 1-5] Changes and cleanup

2014-12-24 Thread Markus Wichmann
On Tue, Dec 23, 2014 at 08:42:18AM -0700, Anthony J. Bentley wrote:
 The point of this rule is not visual alignment. Width of the type doesn't
 matter; it is always one tab. The advantage is that you can find the
 declaration of member foo by grepping for ^Ifoo.
 
 Similarly, the function name at beginning of line rule is so you can
 find the bar() function definition by grepping for ^bar(.
 

Who here doesn't use ctags or similar? Because using navigation
techniques that only work if not technically enforced style guidelines
are followed is not really helpful to people who read and write code in
many different projects.

Basing style guidelines on navigation techniques strikes me as odd.
Style is only there to ease reading and understanding of the code.

Ciao,
Markus



Re: [dev] problem report for sbase/cal

2014-12-15 Thread Markus Wichmann
On Mon, Dec 15, 2014 at 11:53:26AM -0500, random...@fastmail.us wrote:
 On Mon, Dec 15, 2014, at 11:47, Greg Reagle wrote:
  January 2015 is supposed to start on a Thursday.  
 
 January 2014 started on a Wednesday - maybe it's worth investigating
 whether cal -3 that spans two years isn't using the correct year for
 some of the months.
 

Found it!
From 2476d80e7f4854382943368299b4e06a0c53db8c Mon Sep 17 00:00:00 2001
From: Markus Wichmann nullp...@gmx.net
Date: Mon, 15 Dec 2014 20:42:12 +0100
Subject: [PATCH] Fix problem with multi month display spanning a year.

---
 cal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cal.c b/cal.c
index 8b5244c..dca2313 100644
--- a/cal.c
+++ b/cal.c
@@ -59,7 +59,7 @@ drawcal(int year, int month, int day, int ncols, int nmons, int fday)
 yoff = year + moff / 12;
 
 ndays = mdays[cur] + ((cur == 1)  isleap(yoff));
-day1 = dayofweek(year, cur, 1, fday);
+day1 = dayofweek(yoff, cur, 1, fday);
 
 for (d = 0; d  7; d++) {
 	if ((r || d = day1)  count[i] = ndays)
-- 
2.1.3



Re: [dev] GCC situation

2014-11-24 Thread Markus Wichmann
On Mon, Nov 24, 2014 at 11:01:13AM +0100, koneu wrote:
 On November 24, 2014 6:35:51 AM CET, Markus Wichmann nullp...@gmx.net wrote:
 that this asumption removes most overflow checking code.
 
 This behaviour is a pro, not a con, of GCC. If you rely on undefined 
 behaviour to
 check for ... well ... undefined behaviour there is a compiler flag to enable 
 it.
 

Buried in the manpage somewhere. But sure, it's there. Somewhere below
the architecture options for the VAX, and somewhere in the middle of all
the other optimizers. And that's if you even remember what to search
for.

 something, but... well, the problem is, most code out there is not
 strictly conforming to the C standard.
 
 Fix the code instead of breaking the compiler.
 

Assume I'm compiling something like sabotage or LFS. I have about 20
packages to build to get a remotely usable system. And in that situation
compiling with -O3 will result in some broken binaries. Somewhere. Why?
Because in the thousands of code lines somewhere there is a bug. I know
I won't look for it. It is unlikely I'll even be able to identify the
malfunctioning component. All I'll know is that something doesn't work,
and if it is something in those early components it's likely that just
something breaks and then the whole system doesn't work. Great!

OTOH I could just only use suckless software and write everything that's
missing myself. But you'll have to forgive me for wanting to connect to
my WiFi sometime before next year (because I've read wpa-supplicant, and
I don't like it, but I lack the expertise to rewrite it sucklessly
myself).

 By now, the only thing that really bugs me is that GCC's optimizers
 make
 code undebuggable.
 
 -O0 and -g are your best friends.
 
 

Yes, it's the -O0 that bothers me there. I'd like to debug the code that
actually runs in production.

One big problem is that at -O3 almost every value is optimized out.
Now, all that means is that no register or memory location with that
exact variable exists, but from the code I know that clearly _some_
value based on the variables and parameters has to be saved somewhere.
But gdb offers no way to display those. I know that with optimization
control flow may be very different from the flow I wrote into the source
code, but at least let me see my values!

But no, so I'll have to put in debug outputs, which of course changes
the program, and kills the timing, and if I'm debugging a race condition
(in the sucky code I have to write at work) that's exactly what I don't
need. Oh, and I'll have to remember to remove them.

Ciao,
Markus



Re: [dev] [surf] web videos idea

2014-11-23 Thread Markus Wichmann
On Sat, Nov 22, 2014 at 12:39:07AM +, Henrique Lengler wrote:
 Hi,
 
 I have a video player (mplayer) installed on my computer with a lot of
 codecs, so it is able to play a lot of videos formats.
 I don't like the idea of installing some plugins like gstreamer to play
 vide on on the browser if have a video player already working.
 
 This is the Unix philosophy: Write programs that do one thing and do 
 it well. Write programs to WORK TOGETHER.
 
 So I just thought, is there a way to combine both, my web browser that will
 care only about display the html stuff, and leave the video work to my 
 video player? This would be awesome.
 

There is a firefox plugin called mozplugger that does pretty much that.
It'll select a program to display external content with based on its own
config file, termcap, xdg-mime and alternatives[1], then launch that
program and embed its window into firefox.

[1] See, that's what happens when there is no standard. mozplugger has
now 4 different ways of selecting an application, so if the choice it
takes is the wrong one, good luck in figuring out how to change it.

 
 Regards,

Ciao,
Markus



Re: [dev] GCC situation

2014-11-23 Thread Markus Wichmann
On Sun, Nov 23, 2014 at 10:20:44PM +, Henrique Lengler wrote:
 Hi,
 
 What is the situation of GCC, is it bloated?

Holy shit, yes! Ever tried to compile it?

And in the end, GCC has a lot of optimizers that make pedantic
asumptions about the code they compile. For instance, if i is of signed
integer type, i + 1 can never be smaller than i. Yeah, right. Nevermind
that this asumption removes most overflow checking code.

I know that this case is undefined or implementation-defined or
something, but... well, the problem is, most code out there is not
strictly conforming to the C standard. For instance, did you know that
converting a floating point value into an integer type where the integer
part can not be represented causes undefined behavior? I didn't until
recently. So converting an FP value that might be negative to an
unsigned type is undefined, but converting an FP value that is definitly
in range to a signed integer type and that to an unsigned integer type
is completely defined. What?

u = fp;

is undefined, but

u = (int)fp;

is not?

 I'm asking because I don't find too much on suckless site about it 
 I don't have experience in any other compiler.
 

Well, there's always clang. It's completely written in C++, but is way
better organized than GCC and it is contained entirely in a lib, so it
can be easily integrated into IDEs and other programs. If you need a C
parser, have a look at libclang.

 I also found someday TCC (Tiny C compiler - bellard.org/tcc/) 
 And it looks cool.
 

Yeah, but good luck compiling anything with it that requires GCC
extensions.

See, GCC is bloated, but there is also a reason for that: It is written
to be as commonly usable as possible. Why do you think you need (at last
count) three different multi-precision libraries to compile GCC? Because
in the general case you cannot assume that the native types will be big
enough to hold all the values of the target types.

 The site shows the speed of it:
 Compiler  Time(s) lines/secondMBytes/second
 TinyCC 0.9.22 2.27859000  29.6
 GCC 3.2 -O0   20.098000   3.4
 
 What they don't talk about is the speed of execution, wich I think
 is faster with gcc. But if I were create a suckless gcc I would 
 probably fork TCC.
  
 So what do you think, GCC is ok? Or no?
 

Oh, heavens, no! But it is a necessary evil. IIRC the linux kernel can
only partially be compiled with clang (and tinycc doesn't stand a lick
of a chance), so there is a necessity for gcc.

Regarding execution time: Yes, with GCC that will be much better than
with tinycc, because the former has way more and way more aggressive
optimizers.

By now, the only thing that really bugs me is that GCC's optimizers make
code undebuggable. Or is that GDB's fault.

 Regards,

Ciao,
Markus



Re: [dev] why avoid install?

2014-11-20 Thread Markus Wichmann
On Wed, Nov 19, 2014 at 11:12:43AM -0500, random...@fastmail.us wrote:
 On Wed, Nov 19, 2014, at 09:55, Dimitris Papastamos wrote:
  Regarding your question on cp -f then the answer is not quite.
  
  cp -f will try to unlink the destination if it fails to open it for
  whatever
  reason.
 
 And if the target is running and writing to a running binary is a
 problem, opening it will fail with [ETXTBSY], meaning it will be
 unlinked. You can argue about whether that is the purpose or something
 else (permission errors within a directory you own) is the purpose, but
 it will certainly solve that problem.
 

Not always. One thing that reliably gets on people's nerves here is
shared libraries. And those aren't protected with that ETXTBSY thing.

The reason is that the MAP_DENYWRITE flag became the irrecoverable
source of a DoS attack and had to be removed from the syscall. It can
still be used in the kernel, which is why overwriting a running binary
will fail, but it can't be used in userspace (or rather, is ignored), so
opening a shared library that's in use for writing and truncating is
possible. That means that cp -f on a used shared library will destroy
all programs using it.

Also, if you unlink the target file, that means that the file system
gets into the state where the target file does not exist. If you then
start the copy loop, the file system gets into the state where the file
does exist, but has the wrong mode, wrong owner and probably wrong
content. If anything happens to go wrong during that, the target file
will be corrupted. If anything is looking for the target file in the
meantime, they'll see it in the wrong state, which may cause surprise.
After all, every single one of my programs failing at once would
certainly surprise me!

The correct solution is to copy the file to a temporary name in the same
directory (or something else that guarentees it being on the same device
as the target file), then change its mode and owner, and then move it
into place. If anything goes wrong, just delete the temporary file. That
way, you can even update /lib/libc.so with a shell script. But that only
works for musl, of course. For most other libcs, you have to figure out
in what order to update the different library files without breaking
programs. That, or create a compiled program that does all the moving in
one invocation, because a half-updated libc will probably mean that
nothing can run until it's fixed.

Ciao,
Markus



Re: [dev] [sbase] style

2014-11-19 Thread Markus Wichmann
On Wed, Nov 19, 2014 at 07:58:28PM +0100, k...@shike2.com wrote:
 For long time I followed the rule of kernel style of not using typedef
 ever, but I changed it to the rule of using typedef only with structs
 and capital letter, and I can say that this last is far better; You
 get more readable function definitions:
 
   funcion(struct Term *term1, struct Term *term2)
 
 becomes
 
   function(Term *term1, Term *term2)
 
 
 Regards,

How's that more readable? I do agree that function pointer typedefs make
stuff easier to read, because when I read the definition

void (*signal(int, void(*)(int)))(int);

I start to think that I may have stumbled into a LISP source code by
accident. Whereas

typedef void (*sighandler)(int);
sighandler signal(int, sighandler);

But regarding the typedefs for structs: C has only a few namespace
features, so lets not dismantle the probably most used one, alright?
struct stat can be something different from stat()! I like that
namespace thing so much I even use it in C++ (declaring objects with
class foo object;). Not that I use C++ all that often, but, you know,
professional obligations and shit.

In your above example in the first definition it is clear that Term is a
struct to everyone. All I know from the second definition is that I have
to look up what a Term is, because for all I can see it might be
typedef'd to a pointer type, or a union, or an array of whatever. True,
that might not be necessary all that often, but with your first line it
becomes completely unnecessary.

Oh, and typedefing struct pointers is just evil. For instance, when you
declare

struct foo;
typedef struct foo *PST_FOO;
function(const PST_FOO);

then what have you qualified as const there? (BTW, my workplace wants me
to prefix struct types with st or ST, but doesn't want me to use tag
names. That's a stupid thing if I ever heard one, but oh well, we deal
with the hands we're played, I guess.)

Ciao,
Markus



Re: [dev] [st] will global-less changes be wanted upstream?

2014-08-17 Thread Markus Wichmann
On Sun, Aug 17, 2014 at 08:56:45AM +0200, Christoph Lohmann wrote:
 You  are  wrong.  The  approach  to shuffle everything into object‐liked
 structures is what makes software development ill. Stop it now.

It would be hard for that statement to be more wrong, because what makes
software development sick is not a drive towards organization. Anyone
who ever tried to make zsnes run on a 64-bit machine should know that
much: They never use anything but globals there.

Although shuffling all the globals into a global super-object won't
really help with that, it can help to actually analyze the data flow and
make better optimizations.

What makes software development sick is lasagna code that never get's
simplified until runtime. So not only are you developing in a very high
stack of rather fragile applications, that whole stack also has to run
later on. (An example of having a high level of abstraction done right:
Haskell. You won't know what exactly the compiler will make of your
code, but it gets compiled to assembly and is not required to run your
code).

Otherwise, there's the bad habit of software companies to set really
stupid coding rules (like only use structured programming. Ever. No
exceptions.) that fail to address the real problems (like 1000 line
functions and code organization that would tear the souls of everyone
with even the slightest background in software engineering asunder.)

 The rea‐
 son  why  st  is keeping this global is because there is no intention to
 reuse the st object in your web page or on your iPad.
 

No-one wanted to do that. But keep up your straw-man burning over there!

 Enforcing  such  »structure« keeps you from going the fast lane in effi‐
 cient code.
 

Benchmarks or it didn't happen.

 The discussion on how terminals should evolve has happened on this mail‐
 inglist a while ago. No, it’s not reusing them everywhere and  extending
 the escape codes.
  

That is already possible in a relatively painless way in st. So again,
you're burning a straw man here.

 Your  narcissistic  Apple  user.  Come  down  from your white horse.

Ascribing personality disorders to people is meaningless without a
certified psychology education. Also, slightly ironic you should say
that.

 You
 should contribute to st instead of forking it to an irrelevant  platform
 like Mac OS X.
 

You don't need it, therefore it's irrelevant. Classy.

 Who’s  still  using  Apple software in 2014 should be considered a fool.
 iPhones are open to everyone, Mac OS X is full of  security  holes,  the
 hardware  is  built  by slaves in the third world.

None of which is relevant to the task at hand.

 And if you try to use
 the job joker, learn about virtualisation. In the  times  of  quad  core
 CPUs  and  Gbit  network  you can run multiple instances of Linux every‐
 where.
 

Because when I think of running a terminal emulator, I think VMWare.
Especially when trying to change stuff in the host.

  
 Sincerely,
 
 Christoph Lohmann
 
 

Bye,
Markus



Re: [dev] network protocol packing

2014-07-01 Thread Markus Wichmann
On Mon, Jun 30, 2014 at 08:54:52PM +0200, Markus Teich wrote:
 Heyho,
 
 since I did not find any suckless project regarding this issue, I would like 
 to
 ask you guys for some feedback:
 
 
 unsigned char *msg;
 size_t msg_size;
 struct foo *msg_data;
 struct bar *msg_signature;
 
 msg_size = sizeof(unsigned char)// op
   + sizeof(struct foo)// data
   + sizeof(struct bar)// signature
 msg = malloc(msg_size);
 
 *msg = MSG_OP_SIGNED_DATA;
 
 msg_data = (struct foo *)(msg + 1);
 msg_data-field0 = bla;
 msg_data-field1 = blub;
 
 msg_signature = (struct bar *)(msg_data + 1);
 create_signature(msg, msg_signature);
 
 sendmsg(msg);
 
 free(msg);
 
 
 I feel it is pretty good already compared to other message packing I've seen,
 but do you know a way to make it suck even less?
 
 --Markus
 

The alignment issue was already mentioned (there's nothing like your
program working at home and then suddenly dying of SIGBUS in the field
to hammer that point home), but unless all your data is single bytes,
you also have byte order problems. Solving these requires some suck.

There are basically only two ways to resolve these problems: Either copy
the data into the buffer and flip it later, or flip it on the way. I'd
personally go with flipping on the way:

unsigned char *p = msg;
*p++ = MSG_OP_SIGNED_DATA;
align32(p, msg);
write_be32(p, bla);
write_be16(p, blub);
/* and so on */

Then implement them like:

void write_be32(unsigned char **p, uint32_t i)
{
*(*p)++ = i  24;
*(*p)++ = i  16;
*(*p)++ = i   8;
*(*p)++ = i;
}

Then you are even independent of the host processor's byte order.

HTH,
Markus



Re: [dev] [st] [PATCH] Explicit cast in CEIL macro

2014-06-24 Thread Markus Wichmann
On Tue, Jun 24, 2014 at 07:32:10PM +0200, FRIGN wrote:
 We are dealing with floats with at most 2 decimal places. I propose we
 just go for
 
 CEIL(x) ((int)(x) + ((x)  0  (int)(x) != (x)))
 

Well, if we know that much already then the easiest to read version
would be:

#define CEIL(x) ((int)(x = 0? x + .99 : x))

And done! That should returns 3 when anything between 2.01 and 3.01 is
entered (excluding the upper boundary).

Alternatively:

#define INSIGNIFICANT 1e-2 /* values and differences below this don't matter */
#define CEIL(x) ((int)(x = 0? x + 1 - INSIGNIFICANT : x))

That's easier to adjust.

Ciao,
Markus



Re: [dev] Lightweight, non-bloated, fast image viewer?

2014-06-14 Thread Markus Wichmann
Hi all,

Let us analyze the problem at hand: To display an image on screen, we
need to

- interpret the image file
- display the content on screen

So, having one program that reads some standardized input and displays
it on screen, while another program converts any given image file to
that standardized format may be more UNIX-like. But maybe a file is not
the right representation for that standardized format. So maybe the
converter would need to be a library instead of a program.

So yes, I argue we should rather rewrite imlib, that is, try to
implement imlib's interface in a suckless way. Unless that is
impossible, then the rewrite feh idea is the only one left.

Ciao,
Markus



Re: [dev] [PATCH] [ubase] Simplify login

2014-06-03 Thread Markus Wichmann
On Mon, Jun 02, 2014 at 06:41:45PM +0200, FRIGN wrote:
 Well, I prefer /etc/passwd, given it gives a false feeling of security
 using the shadow-file.
 In reality, it's a solution for a very unimportant issue.
 If your password is strong, having the hashes won't help any attacker.
 On the other hand, having a weak password, the shadow-file doesn't save
 you from a breach.
 

Well, it won't save you, but delay it significantly! Testing a password
with login takes 5 seconds, testing a password with the hash at hand
takes less than a microsecond.

But I concur this issue is pretty unimportant. Most security breaches
these days occur due to faulty software allowing arbitrary code
execution from network input. Or some fault/feature in the operating
system allowing circumvention of the login prompt. (If you give me
physical access to a Linux box, I'll get access to it.) So knowing a
password isn't necessary any more.

 Cheers
 
 FRIGN
 

Ciao,
Markus



Re: [dev] C coded cross-platform youtube video viewer

2014-05-17 Thread Markus Wichmann
On Sat, May 17, 2014 at 04:14:21PM +0200, Teodoro Santoni wrote:
 You're speaking like you're using some OS in which, during runtime,
 the code of that software written with a scripting language
 is passed through a dispatcher that recalls namespace sessions 
 and, then, to a limited number of scripting interpreters loaded
 and daemonised in memory when available for executing code,
 without seeing an interpreter for every process spawned
 by every scripted program, which is what happens on my uglybuntu
 with programs written with scripting languages.
 

First, please don't top post.

Second, that is a total non sequitur. Because I was talking about disc
space and you are talking about processes. I said, I want _one_
perl/python/php (ok, bad example) on my box instead of one for every
package that might use it. That way, it's on my box only once. It's
configured only once and it's downloaded only once.

Of course it's run for every program that needs it whenever it's needed.
And of course the parsing overhead sucks. However, at that point we're
usually talking about stuff that might be beyond my ability to
reimplement in a compiled language. And is _definitely_ beyond my
ability to do so on the spot.

 Although it's true that it's a waste of data downloading the
 whole damn language everytime you need the ultimate geek
 hipsterish idea put down on iPad during a pause spent taking a
 sh*t...

Slow down there: If you deem the software you use of that low quality,
why use it at all? Unless of course, you're unable or unwilling to
reimplement that software. That other people whipped up inside of five
minutes. You know, those people talking about how low-productive C is?
Maybe they're on to something here.

OK, in the end I usually find that five minute programs that do in their
language what I can't do in C even after hours typically do so by using
the language's standard library, which is far more extensive (read:
bloated) than C's, so I have to actually implement stuff that was
already done for the script kiddie.

 But an interpreter is a parser and some modules
 dynamically loaded, most of the time with scripting langs, so
 dunno, when deploying a package nobody impedes a distro community
 to deploy a JIT compiler that loads some of the modules during
 compilation.

Last I checked, all the major interpreters are already in all the major
distributions, so what's your point here? Don't make packages with
dependencies? In that case, why use package managers at all? *glance to
Windows* Oh, right...

 Or saying f*ck the whole script idea and rewrite
 the whole thing in C/Go/Pascal/Ada/whatever you like to compile.
 

Yes, yes, real hackers write in C. And if you can't write it in C, you
write it in FORTRAN. And if that's not possible you write it in
assembly. And if that's not possible you solder it.

Jokes aside, the whole compiled vs. scripted thing never made sense to
me. Not in the almost religious ways many view this issue (not just here
but on other forums, too. Only, for those the pendulum usually swings
too far in the other direction). To me, that debate just misses the
point. It is clear that scripted languages have their pros and cons over
compiled ones and what to use is to be decided on a case-by-case basis.
Especially, compiled languages are not inherently better than scripted
languages. Both can be memory hogs and both can be beautiful, it depends
on the skill of the programmer.

I don't use C religiously, I use it because I know it well and I usually
want readability and traceability, Speed being a tangential concern at
best. But if I need a ton of string handling, for instance, C would not
be my first choice. At least not if heightened security is necessary.

Ciao,
Markus



Re: [dev] C coded cross-platform youtube video viewer

2014-05-15 Thread Markus Wichmann
On Thu, May 15, 2014 at 04:08:59PM +0200, Sylvain BERTRAND wrote:
 Hi,
 
 Unfortunately, libquvi on gentoo expects a system
 installed lua (with additional modules).
 
 I don't want this high level script language as a system
 dependency. I would prefer lua being packaged internally into
 libquvi. Coze I would like to quit gentoo one day and have my own
 suckless-ish distro, then better do the work now. I don't want
 system wide installed
 perl/python/ruby/php/lua/guile/javascript... (holy m
 f*!), I would rather try to have applications package their
 high level script language and don't try to f*** it up our
 system throat. (and tell the script kiddies: no, you FOO
 script language is not installed, and won't be. Then package your
 bloody f** kludge with your app)
 

Why would you do this? It's bloody idiotic, if you think about it. It
would be like having all C programs ship their own libc. Have you seen
how big perl is? Do you really want to have two perl installations just
because two different programs use it?

That, in my opinion was always the major benefit of Linux over Windows:
On Linux you have system wide package managers. That means each software
package can be as small as possible and only pull external dependencies.
On Windows, no such thing exists. If a program needs a lib, it has to
ship that lib. If you have 50 programs using that lib, on Linux you have
that lib once, on Windows you have it 50 times. Which way is better? And
scripting languages are not fundamentally different!

Ciao,
Markus



Re: [dev] [GENERAL] License manifest

2014-05-13 Thread Markus Wichmann
On Mon, May 12, 2014 at 07:28:48PM -0400, Lee Fallat wrote:
[GPL quoted in full]

Could you please take the time to shorten your quotes to the part you
actually want to reply to?

 I've come to adopt the NoLicenseLicense, for sole reason of
 demonstrating to people that many of us code for the sake of fun.
 
 NoLicenseLicense.txt
 There is no license attached to this software, enjoy.
 

Oh goodie, this means no usage for me, then. After all, no licence means
the default state applies, which is All rights reserved by the author.
There is no need to actually claim the copyright or write that sentence
out, by the way.

 ...Yes this is a joke. If you are interested in these types of
 Licenses, also check out WTFPL- you'll enjoy it!
 

The WTFPL on the other hand is, barring relicensing in the future,
equivalent to placing your work in the public domain.

To me, licensing comes down to more or less three choices:

A) Do I think this may be profitable to someone else in the future? If
so, do I want a piece of that? If so: Use something copyleft with the
option of commercial relicensing in the future. GPL will do in a pinch.

B) Just something I scribbled up in my free time with no budget or
effort behind it? Or genuinely important code for others to see (highly
unlikely)? If so: Public Domain or whatever your local law calls it.

C) Looking to sell it for profit later? Commercial license it is!

At the moment, my local projects all fall into category B.

JM2C,
Markus



Re: [dev] [GENERAL] License manifest

2014-05-13 Thread Markus Wichmann
On Mon, May 12, 2014 at 01:46:02PM -0600, Anthony J. Bentley wrote:
 Example: LibreCAD, a fork of QCad, which had been relicensed by the
 authoring company under the GPLv2. LibreCAD wanted to support AutoCAD's
 DWG file format. Unluckily for them, LibreDWG (a FSF project) is licensed
 GPLv3+, and the FSF refused to relicense. The GPL made the code so free
 they couldn't use it.
 
 Example: the SMB implementations in Samba (GPLv3+) and the Linux kernel
 (GPLv2), which literally cannot share even a single line of code. It's
 really fascinating that people seem to love the idea of a license that is
 so easily made incompatible with _itself_.
 

Amazing! Version incompatibilities in GPL! Well, it is an FSF product
(seriously, after Glibc and gcc both having version incompatibilities
and interdependencies, and binutils being in that mix, too, is it any
wonder more and more people grow tired of GNU-ware?)



Re: [dev][project] soap - a simple xdg-open replacement

2014-05-04 Thread Markus Wichmann
On Sun, May 04, 2014 at 03:58:39PM +0100, Chris Down wrote:
 My seconds use is perhaps a little unclear, sorry. I meant the shell
 quoting [method used in soap] does not handle existing instances [of
 single quotes] inside single quotes.
 

Did you even read the code? Of course it does: Every existing single
quote within the string argument is replaced by a single quote, followed
by a backslash, followed by two single quotes. No way for that to turn
out to be wrong as far as I can see!

Ciao,
Markus



Re: [dev] [st] [PATCH] Fix techo handling of control and multibyte characters.

2014-05-02 Thread Markus Wichmann
On Fri, Apr 25, 2014 at 04:42:09PM +0200, Roberto E. Vargas Caballero wrote:
 The problem is Wall change from one system to another (this is something
 OpenBSD users know with strcpy calls...), and it doesn't force how to
 remove the warning, so at the end I think style is not really improved
 with Wall (and guys, some of the warning are really, really stupid).
 

That's one of the problems with C and gcc: Too many messages fall into
the same category of warning. gcc warns you about a comparison between
signed and unsigned variables even in places where that can't bite you,
like in

int s;
unsigned u;
/* ... */
if (s  0 || s  u)

In this case the s  u is only evaluated if s's value is representable
in unsigned. gcc will warn anyway.

At the same time implicit declaration of function X is just a warning,
too. And it can crash your program not to declare a function. If a
function is supposed to return a pointer, and you don't declare it at
the call site, even if you cast the result to remove the assignment
makes pointer from integer without cast warning, and you are on x86-64,
and the pointer returned is bigger than INT_MAX (e.g. on the stack),
then the result's top 32 bits will get ignored, the lower 32 bits will
get a sign extension and your program will segfault while trying to
access kernel space. Which is very annoying when the program in question
is login, which you yourself bothed the day before. This may have
happened to me.

And then there are the bizarre cases, like variable X may not be
initialized: That is an incredibly helpful warning that is only
produced when gcc is optimizing (I guess it's a byproduct of the flow
analysis, which is part of the optimizer). However, when developing I
usually have the optimizer off so I can debug. And this warning is
removed in newer versions of gcc entirely. But not the command line
option for it. Nice! I'm switching to clang!

 I moved to Linux kernel style some years ago, but I am beginning to break
 some rules, basically the typedef rule. I accept typedef of struct always
 that the new type begins with upper case.
 

I never typedef my structs. At least for private works. Professionally I
have to abide by the company rules (which are the kind of pussy-footing
rules you'd expect from a bunch of engineers trying to do programming,
like don't use the ternary operator, it's hard to understand or don't
return from anywhere but the final statement of a function that are
supposed to make the source code easier to read but completely miss that
they still allow 100-line structs and 3000-line functions), but in
private I think C desperately needs namespaces so I'm not going to
destroy the only namespaces C has.

Sorry this became quite a rant and a lot off topic.

Ciao,
Markus



Re: [dev][ubase] Implement switch_root

2014-04-18 Thread Markus Wichmann
On Wed, Apr 16, 2014 at 11:10:23PM +0100, Dimitris Papastamos wrote:
 On Thu, Apr 17, 2014 at 12:07:46AM +0200, Szabolcs Nagy wrote:
  so implementing that tool is a one-liner in c
  
  so it is easy to add if it's missing from ubase
 
 We already have pivot_root in ubase.  Markus is basically asking
 why we implemented switch_root in C instead of in sh (as demonstrated
 in his e-mail).
 

Nope, that wasn't my question. Rather, I'd like to know why the OP wants
to use switch_root in his initrd instead of pivot_root, as the latter is
easier to use and already included in ubase. And it doesn't depend on
the filesystem type of the initrd.

Also, the shell script I posted was a mockup. It probably doesn't work
like that as drop-in, because for one it calls chroot and then does
stuff after that. I just didn't want to write all that in C as that
would have been way longer. I didn't deem it necessary for the purposes
of demonstration.

Ciao,
Markus



  1   2   >