Re: critique of gnulib

2019-09-01 Thread Jonas 'Sortie' Termansen
Hi Bruno & Paul,

Thanks for your interest in my notes on gnulib. I appreciate your desire
to discuss them. Please excuse some of the resources that I'll link
below for overreacting in jest ("screaming in horror", "usual gnulib
infection"), they weren’t really meant for upstream consumption, but
they do refer to true struggles that I've had to go through. I
understand and appreciate that you and I have different goals, but I
think we do have some common ground. I'll give you the context of my
notes below.

My goal is to make a good and clean  POSIX-like operating system, and to
enable other people to do so as well because healthy competition is good.

I have contributed to gnulib in the past. Although my main interest is
my operating systems project and I only work on ports as needed. This
year I am dedicating my time to my game development project, so I don't
have the resources to do OS work these days. Please excuse me if my
information is out of date.

I rather enjoy my operating systems work on Sortix, though, because I've
accomplished something extraordinary: A self-hosting POSIX-like system
made from scratch with key ports of third party software (about 75% of
ports compiles natively, so I rely on cross-compilation). What really
surprised me pleasantly was that I did not have the same backwards
compatibility concerns of a GNU/Linux system. By doing things in a
simple way without historical mistakes, my project got a good baseline
quality.

This really accomplishes the best qualities of a free software platform,
because all the code and ports are integrated and are easy to modify
(you can 'cd /src && make sysmerge' out of the box and the system is
updated to the new sources of everything). I'm free to compete with
other POSIX-like systems by making better implementations of the
standard interfaces and in turn encouraging other systems to improve.
Meanwhile I have encountered technical debt in other projects that I
port, and I sometimes fix those issues and contribute fixes upstream,
improving the health of the free software ecosystem.

My method for porting software is to cross-compile the software to my OS
(see ). Sometimes I have
to fix some build system bugs. Then I fix the compile errors and
warnings, if any. That may require implementing some new features in my
OS. Finally it compiles and I run it. It might not work or crash, and I
fix those bugs too. Finally I package up the thing and I might send a
patch to the upstream if I like the software and it's easy and the
upstream seems receptive.

I find BSD software can be easier to port than GNU software, even though
it often does not even attempt to be portable. I can easily deal with it
because it simply fails to compile and I can easily figure out what I
need to provide, or just change the software to use a different feature.
Porting GNU software can be much harder to port because of complexities
in layers like autoconf or gnulib that cause problems that didn't need
to be there.

A big problem with gnulib is that good new operating systems are
unreasonably burdened because of the mistakes of buggy operating systems
(which may have been fixed long ago). A good example is e.g.
cross-compilation. For instance, an old Unix might not have had a broken
fork() system call or something. When cross-compiling, gnulib might be
pessimistic and default to assuming the system call is broken, which may
be handled with a poor or inefficient fallback, disabling functionality
at runtime, or a compile time error. There is usually a whitelist of
systems without the problem and an environment variable to inject the
true answer. That means that it's harder to compete with a new unknown
operating system because I must set the environment variable, while
other operating systems just work, including the buggy one. That means
my good operating system is paying for the complexity caused by a bad
operating system. I'd rather the extra work of cross-compiling is moved
to the buggy operating systems.

Cross-compilation is inherently a bit more difficult when the host
system is buggy, so a more reasonable design would could be to assume
the best about unknown operating systems, and to only invoke the
workarounds for known buggy systems (and forcing them to set the
environment variable instead of me). That means the buggy operating
systems pay the cost instead of the good ones (making it harder for new
systems). Making cross-compilation nice helps the development of new
operating systems, and not just for established things like glibc/musl.

As you saw in my gnulib wiki page, I literally inject 120 environment
variables to make gnulib assume the very best about my operating system.
I'd rather be confronted with bugs up front than have then be secretly
hidden by a portability layer, or be told that it assumed the worst
about my unknown operating system so I have to teach it internals about
my OS. I'd love if it was able to disable 

Re: Fix weird _SC_OPEN_MAX usage

2014-08-07 Thread Jonas 'Sortie' Termansen
On 08/07/2014 06:59 PM, Paul Eggert wrote:
 That shouldn't be a problem, since the modules in question all depend on
 the getdtablesize module, which should supply the getdtablesize function
 on platforms that lack it.

Ah. I missed that.

Some background: I'm porting these modules (as found in bison, gettext,
m4, and such) to a new operating system. It has the standard
sysconf(_SC_OPEN_MAX) interface and it doesn't have the older and
non-standard getdtablesize() interface.

But the gnulib getdtablesize only has implementations for Windows and
Cygwin. This causes an undefined reference error when the spawn faction
modules tries to use it.

We can fix this:

1) Add a getdtablesize () replacement based on sysconf (_SC_OPEN_MAX).
2) Replace __sysconf (_SC_OPEN_MAX) with getdtablesize ().

The modules shouldn't use the __sysconf name as it is in the reserved
namespace and actually likely to collide with a system header. It should
just call getdtablesize directly.

I'm proposing something like this:

lib/getdtablesize.c
+#elif HAVE_SYSCONF
+
+int
+getdtablesize (void)
+{
+  return sysconf (_SC_OPEN_MAX);
+}
+
+#endif

lib/spawn_faction_addfoo.c
-#if !_LIBC
-# define __sysconf(open_max) getdtablesize ()
-#endif
 ...
-  int maxfd = __sysconf (_SC_OPEN_MAX);
+  int maxfd = getdtablesize ();

Thanks,

Jonas



Fix weird _SC_OPEN_MAX usage

