Skip to content

Conversation

@PiotrZierhoffer
Copy link
Contributor

Based on musl implementation.

From IEEE Std 1003.1-2017:
The strerror() function shall map the error number in errnum to a
locale-dependent error message string and shall return a pointer to it.

This implementation does not take locales information into account, as
this concept is not present in Zephyr.

Signed-off-by: Piotr Zierhoffer [email protected]

@zephyrbot
Copy link

zephyrbot commented May 31, 2019

Found the following issues, please fix and resubmit:

License issues

In most cases you do not need to do anything here, especially if the files
reported below are going into ext/ and if license was approved for inclusion
into ext/ already. Fix any missing license/copyright issues. The license
exception if a JFYI for the maintainers and can be overriden when merging the
pull request.

  • lib/libc/minimal/source/string/__strerror.h is not apache-2.0 licensed: mit
  • lib/libc/minimal/source/string/strerror.c is not apache-2.0 licensed: mit

@nashif
Copy link
Member

nashif commented May 31, 2019

can you provide some context on why you are adding all those libc functions?

Based on musl implementation.

From IEEE Std 1003.1-2017:
The strerror() function shall map the error number in errnum to a
locale-dependent error message string and shall return a pointer to it.

This implementation does not take locales information into account, as
this concept is not present in Zephyr.

Signed-off-by: Piotr Zierhoffer <[email protected]>
@PiotrZierhoffer
Copy link
Contributor Author

can you provide some context on why you are adding all those libc functions?

This is required for integration with civetweb.

We will, most likely, submit some time related functions, float parsing and sscanf as well.

I used code based on musl, as it is already present in Zephyr.

@pfalcon
Copy link
Contributor

pfalcon commented May 31, 2019

can you provide some context on why you are adding all those libc functions?

+1

This is required for integration with civetweb.

Unfortunately, the idea that you can build POSIX applications (like civetweb) with non-existent libc (like minlibc) is flawed. You can't, because (full) C library is unalienable part of POSIX. Please just use newlib. Whoever won't follow that advice, will effectively build a copy of newlib. Likely, in "frankenstein style"copy, pulling parts from different libc's around. All that someone will then have to maintain. And so far, we can't maintain well even integration with more or less integral libc like newlib.

I used code based on musl, as it is already present in Zephyr.

Good to know, because pulling in non-Apache2 licenced code into Zephyr usually means going thru Zephyr TSC discussion (even if it's MIT/BSD license which everyone knows compatible with Apache2).

@aescolar aescolar added the area: C Library C Standard Library label Jun 3, 2019
@PiotrZierhoffer
Copy link
Contributor Author

We tried to use Newlib, but it doesn't work with the POSIX APIs in Zephyr - it doesn't compile due to a large number of issues like symbol redefinitions etc.

Since Zephyr's documentation (https://github.com/zephyrproject-rtos/zephyr/blob/master/doc/guides/c_library.rst) states that you can either use Newlib or extend minimal-libc, we went for the latter.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 3, 2019

We tried to use Newlib, but it doesn't work with the POSIX APIs in Zephyr

As explained above, the opposite is also true - POSIX API doesn't (can't) work without newlib (or it's not POSIX API, but very limited and holey thing).

it doesn't compile due to a large number of issues like symbol redefinitions etc.

Well, https://github.com/zephyrproject-rtos/zephyr/tree/master/tests/posix are 2 examples where "POSIX API" works well with newlib.

However, if you formulate the situation as "if you step aside from whatever POSIX API samples are included in Zephyr, all the hell breaks loose", that would pinpoint the situation well. That happens because people who initially implemented parts of POSIX API didn't think how it all would fit together into consistent a POSIX system. Well, that will need to be thought out sooner or later.

One possible "alternative" would be:

  1. Ignore the situation.
  2. Make another box within Zephyr and keep adding adhoc things based on particular and peculiar needs to it.

But p.2 is exactly how "POSIX API" was developed so far, so it would be too optimistic to think that any different results will come out from p.2.

Since Zephyr's documentation (https://github.com/zephyrproject-rtos/zephyr/blob/master/doc/guides/c_library.rst) states that you can either use Newlib or extend minimal-libc, we went for the latter.

IMHO, it's a bug in the docs, it doesn't take into consideration that POSIX subsystem has special needs and requirements.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 4, 2019

Summing up discussion at the networking forum (from my PoV):

  1. Between choices of improving minimal libc vs adding adhoc workarounds to "civitweb sample", improving minimal libc is definitively the preferred choice.
  2. But then "minimal libc" should be, well, minimal, and this implementation adds a bunch of strings to ROM. Having stuff like E(EDOM, "EDOM") would be a good choice for minimal libc IMHO.
  3. In the context of civetweb porting, this is still more like a workaround, instead of using (and improving) newlib.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 4, 2019

instead of using (and improving) newlib.

It was said that there're issues with, like symbol conflicts trying to use POSIX_API and newlib, but I don't believe I saw any bugreport. Is there any?

@pfalcon
Copy link
Contributor

pfalcon commented Jun 4, 2019

libc: add strerror() to minimal libc

I'd say, better title would be "libc: minimal: add strerror()".

@rakons
Copy link
Contributor

rakons commented Jun 5, 2019

@pfalcon
I cannot agree only about the 2nd point of your list. This would add strings into ROM only if you use strerror function. And it should be optimized out even if you do disable garbage collection in linker - as all that strerror requires is placed in a separate file. So as far as I know - it would be removed if nothing references to any element inside this file.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 5, 2019

I cannot agree only about the 2nd point of your list. This would add strings into ROM only if you use strerror function.

Yeah, and if you use it, it adds a bunch of bloat, whereas a function from "minimal libc" could take care to be minimal, as suggested above.

Copy link
Contributor

@rakons rakons left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sometimes really missing strerror functionality. The problem is that Zephyr is complex enough that it takes time to judge witch errno.h file is really used, especially if trying to quickly debug someones other code.

What I really would love to see here is a configuration between:

  1. Return descriptive error message (like here)
  2. Return error mnemonic - so EINVAL would return "EINVAL"
  3. Disable - return an empty string.


#include <errno.h>

#define E(a, b) ((unsigned char)a),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not cast to unsigned char here - you are removing a compiler warning if any code does not fit 8 bit (I get that it should be not an issue, but it seems not to make any sense to remove this warning if it happens).

E(EALREADY, "Operation already in progress")
E(EINPROGRESS, "Operation in progress")

E(0, "No error information")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 - operation finished successfully?
Moreover - the current implementation of strerror function requires this one to be the last one. It has to be commented or the implementation should be changed.

{
int i;

for (i = 0; errid[i] && errid[i] != e; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not:

for (i=0; i<ARRAY_SIZE(errid); i++) {
   if (errid[i] == e) {
      return errmsg[i];
   }
}
return "No error description found";

This way no special mark inside the errid has to be implemented.

for (i = 0; errid[i] && errid[i] != e; i++) {
/* intentionally left blank */
}
return (char *)errmsg[i];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot agree about removing "const" modifier like here. It is very risky. I would prefer to have a non-standard strerror implementation that returns const char* instead of such a dirty trick.

@rakons
Copy link
Contributor

rakons commented Jun 5, 2019

@pfalcon

"minimal libc" could take care to be minimal, as suggested above.

I agree. This is why I have added a proposal of the configurable strerror in my review above.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 5, 2019

This is why I have added a proposal of the configurable strerror in my review above.

Sorry, but even I would consider that scope creep (a typical problem with Zephyr reviews). This patch adds strerror() implementation to minimal libc, whereas there was none before. It should be judged based on that, not on what else it might have been. That's why I personally don't add -1 here, even though I think that the approach taken by this patch is wrong on several accounts. Even if that's true (and it's just my opinion), in the end this patch does add proper and useful functionality which wasn't available before.

Someone needing additional things from strerror() mostly likely will need to follow up with further patches on top of this one.

@rakons
Copy link
Contributor

rakons commented Jun 5, 2019

Why creep? Just change:

#define E(a, b) b,

To:

#if STRERROR_FULL
#define E(a, b) b,
#else
#define E(a, b) #a,
#endif

@PiotrZierhoffer
Copy link
Contributor Author

The discussion went far away from the original problem, but as this PR is not about to be accepted, I'll close it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: C Library C Standard Library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants