4 ms·
I thought I found a bug
- userbinator 2y agoI was a bit disappointed that the article didn't go into the system calls themselves, since AFAIK those have always supported interleaved reads and writes with no problems even on early Unices. E.g. POSIX has this: https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html https://pubs.opengroup.org/onlinepubs/9699919799/functions/w... After a write() to a regular file has successfully returned: Any successful read() from each byte position in the file that was modified by that write shall return the data specified by the write() for that position until such byte positions are again modified.
- PeterWhittaker 2y agoPerhaps because the article is specifically about the buffered f*() calls in stdio, and not the system calls? Though, as I offer that thought, the divergence between C and the system calls is definitely curious.
- mystified5016 2y agoI get a real kick out of the different ways people pluralize Unixen. Unices is a good one
- anonymousiam 2y agoWhile reading this, I realized that I have a copy of the elusive usr/group Standard that the author mentions. I just pulled it off an image of my early DOS hard drive (before I migrated to Linux in 1991). I should probably post it somewhere. # ls -altr total 540 -rw-r--r-- 1 root root 22606 Apr 12 1990 NOTES -rw-r--r-- 1 root root 172645 Apr 12 1990 LIB -rw-r--r-- 1 root root 102349 Apr 12 1990 APP -rw-r--r-- 1 root root 224037 Apr 12 1990 C
- codetrotter 2y ago> I should probably post it somewhere. Upload it to the Internet Archive! :D https://help.archive.org/help/uploading-a-basic-guide/ https://help.archive.org/help/uploading-a-basic-guide/
- anonymousiam 2y agoThanks. It looks like the document itself is still copyrighted. The files can be uploaded, so I will.
- xelxebar 2y ago> before I migrated to Linux in 1991 What a mic drop. That must have been a fun ride from then until now! Would love to hear some of your battle stories.
- jsjohnst 2y agoMy first Linux machine was in 1993, what would you like to know? Pre-1.0 Kernels were an adventure that’s for sure.
- icedchai 2y agoMy first Linux box ran 0.99.10. I was running SLS, which installed off of a dozen or so floppies. I eventually moved to Slackware a year or so later.
- xenophonf 2y agoI remember downloading and installing one of the MCC Interim releases in 1993? 1994? before switching to Slackware. Early *BSD and Linux were certainly an adventure back then. I don't miss it.
- anonymousiam 2y agoSLS was also my first distro. I also played with Yggdrasil Linux (bootable CD) for a while, because at the time, nobody could afford a hard drive with as much capacity as a CD-ROM. Those early Linux distros borrowed a lot from SunOS (Solaris 1), so it was easy to adapt between work/home.
- purplesyringa 2y agoI must be missing something. The article lists three libcs (Open Watcom, Microsoft Visual C++ 6.0, IBM C/C++ 3.6 for Windows) from the good old times. Does the emulator link to Open Watcom, i.e., does it emulate DOS on machines about as old as DOS itself? What's the point here?
- AntiRush 2y agoThe article is about compiling and running a program inside the emulator. When the unexpected behavior occurred, the author assumed it was a bug in the emulator.
- purplesyringa 2y agoSo if it's not a bug in the emulator, then it's a bug in COMMAND.COM? I don't think that's the case, surely it couldn't have been missed by Microsoft at the time. The article goes on to talk about fread/fwrite calls, but COMMAND.COM was written in assembly, I'm pretty sure it didn't link to any libc, and certainly not to Open Watcom -- why would MS use it instead of their own library?
- grodriguez100 2y agoIt is not a bug. The article explains that this is the expected behaviour.
- purplesyringa 2y agoWhat is expected behavior? Surely `echo AB> foo.txt; echo CD>> foo.txt` producing `ABBC` is either a bug in COMMAND.COM, the emulator, or something else? That can't be correct.
- deleted 2y ago[deleted]
- justin_ 2y ago
- raldi 2y agoI'm having trouble following whether the problem occurs with any append or only when it's two consecutive commands like this.
- cryptonector 2y agoIn the stdio implementations that don't support free intermixing of reads and writes the issue typically is that there is only one buffer for both reading and writing. You have to reset the buffer in order to switch from reading to writing or vice-versa, else you will have a dirty, non-empty buffer that does not correspond. The functions `fflush()`, `fseek()`, `rewind()`, and `fsetpos()` happen to clear the buffer, which is why you have to use them before switching from reading to writing or vice-versa! Without an indicator in `struct FILE` of whether the last operation was a read or a write, the stdio implementation has no way to detect the problem and correct the situation by automatically flushing and resetting the buffer, say. An alternative would be to have two buffers, naturally. But you can see how a pre-update version could be trivially made to support update modes without adding a second buffer or automatic buffer flushing. And that's almost certainly what happened when update mode was added. My guess is someone got bitten by that and then the maintainer decided to just document the problem rather than fix it, probably because by then fixing the problem was hard.
- fweimer 2y agoHistorically, before mandatory locking, getc and putc have been implemented as macros, and an extra check for stream state likely mattered from a performance perspective. To avoid the extra check, you don't actually need two buffers, just separate buffer pointers for reading and writing. (This is probably how most libcs implement this today.) I suppose memory was really scarce back then.
- cryptonector 2y agoSeparate non-overlapping pointers into one buffer is not that different from two buffers, notionally, but yeah.
- fweimer 2y agoThe idea is that for the non-active mode, the current/end pointers are equal, signifying that the buffer is exhausted. This forces entering the slow path, where the mode can be switched. I don't think an implementation with two active, non-empty buffers is all that useful because you can't tell which buffer's progress should be used for the file pointer adjustment in ftell.