Skip to content

Commit 778afb0

Browse files
authored
fix(pwrite): correct sparse-write failure and ChangeFileSize error check (#415)
* Don't open timer.device any tyme a pthread timed function is called * Fixed uuid created as local memory variable * pwrite was failing after first call
1 parent fb9cb02 commit 778afb0

2 files changed

Lines changed: 29 additions & 14 deletions

File tree

library/c.lib_rev.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define REVISION 1
33
#define SUBREVISION 0
44

5-
#define DATE "07.05.2026"
5+
#define DATE "14.05.2026"
66
#define VERS "clib4.library 2.1"
7-
#define VSTRING "clib4.library 2.1 (07.05.2026)\r\n"
8-
#define VERSTAG "\0$VER: clib4.library 2.1-ab40f98 (07.05.2026)"
7+
#define VSTRING "clib4.library 2.1 (14.05.2026)\r\n"
8+
#define VERSTAG "\0$VER: clib4.library 2.1-ab40f98 (14.05.2026)"

library/unistd/pwrite.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,25 +78,40 @@ pwrite(int fd_num, const void *buf, size_t n, off_t off) {
7878
* AmigaOS ChangeFilePosition fails when seeking past EOF.
7979
* POSIX: pwrite past EOF extends the file with zero-fill.
8080
* Use ChangeFileSize to extend, then retry the seek.
81+
*
82+
* IMPORTANT: after a failed ChangeFilePosition the AmigaDOS file
83+
* handle may be left in an undefined state on some filesystems
84+
* Restore the position to saved_pos BEFORE
85+
* calling ChangeFileSize so the handle is in a known good state.
8186
*/
8287
file_size = GetFileSize(file);
8388
if (file_size != GETPOSITION_ERROR && off >= file_size) {
84-
if (ChangeFileSize(file, off, OFFSET_BEGINNING) != -1) {
85-
new_pos = ChangeFilePosition(file, off, OFFSET_BEGINNING);
86-
if (new_pos == CHANGE_FILE_ERROR) {
87-
ChangeFilePosition(file, saved_pos, OFFSET_BEGINNING);
88-
fd->fd_Position = saved_pos;
89-
__fd_unlock(fd);
90-
__set_errno(EIO);
91-
goto out;
92-
}
93-
} else {
94-
ChangeFilePosition(file, saved_pos, OFFSET_BEGINNING);
89+
/* Restore position first to stabilise the file handle. */
90+
ChangeFilePosition(file, saved_pos, OFFSET_BEGINNING);
91+
92+
/*
93+
* ChangeFileSize returns the old file size on success, or
94+
* CHANGE_FILE_ERROR (0) on failure. CHANGE_FILE_ERROR == 0,
95+
* so we must also consult IoErr() to distinguish a successful
96+
* call whose old size happened to be 0 from a real error —
97+
* exactly the same pattern used in ftruncate.c.
98+
*/
99+
int64_t cfs_result = ChangeFileSize(file, off, OFFSET_BEGINNING);
100+
if (cfs_result == CHANGE_FILE_ERROR && IoErr() != OK) {
95101
fd->fd_Position = saved_pos;
96102
__fd_unlock(fd);
97103
__set_errno(__translate_io_error_to_errno(IoErr()));
98104
goto out;
99105
}
106+
107+
new_pos = ChangeFilePosition(file, off, OFFSET_BEGINNING);
108+
if (new_pos == CHANGE_FILE_ERROR && IoErr() != OK) {
109+
ChangeFilePosition(file, saved_pos, OFFSET_BEGINNING);
110+
fd->fd_Position = saved_pos;
111+
__fd_unlock(fd);
112+
__set_errno(EIO);
113+
goto out;
114+
}
100115
} else {
101116
ChangeFilePosition(file, saved_pos, OFFSET_BEGINNING);
102117
fd->fd_Position = saved_pos;

0 commit comments

Comments
 (0)