DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
...
Instead user code must explicitly call set_errno(errcode). This a a violation of the accepted usage of the POSIX errno variable.
Task-Specific Globals in the FLAT and PROTECTED builds
A special case is the use of TLS to support task-specific (vs. thread specific) global data. Task-specific differs from thread-specific in that all of the threads in the task group share the global data, however, each task group has its own set of task-specific global variables. This feature permits a high-fidelity emulation of process global data as you would see in the KERNEL build where each process has its own copy of all global variables.
Task-specific data is implemented by keeping such globals in the stack of the main thread. A single main thread is always present and, hence, provides user-accessible, per-task storage. Task-specific data is accessed via TLS: The TLS data of each thread includes a reference to the main thread's task-specific globals.
Re-Entrant getopt()
One use of task-specific data is for global variables used by the getopt() function. getopt() is an important C library function used by applications for parsing of task command line parameters. It is, however, not re-entrant due to the use of global variables: optarg, opterr, optind, and optopt. There are several, non-standard implementations for a re-entrant version of called getopt_r(), however, these are all wildly different and do not conform to any standard. Non-standard interfaces are not desirable in NuttX.
In the FLAT and PROTECTED builds, this non-reentrant limitation poses a problem. Unlike the KERNEL build mode, there is one instance of of the globals optarg, opterr, optind, and optopt shared across all task groups. It is not a problem in the KERNEL build where there is a separate instance of the globals in each process address space.
Using task-specific data, however, it is possible to make getopt() thread-safe. This amounts to keeping the getopt() globals in the main thread's TLS so that there is an individual copy for each thread. That would keep both the standard form of the getopt() interfaces as well as making getopt() full re-entrant with respect to task groups.
TLS-Based errno
The current solution has moved the errno storage location out of the protected TCB memory and into the unprotected application thread's stack memory. Then it can be accessed with the appropriate TLS (Thread Local Storage) interfaces.
...
In retrospect, this is not such a good idea. It is not a good idea because the I/O streams are not unique per-thread; they are common across all threads within a task group: That includes main thread of the group and all child pthreads whose parent, grandparent, of great-grandparent is the main thread. They all share the same I/O stream array. As a result, I/O streams must be one per task-group.
This works now because the I/O stream array is a part of the internal OS group structure which is one per task group. While it would be nice to get the I/O stream around out of the OS, TLS is probably not the right solution to do that.
Re-Entrant getopt()
getopt() is an important C library function used by applications for parsing of task command line parameters. It is, however, not re-entrant due to the use of global variables: optarg, opterr, optind, and optopt. There are several, non-standard implementations for a re-entrant version of called getopt_r(), however, these are all wildly different and do not conform to any standard. Non-standard interfaces are not desirable in NuttX.
In the FLAT and PROTECTED builds, this non-reentrant limitation poses a problem. Unlike the protected mode, there is one instance of of the globals optarg, opterr, optind, and optopt shared across all tasks. It is not such a problem in the KERNEL build where there is a separate instance of the globals in each process address space.
...
.
Code References
Things to look at:
...