2014-08-06 Thread Jonas 'Sortie' Termansen
Hi,

The files

lib/spawn_faction_addopen.c
lib/spawn_faction_addclose.c
lib/spawn_faction_adddup2.c

contains this unusual pattern:

#if !_LIBC
# define __sysconf(open_max) getdtablesize ()
#endif
...
int maxfd = __sysconf (_SC_OPEN_MAX);

This is non-portable to new systems that doesn't have the non-standard
getdtablesize() function, but implements the standard sysconf value. The
desirable pattern would be to just use the real standard sysconf call
directly:

int maxfd = sysconf (_SC_OPEN_MAX);

Or, if it is desirable to support systems with no sysconf() and just
getdtablesize(), then:

#ifdef _SC_OPEN_MAX
int maxfd = sysconf (_SC_OPEN_MAX);
#else
int maxfd = getdtablesize ();
#endif

Jonas 'Sortie' Termansen



[PATCH] getpass: conditionalize variable declarations

2014-08-06 Thread Jonas 'Sortie' Termansen
This fixes unused variable warnings. Additionally, the struct termios may
not be defined on systems without tcsetattr and no termios header.
---
 lib/getpass.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/getpass.c b/lib/getpass.c
index 43d0d59..18dc0b7 100644
--- a/lib/getpass.c
+++ b/lib/getpass.c
@@ -85,7 +85,9 @@ getpass (const char *prompt)
 {
   FILE *tty;
   FILE *in, *out;
+# if HAVE_TCGETATTR
   struct termios s, t;
+# endif
   bool tty_changed = false;
   static char *buf;
   static size_t bufsize;
-- 
2.0.0




Re: parse-duration.c - TIME_MAX conflict

2014-06-17 Thread Jonas 'Sortie' Termansen
On 06/15/2014 06:53 PM, Bruce Korb wrote:
 I still think that implementations need an unambiguously distinct
 name space.  *_MAX is too greedy.

It actually turns out that POSIX has reserved the _MIN and _MAX
suffixes for limits.h as stated in POSIX 2008 `2.2.2 The Name Space'.
It has a nice table with all the POSIX namespace rules that you can
view online:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_02



Re: parse-duration.c - TIME_MAX conflict

2014-06-15 Thread Jonas 'Sortie' Termansen
On 06/15/2014 06:53 PM, Bruce Korb wrote:
 Actually, it occurs to me that the result still uses TIME_MAX and, if
 not guarded,
 still conflicts with glibc's claim to a new name.  I still think that
 implementations
 need an unambiguously distinct name space.  *_MAX is too greedy.

Ah, don't misunderstand my short remark in my original email. I'm not
associated with glibc or GNU (beside a few odd contributions here and
there) and as far as I know they don't have or plan to have a TIME_MAX
constant. I wrote my own custom operating system with a custom libc and
ported software using gnulib to it. My addition of a TIME_MAX constant
(as well as limit, print and scan macros for all sys/types.h typedefs)
is a non-standard extension to my libc and it is properly hidden behind
feature macros - and shouldn't even conflict with the parse-duration.c
file in the fist place.

What I meant is that such a constant would be fairly useful (in code
such as this, for instance) and other libcs/standards could potentially
add one as well (likely not), I recognize its potential to collide with
some existing code.

Regardless that was just a side remark and my issue here wasn't the use
of TIME_MAX, but rather the hard-coded limit. You can continue to use
the identifier TIME_MAX if you wish, it's a bug if any of my standard
headers declares such a constant when adhering to POSIX.

The patch looks good to me as well. :-)

Jonas



Re: parse-duration.c - TIME_MAX 2038 unpreparedness

2014-06-11 Thread Jonas 'Sortie' Termansen
Hi Bruce,

On 06/11/2014 02:38 AM, Bruce Korb wrote:
 OK, I promise to fix it within the next 24 years.

It will be a while before any 2038 issues happen, yeah.  Though, some
operating systems vendors today are making guarantees that their current
installations will be able to last past that point.

 In truth, since this is a _duration_, it really constrains the
 result to be within 68 years.

Durations longer than 68 years would indeed be unusual.  (Though can
this code be abused to parse absolute dates?)  Either way, this is a
silly artificial restriction: The code takes great care not to overflow
beyond the limit, but the limit isn't always right.  Jim points out the
TYPE_MAXIMUM () macro from lib/intprops.h, it looks reliable and ideal
for this purpose.  (It also avoids the problem yours had where
right-shifts on negative signed integers can be either arithmetic or
logical.)

The TIME_MAX macro is currently just used twice and both uses are in the
scale_n_add function. It would probably be sufficient to just discard
the macro and instead use this declaration in scale_n_add:

  time_t time_max = TYPE_MAXIMUM (time_t);

That should be clean, simple and reliable - and make everyone happy. :-)

Jonas



parse-duration.c - TIME_MAX 2038 unpreparedness

2014-06-01 Thread Jonas 'Sortie' Termansen
Hi,

I noticed that lib/parse-duration.c does:

#define TIME_MAX 0x7FFF

This is naturally entirely unacceptable as the 2038 bug ((time_t)
INT32_MAX) is coming up soon and most operating systems are 64-bit
time_t capable by now. This should be rewritten as something involving
sizeof(time_t) in a safe and portable manner.

It would probably be best to not use a define named TIME_MAX, as that
name would be ideal if a standard header wanted to expose the domain of
time_t for use in cases like this (indeed, this came up because I am
adding a TIME_MAX constant to my libc).

Jonas 'Sortie' Termansen