I stopped trying to follow the newlib guide from the wiki because it's very dated. (I hope to update it eventually, but I'm nowhere near there yet). I'm using the latest release of newlib, 4.4.0, and linking it against userspace software (not my kernel).
I compiled newlib (and not libgloss) using the configure script in the newlib directory (not the one in the source root). I did not do anything to "port" it to my operating system, I just asked it to build a generic m68k-elf. This got me what I had been trying to get the source code to do---produce a libc.a that only needs to be linked against those 18 missing functions to work. Then I linked this against your standard printf("hello world"), actually implemented the system calls it wanted, and it works.
Now I'd like to use fopen(). I already had a working open() system call before I started porting newlib. The problem is that posix only specifies the value of the flags argument in terms of named constants, so what numeric values is fopen() going to pass to my open()? I haven't told it what the value of those constants should be. All the documentation I can find on the topic only explains how to write a stub that will work when there is no open(). I am not sure what headers I should be editing, or options that need to be passed to the configure script.
As an aside that might just be the answer to my question, Advanced Programming in the Unix Environment mentions that O_RDONLY, O_WRONLY and O_RDWR are conventionally 0, 1 and 2. Does newlib just use basic functionality where the value of constants happens to be the same across all major platforms for legacy compatibility?
How do I define constants posix expects in newlib?
Re: How do I define constants posix expects in newlib?
POSIX doesn't specify the numbers because they can be different in different OSs. In other words, you just choose the numbers for your OS. I guess you already have chosen them since you have a working open() syscall. What you need is a header file which defines the values both for your kernel (for the syscall) and for userspace (newlib). The standard name for this header is fcntl.hlambduh wrote: ↑Wed Jun 26, 2024 12:15 pmNow I'd like to use fopen(). I already had a working open() system call before I started porting newlib. The problem is that posix only specifies the value of the flags argument in terms of named constants, so what numeric values is fopen() going to pass to my open()?
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Re: How do I define constants posix expects in newlib?
I understand that, what I'm struggling with is how to configure newlib to use *my* fcntl.h, because newlib provides its own fcntl.h.
Re: How do I define constants posix expects in newlib?
I have no experience with newlib, sorry. I guess there 'should' be a way to do it as I see it's architecture-specific in Linux and a symlink even in OpenBSD, but running under an OS isn't really newlib's purpose, so I don't know.
What about if you compiled your kernel with newlib's fcntl.h to make the open() flags the same? Provided it doesn't create any conflicts, of course. If it does, you could generate a header for the kernel based on the newlib fcntl.h.
What about if you compiled your kernel with newlib's fcntl.h to make the open() flags the same? Provided it doesn't create any conflicts, of course. If it does, you could generate a header for the kernel based on the newlib fcntl.h.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Re: How do I define constants posix expects in newlib?
Should my operating system be providing headers to the libc source when I compile it, like that are outside the libc source tree? I've dug into the source code a little, and newlib itself is #include-ing headers with angle brackets. I wonder if the intention is that I provide my own fcntl.h in $sysroot/usr/include when newlib is compiled. I guess the next step is to see if that works and if my own headers remain intact after I make install.
I have given some thought to just accepting the values that newlib wants to use. I'm not opposed to it, but I want to understand how it's chosen the values it has so that I don't accidentally make it use different constants later. The fcntl.h in the newlib source is just #include <sys/fcntl.h>, which in turn is just #include <sys/_default_fcntl.h>, which has the actual header. It's not clear from the source code what it's meant to be compatible with. I haven't been able to find any other fcntl.h in the source, but I suspect it might be in libgloss.
I have given some thought to just accepting the values that newlib wants to use. I'm not opposed to it, but I want to understand how it's chosen the values it has so that I don't accidentally make it use different constants later. The fcntl.h in the newlib source is just #include <sys/fcntl.h>, which in turn is just #include <sys/_default_fcntl.h>, which has the actual header. It's not clear from the source code what it's meant to be compatible with. I haven't been able to find any other fcntl.h in the source, but I suspect it might be in libgloss.
Re: How do I define constants posix expects in newlib?
The inclusion of sys/fcntl.h is essentially the same as OpenBSD, just with a #include instead of a symlink.
That _default looks like a sign that it's meant to be replaceable, though I don't know newlib's procedure for replacing it. Some of these procedures are simple, some are complex for no other reason than no-one ever sat down and figured out a simple way to do it. And sometimes, complex procedures are immitated without reason, only that the people immitating them didn't understand why they existed and just assumed they are the proper way. All this is to say that I'd try to find the proper way to replace fcntl.h in newlib, but if you don't find it, don't worry; there might be no good reason to be found. lol And even when there is a reason, trying to do things correctly or well is often making things harder for yourself in what is already a very hard hobby. I got nothing done for years because I wanted to do everything right before I knew how to do it wrong! lol
Should you be providing constants to newlib? Perhaps. I recall early Linux provided constants to glibc; constants glibc didn't provide because they depended on the kernel. (Once upon a time, glibc was portable! Or tried to be; the GNU folk weren't very bright.) Could you mess up newlib with bad constants? Not if those constants are only going to end up in your kernel. So the question becomes, if newlib makes use of those constants besides sending them to your kernel, what could they possibly conflict with? Finding out might be worthwhile, though it's another area where you could be trying too hard. And how could you accidentally make it use different constants later? There's a case to be made here for always compiling your kernel and libc together, or at least making a test suite to ensure they always work together.
That _default looks like a sign that it's meant to be replaceable, though I don't know newlib's procedure for replacing it. Some of these procedures are simple, some are complex for no other reason than no-one ever sat down and figured out a simple way to do it. And sometimes, complex procedures are immitated without reason, only that the people immitating them didn't understand why they existed and just assumed they are the proper way. All this is to say that I'd try to find the proper way to replace fcntl.h in newlib, but if you don't find it, don't worry; there might be no good reason to be found. lol And even when there is a reason, trying to do things correctly or well is often making things harder for yourself in what is already a very hard hobby. I got nothing done for years because I wanted to do everything right before I knew how to do it wrong! lol
Should you be providing constants to newlib? Perhaps. I recall early Linux provided constants to glibc; constants glibc didn't provide because they depended on the kernel. (Once upon a time, glibc was portable! Or tried to be; the GNU folk weren't very bright.) Could you mess up newlib with bad constants? Not if those constants are only going to end up in your kernel. So the question becomes, if newlib makes use of those constants besides sending them to your kernel, what could they possibly conflict with? Finding out might be worthwhile, though it's another area where you could be trying too hard. And how could you accidentally make it use different constants later? There's a case to be made here for always compiling your kernel and libc together, or at least making a test suite to ensure they always work together.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Re: How do I define constants posix expects in newlib?
Oh gotcha, that's what you were saying in your last post, I understand.
Hm, yeah, this is really helpful advice right now. I think this is just a skill that I need to work on.lol And even when there is a reason, trying to do things correctly or well is often making things harder for yourself in what is already a very hard hobby. I got nothing done for years because I wanted to do everything right before I knew how to do it wrong! lol
Oh, I just use the same header when I compile the kernel. This makes a lot more sense after working through OS Specific Toolchain. I can build the libc first, and then just use the same header that it provides in my kernel, even if I don't want to link against it.Finding out might be worthwhile, though it's another area where you could be trying too hard. And how could you accidentally make it use different constants later? There's a case to be made here for always compiling your kernel and libc together, or at least making a test suite to ensure they always work together.