Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for fcntl() flags definition #14751

Merged
merged 1 commit into from
Jun 28, 2021
Merged

Conversation

tymoteuszblochmobica
Copy link
Contributor

Summary of changes

Disable override errno erro value in mbed_retarget.h
Disable setting own values of flags for fcntl() function if they are defined

Impact of changes

No impact

Migration actions required

Not needed

Documentation

None


Pull request type

[x] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[x] No Tests required for this change (E.g docs only update)
[] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers

@pan-
@ ATmobica


@ciarmcom ciarmcom added the release-type: patch Indentifies a PR as containing just a patch label Jun 8, 2021
@ciarmcom
Copy link
Member

ciarmcom commented Jun 8, 2021

@tymoteuszblochmobica, thank you for your changes.
@pan- @ARMmbed/mbed-os-maintainers please review.

@@ -63,17 +64,36 @@ typedef unsigned int gid_t; ///< Group ID
/* Flags for open() and fcntl(GETFL/SETFL)
* At present, fcntl only supports reading and writing O_NONBLOCK
*/
#ifndef O_RDONLY
Copy link
Contributor

Choose a reason for hiding this comment

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

I am trying to find a reasoning we had it previously as undef. Didn't we have fcntl in one of the toolchains (I bet it was IAR back then) ? If this is tested with both toolchains we support, it should be good.

Avoiding redefinition errors (either this PR or as it was would result with the same effect), however the previous one ignored the values set by elsewhere and forcing our retarget value (undef + set). This PR is changing it to (ifndef then set).

@kjbracey-arm Would you know if the proposed way is acceptable ?

Copy link
Contributor

@kjbracey kjbracey Jun 9, 2021

Choose a reason for hiding this comment

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

