jcs
/amend
/amendments
/183
util: Make xmalloc take flags, move xalloc_dump here
This makes it again panic on failure by default, but callers can
pass M_CANFAIL for more fine-grained handling.
Also fold xmalloczero into this with M_ZERO.
jcs made amendment 183 about 1 month ago
--- main.c Mon Sep 28 21:28:01 2026
+++ main.c Fri Oct 2 17:48:59 2026
@@ -35,8 +35,6 @@ struct settings settings;
#ifdef MALLOC_DEBUG
MenuHandle debug_menu;
#define DEBUG_MENU_DUMP_ID 999
-static short xalloc_frefnum = 0;
-size_t xalloc_printf(const char *format, ...);
#endif
bool handle_menu(long menu_id);
@@ -272,32 +270,10 @@ handle_menu(long menu_id)
#ifdef MALLOC_DEBUG
case DEBUG_MENU_DUMP_ID:
switch (LoWord(menu_id)) {
- case 1: {
- Str255 vname;
- short error, vrefnum;
-
- error = GetVol(&vname, &vrefnum);
- if (error)
- panic("Failed to get volume: %d", error);
- PtoCstr(vname);
- strlcat((char *)vname, ":amend_xalloc.txt", sizeof(vname));
- CtoPstr(vname);
-
- error = Create(vname, vrefnum, 'TEXT', 'TEXT');
- if (error && error != dupFNErr)
- panic("Failed to create file: %d", error);
- error = FSOpen(vname, vrefnum, &xalloc_frefnum);
- if (error)
- panic("Failed to open file: %d", error);
- error = SetEOF(xalloc_frefnum, 0);
- if (error)
- panic("Failed to truncate file: %d", error);
-
- xalloc_print(xalloc_printf);
- FSClose(xalloc_frefnum);
+ case 1:
+ xalloc_dump("amend_xalloc.txt");
break;
}
- }
ret = true;
break;
#endif
@@ -309,32 +285,6 @@ handled:
HiliteMenu(0);
return ret;
}
-
-#ifdef MALLOC_DEBUG
-size_t
-xalloc_printf(const char *format, ...)
-{
- static char buf[256];
- short error;
- va_list va;
- size_t len;
-
- va_start(va, format);
- len = vsnprintf(buf, sizeof(buf), format, va);
- va_end(va);
-
- error = FSWrite(xalloc_frefnum, &len, buf);
- if (error)
- panic("Failed to write: %d", error);
-
- len = 1;
- error = FSWrite(xalloc_frefnum, &len, "\r");
- if (error)
- panic("Failed to write: %d", error);
-
- return len;
-}
-#endif
void
menu_defaults(void)
--- util.c Wed Dec 17 20:45:52 2025
+++ util.c Fri Oct 2 17:48:06 2026
@@ -201,10 +201,11 @@ struct xalloc {
};
#define XALLOC_NXALLOCS 512
static struct xalloc *xallocs = NULL;
+static short xalloc_frefnum = 0;
#endif
void *
-xmalloc(size_t size)
+xmalloc(size_t size, long flags)
{
void *ptr;
#ifdef MALLOC_DEBUG
@@ -220,9 +221,15 @@ xmalloc(size_t size)
panic("xmalloc: zero size");
ptr = NewPtr(size);
- if (ptr == NULL)
+ if (ptr == NULL) {
+ if (!(flags & M_CANFAIL))
+ panic("xmalloc: failed allocating %lu bytes", size);
return NULL;
+ }
+ if (flags & M_ZERO)
+ memset(ptr, 0, size);
+
#ifdef MALLOC_DEBUG
asm {
move.l a6,_a6
@@ -350,25 +357,13 @@ xfree(void *ptrptr)
}
void *
-xmalloczero(size_t size)
-{
- void *ptr;
-
- ptr = xmalloc(size);
- if (ptr != NULL)
- memset(ptr, 0, size);
-
- return ptr;
-}
-
-void *
xcalloc(size_t nmemb, size_t size)
{
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
nmemb > 0 && SIZE_MAX / nmemb < size)
panic("xcalloc(%lu, %lu) overflow", nmemb, size);
- return xmalloczero(nmemb * size);
+ return xmalloc(nmemb * size, M_ZERO);
}
void *
@@ -376,7 +371,7 @@ xrealloc(void *src, size_t size)
{
void *ptr, *tsrc;
- ptr = xmalloc(size);
+ ptr = xmalloc(size, 0);
if (ptr != NULL && src != NULL) {
memcpy(ptr, src, size);
tsrc = src;
@@ -403,7 +398,7 @@ xstrdup(const char *str)
size_t len;
len = strlen(str);
- cp = xmalloc(len + 1);
+ cp = xmalloc(len + 1, 0);
if (cp != NULL)
strlcpy(cp, str, len + 1);
@@ -422,7 +417,7 @@ xstrndup(const char *str, size_t maxlen)
;
len = (size_t)(cp - str);
- copy = xmalloc(len + 1);
+ copy = xmalloc(len + 1, 0);
if (copy != NULL) {
(void)memcpy(copy, str, len);
copy[len] = '\0';
@@ -471,6 +466,58 @@ xalloc_print(size_t (*printer)(const char *, ...))
printer("%ld bytes in %ld allocations in use", total, nallocs);
}
+
+void
+xalloc_dump(char *filename)
+{
+ Str255 vname;
+ short error, vrefnum;
+
+ error = GetVol(&vname, &vrefnum);
+ if (error)
+ panic("Failed to get volume: %d", error);
+ PtoCstr(vname);
+ strlcat((char *)vname, ":", sizeof(vname));
+ strlcat((char *)vname, filename, sizeof(vname));
+ CtoPstr(vname);
+
+ error = Create(vname, vrefnum, 'TEXT', 'TEXT');
+ if (error && error != dupFNErr)
+ panic("Failed to create file: %d", error);
+ error = FSOpen(vname, vrefnum, &xalloc_frefnum);
+ if (error)
+ panic("Failed to open file: %d", error);
+ error = SetEOF(xalloc_frefnum, 0);
+ if (error)
+ panic("Failed to truncate file: %d", error);
+
+ xalloc_print(xalloc_printf);
+ FSClose(xalloc_frefnum);
+}
+
+size_t
+xalloc_printf(const char *format, ...)
+{
+ static char buf[256];
+ short error;
+ va_list va;
+ size_t len;
+
+ va_start(va, format);
+ len = vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+
+ error = FSWrite(xalloc_frefnum, &len, buf);
+ if (error)
+ panic("Failed to write: %d", error);
+
+ len = 1;
+ error = FSWrite(xalloc_frefnum, &len, "\r");
+ if (error)
+ panic("Failed to write: %d", error);
+
+ return len;
+}
#endif
/*
@@ -484,8 +531,11 @@ getline(char *str, size_t len, char **ret)
for (i = 0; i < len; i++) {
if (str[i] == '\r' || i == len - 1) {
- if (*ret == NULL)
- *ret = xmalloc(i + 1);
+ if (*ret == NULL) {
+ *ret = xmalloc(i + 1, M_CANFAIL);
+ if (*ret == NULL)
+ return -1;
+ }
memcpy(*ret, str, i + 1);
(*ret)[i] = '\0';
return i + 1;
@@ -1020,7 +1070,9 @@ xGetStringAsChar(short id)
h = xGetString(id);
HLock(h);
l = (*h)[0];
- out = xmalloc(l + 1);
+ out = xmalloc(l + 1, M_CANFAIL);
+ if (out == NULL)
+ return NULL;
memcpy((void *)out, (void *)(*h + 1), l);
out[l] = '\0';
ReleaseResource(h);
@@ -1075,8 +1127,8 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b
return 0;
}
- name = xmalloc(FILENAME_MAX);
-
+ name = xmalloc(FILENAME_MAX, 0);
+
wdir.ioVRefNum = wdir.ioWDVRefNum = vRefNum;
wdir.ioWDIndex = 0;
wdir.ioWDProcID = 0;
@@ -1109,8 +1161,8 @@ getpath(short vRefNum, Str255 fileName, Str255 *ret, b
wcinfo.ioDrParID = wdir.ioWDDirID;
wcinfo.ioDrDirID = wdir.ioWDDirID;
- tmp = xmalloc(FILENAME_MAX);
- tmpret = xmalloc(FILENAME_MAX);
+ tmp = xmalloc(FILENAME_MAX, 0);
+ tmpret = xmalloc(FILENAME_MAX, 0);
/* go backwards, prepending each folder's parent */
while (wcinfo.ioDrParID != 1) {
@@ -1289,9 +1341,10 @@ copy_file(Str255 source, Str255 dest, bool overwrite)
OSErr
copy_file_contents(short source_ref, short dest_ref)
{
- char *buf;
- short error;
+ char *buf = NULL;
+ size_t buf_size = 4048;
long source_size, count;
+ short error;
GetEOF(source_ref, &source_size);
error = SetFPos(source_ref, fsFromStart, 0);
@@ -1303,11 +1356,12 @@ copy_file_contents(short source_ref, short dest_ref)
error = SetFPos(dest_ref, fsFromStart, 0);
if (error)
return error;
-
- buf = xmalloc(1024);
+ buf_size = 1024;
+ buf = xmalloc(buf_size, 0);
+
while (source_size > 0) {
- count = 1024;
+ count = buf_size;
if (count > source_size)
count = source_size;
error = FSRead(source_ref, &count, buf);
--- util.h Wed Oct 2 12:51:17 2024
+++ util.h Fri Oct 2 17:48:30 2026
@@ -76,10 +76,11 @@ struct stat {
void util_init(void);
-void * xmalloc(size_t);
+void * xmalloc(size_t, long);
+#define M_ZERO 0x00000001
+#define M_CANFAIL 0x00000002
void xfree(void *ptrptr);
void xfree_verify(void);
-void * xmalloczero(size_t);
void * xcalloc(size_t, size_t);
void * xrealloc(void *src, size_t size);
void * xreallocarray(void *, size_t, size_t);
@@ -87,6 +88,8 @@ char * xstrdup(const char *);
char * xstrndup(const char *str, size_t maxlen);
#ifdef MALLOC_DEBUG
void xalloc_print(size_t (*printer)(const char *, ...));
+void xalloc_dump(char *);
+size_t xalloc_printf(const char *format, ...);
#endif
short getline(char *str, size_t len, char **ret);