I think ifndef is better for errno because it maintains binary compatibility with the C library. There will be some C library functions setting errno (but not many in this embedded environment - usually it's the porting layer), and they would be using the values from the toolchain header.

I'm not sure what the original justification for the forced undefine was. Consistency of values between toolchains?

Comment says this, but it's not totally illuminating:

* Note also that ARMCC errno.h defines some symbol values differently from
* the GCC_ARM/IAR/standard POSIX definitions. The definitions guard against
* this and future changes by changing the symbol definition as shown below.

The implication being that the values below were matching GNU+IAR?

Switching values now (for ARMC only?) would potentially introduce binary compatibility issues with other binary blobs. But I doubt that would matter. The sort of things using binary blobs don't use these values - Wifi drivers would be using NSAPI error codes.

So I don't have a problem with this change, conceptually.

The main issue is that if doing ifdef, then this file really must make sure it has included the toolchain file that would define these to get the same result every time.

Otherwise

#include "mbed_retarget.h"

and

#include <sys/something>
#include "mbed_retarget.h"

might give you two different values in different compilation units. (Maybe that was the point of the undefine?)

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for commenting on this Kevin.

Most of the values below match GCC's newlib values but not all of them; some are different. It is what motivated the change. For example, EADDRINUSE is equal to 112 on Mbed OS but is set to 98 in newlib.

This has caused us issues when implementing a POSIX compatible socket layer on top of Mbed OS as the values between the system header and mbed header were not matching.

The inclusion of errno.h and fcntl.h should cover us as defines are reused from here.

The last difficulty is to find if a value defined in this file doesn't collide with another errno value defined in the system header. I think we can use a constexpr and static_assert (maybe just in the cpp file to not impact build time) to validates that these errno values are distinct:

constexpr bool validate_errno_values() { 
    constexpr int values[] { 
        EPERM,
        ENOENT,
        ESRCH
        /* other errno values ... */
    };

    constexpr int count = sizeof(values) / sizeof(values[0]);

    for (int i = 0; i < count; ++i) { 
        for (int j = i + 1; j < count; ++j) { 
            if (i == j) { 
                continue;
            }
            if (values[i] == values[j]) { 
                return false;
            }
        }
    }

    return true;
}

static_assert(validate_errno_values() == true, "Not all errno values are unique");

@tymoteuszblochmobica Have you validated the change with ARMCC ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Cute, but you don't need to go that far. Just make a switch statement listing each value. That will give a compile error for duplicates.

(EAGAIN and EWOULDBLOCK are allowed to be duplicates, others aren't, I believe).

Copy link
Member

Choose a reason for hiding this comment

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

Aha, I completely forgot about the switch statement 🤦 . That should work too and be faster.

@ciarmcom ciarmcom added the stale Stale Pull Request label Jun 15, 2021
@ciarmcom
Copy link
Member

This pull request has automatically been marked as stale because it has had no recent activity. @pan-, please complete review of the changes to move the PR forward. Thank you for your contributions.

@tymoteuszblochmobica
Copy link
Contributor Author

I added switch to verify duplicates at compile time.
It detects 11 collisions so changed that values.

@ciarmcom ciarmcom added stale Stale Pull Request and removed stale Stale Pull Request labels Jun 15, 2021
#define O_RDONLY 0 ///< Open for reading
#endif
Copy link
Member

Choose a reason for hiding this comment

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

Which one was redefined ? That could be terrible if some are equals to others.

Copy link
Contributor

Choose a reason for hiding this comment

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

Mmm, it is worth sanity checking you haven't made a mismatched set.

The same switch trick for all the O_ defines is basically sufficient. You might want to also add

static_assert((O_ACCMODE & (O_NONBLOCK|O_APPEND|O_CREAT|O_TRUNC|O_EXCL|O_BINARY)) == 0, "O_ACCMODE clash")

case EOWNERDEAD:
break;
case ENOTRECOVERABLE:
break;
Copy link
Member

Choose a reason for hiding this comment

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

I think we should check for equality too as pointed out by Kevin.

can you add static asserts for them ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Eh? What did I suggest? The switch is testing for equality. (A comment explaining that would be a good idea...)

Not sure the breaks are needed - wouldn't expect any compiler to complain about "fallthrough" for directly adjacent cases.

Copy link
Member

Choose a reason for hiding this comment

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

I should have precise that I was speaking about EAGAIN and EWOULDBLOCK. It is not mandatory to have them equal thought.
In such case we need a second switch case where EAGAIN is replaced with EWOULDBLOCK.

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe you can simply do:

#if EAGAIN != EWOULDBLOCK
case EAGAIN:
#endif
case EWOULDBLOCK: 

POSIX says the defines have to be usable in #if directives.

@tymoteuszblochmobica
Copy link
Contributor Author

tymoteuszblochmobica commented Jun 23, 2021

Definition conflicts

First time defined
in retarget.h left
Already defined in toolchain errno.h right

ERESTART 85 ELIBSCN 85
EUCLEAN 117 EHOSTDOWN 117
ENOTNAM 118 EHOSTUNREACH 118
ENAVAIL 119 EINPROGRESS 119
EISNAM 120 EALREADY 120
EREMOTEIO 121 EDESTADDRREQ 121
EMEDIUMTYPE 124 ESOCKTNOSUPPORT 124
ENOKEY 126 ENETRESET 126
EKEYEXPIRED 127 EISCONN 127
EKEYREVOKED 128 ENOTCONN 128
EKEYREJECTED 129 ETOOMANYREFS 129

@0xc0170
Copy link
Contributor

0xc0170 commented Jun 24, 2021

@tymoteuszblochmobica I don't follow the last comment.

All comments were resolved, the switch function works and this is ready for integration or there is still some redefinition errors?

pan-
pan- previously approved these changes Jun 24, 2021
@mergify mergify bot added needs: CI and removed needs: review labels Jun 24, 2021
@pan-
Copy link
Member

pan- commented Jun 24, 2021

@0xc0170 I think @tymoteuszblochmobica just mention the define values that were changed in this PR.

@0xc0170
Copy link
Contributor

0xc0170 commented Jun 24, 2021

CI started

@mergify mergify bot added needs: work and removed needs: CI labels Jun 24, 2021
@mbed-ci
Copy link

mbed-ci commented Jun 24, 2021

Jenkins CI Test : ❌ FAILED

Build Number: 1 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_cmake-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-GCC_ARM
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM
jenkins-ci/mbed-os-ci_cmake-example-GCC_ARM
jenkins-ci/mbed-os-ci_build-example-GCC_ARM

@0xc0170
Copy link
Contributor

0xc0170 commented Jun 24, 2021

Please review failures for Gcc, they are related

@mbed-ci
Copy link

mbed-ci commented Jun 24, 2021

Jenkins CI Test : ❌ FAILED

Build Number: 2 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-GCC_ARM
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-GCC_ARM
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM
jenkins-ci/mbed-os-ci_build-example-GCC_ARM

@0xc0170
Copy link
Contributor

0xc0170 commented Jun 25, 2021

@tymoteuszblochmobica have you tried locally, any of example to build with Gcc Arm? The second run confirmed the failures.

@tymoteuszblochmobica
Copy link
Contributor Author

I tried locally with mbed-os and added main. There was no errors.
I will try example for aws and fix remaining definition conflicts

Disable setting own values of flags for fcntl() function if they are defined
@mbed-ci
Copy link

mbed-ci commented Jun 25, 2021

Jenkins CI Test : ❌ FAILED

Build Number: 3 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_greentea-test

@mbed-ci
Copy link

mbed-ci commented Jun 25, 2021

Jenkins CI Test : ✔️ SUCCESS

Build Number: 4 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_greentea-test ✔️

@jeromecoutant
Copy link
Collaborator

Hi
Since this PR, IAR build is not building any more...

[ERROR]
  #include <fcntl.h>
                    ^
"C:\github\mbed-os\platform\include\platform\mbed_retarget.h",41  Fatal error[Pe1696]: cannot open source file "fcntl.h"

#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#undef EILSEQ
#endif
#ifndef EILSEQ
Copy link
Collaborator

Choose a reason for hiding this comment

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

Got issue with this one only for IAR...
Seems EILSEQ is wrongly defined?

$ grep -r EILSEQ *
arm/inc/c/errno.h: #define EILSEQ 36

@mbedmain mbedmain removed release-type: patch Indentifies a PR as containing just a patch Release-pending labels Jul 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants