public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Michel Lind <salimma@fedoraproject.org>
To: git-commits@fedoraproject.org
Subject: [rpms/hfsutils] rawhide: Port tclhfs.c and hfswish.c to the Tcl 9 result API
Date: Fri, 31 Jul 2026 13:59:39 GMT [thread overview]
Message-ID: <178550637998.1.7278145118155512351.rpms-hfsutils-8fe66a9c2fb7@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/hfsutils
Branch : rawhide
Commit : 8fe66a9c2fb70500d291e871b669d1c097c437d2
Author : Michel Lind <salimma@fedoraproject.org>
Date : 2026-07-20T16:02:34+01:00
Stats : +870/-2 in 3 file(s)
URL : https://src.fedoraproject.org/rpms/hfsutils/c/8fe66a9c2fb70500d291e871b669d1c097c437d2?branch=rawhide
Log:
Port tclhfs.c and hfswish.c to the Tcl 9 result API
- Fix pointer-type mismatches with the Tcl 9 API and allocator pairing
Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Michel Lind <salimma@fedoraproject.org>
---
diff --git a/hfsutils-3.2.6-tcl9-interp-result.patch b/hfsutils-3.2.6-tcl9-interp-result.patch
new file mode 100644
index 0000000..6451f47
--- /dev/null
+++ b/hfsutils-3.2.6-tcl9-interp-result.patch
@@ -0,0 +1,578 @@
+Port tclhfs.c and hfswish.c to the Tcl 9 result API
+
+Tcl 9.0 (Fedora 43+) made the Tcl_Interp struct fully opaque: the
+"result" field -- deprecated since Tcl 8.6 (TIP 330) and until now
+re-enabled with -DUSE_INTERP_RESULT -- no longer exists, so every
+direct interp->result access is a compile error.
+
+Replace them with the supported API, which exists in both Tcl 8 and 9:
+- static message assignments -> Tcl_SetResult(interp, msg, TCL_STATIC)
+- sprintf(interp->result, ...) -> sprintf into a local buffer +
+ Tcl_SetResult(interp, buf, TCL_VOLATILE) (the old code relied on the
+ interp's built-in result buffer, which is gone)
+- the generated "hfsfileN"/"hfsvolN" command names are now built in a
+ local buffer; an explicit Tcl_SetResult keeps them as the script-level
+ return value of "vol open", "vol create" and "hfs mount"
+- reading the result (Tcl_SplitList in "vol path", the error report in
+ hfswish's Tcl_AppInit) -> Tcl_GetStringResult
+
+--- hfsutils-3.2.6/tclhfs.c 1998-11-02 22:08:32.000000000 +0000
++++ hfsutils-3.2.6/tclhfs.c 2026-07-20 15:32:14.655282871 +0100
+@@ -239,7 +239,7 @@ int getdir(Tcl_Interp *interp, volref *v
+ str = direntstr(&ent);
+ if (str == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -284,7 +284,7 @@ int file_cmd(ClientData clientData, Tcl_
+ switch (argc)
+ {
+ case 1:
+- interp->result = "missing command";
++ Tcl_SetResult(interp, "missing command", TCL_STATIC);
+ return TCL_ERROR;
+
+ case 2:
+@@ -297,12 +297,14 @@ int file_cmd(ClientData clientData, Tcl_
+ else if (strcmp(argv[1], "tell") == 0)
+ {
+ long offset;
++ char buf[CHARLEN(unsigned long) + 1];
+
+ offset = hfs_seek(file, 0, HFS_SEEK_CUR);
+ if (offset == -1)
+ return error(interp, 0);
+
+- sprintf(interp->result, "%lu", offset);
++ sprintf(buf, "%lu", offset);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "stat") == 0)
+ {
+@@ -315,7 +317,7 @@ int file_cmd(ClientData clientData, Tcl_
+ str = direntstr(&ent);
+ if (str == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -323,7 +325,7 @@ int file_cmd(ClientData clientData, Tcl_
+ }
+ else if (strcmp(argv[1], "getfork") == 0)
+ {
+- interp->result = (hfs_getfork(file) == 0) ? "data" : "rsrc";
++ Tcl_SetResult(interp, (hfs_getfork(file) == 0) ? "data" : "rsrc", TCL_STATIC);
+ }
+ else
+ {
+@@ -346,7 +348,7 @@ int file_cmd(ClientData clientData, Tcl_
+ fork = 1;
+ else
+ {
+- interp->result = "bad arg to setfork: must be data or rsrc";
++ Tcl_SetResult(interp, "bad arg to setfork: must be data or rsrc", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -355,6 +357,7 @@ int file_cmd(ClientData clientData, Tcl_
+ else if (strcmp(argv[1], "seek") == 0)
+ {
+ long offset;
++ char buf[CHARLEN(unsigned long) + 1];
+
+ if (Tcl_ExprLong(interp, argv[2], &offset) != TCL_OK)
+ return TCL_ERROR;
+@@ -363,7 +366,8 @@ int file_cmd(ClientData clientData, Tcl_
+ if (offset == -1)
+ return error(interp, 0);
+
+- sprintf(interp->result, "%lu", offset);
++ sprintf(buf, "%lu", offset);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "read") == 0)
+ {
+@@ -375,14 +379,14 @@ int file_cmd(ClientData clientData, Tcl_
+
+ if (bytes < 0)
+ {
+- interp->result = "size must be >= 0";
++ Tcl_SetResult(interp, "size must be >= 0", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+ mem = ALLOC(char, bytes + 1);
+ if (mem == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -400,12 +404,14 @@ int file_cmd(ClientData clientData, Tcl_
+ else if (strcmp(argv[1], "write") == 0)
+ {
+ long bytes;
++ char buf[CHARLEN(unsigned long) + 1];
+
+ bytes = hfs_write(file, argv[2], strlen(argv[2]));
+ if (bytes == -1)
+ return error(interp, 0);
+
+- sprintf(interp->result, "%lu", bytes);
++ sprintf(buf, "%lu", bytes);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else
+ {
+@@ -420,6 +426,7 @@ int file_cmd(ClientData clientData, Tcl_
+ {
+ long offset;
+ int whence;
++ char buf[CHARLEN(unsigned long) + 1];
+
+ if (Tcl_ExprLong(interp, argv[2], &offset) != TCL_OK)
+ return TCL_ERROR;
+@@ -434,7 +441,7 @@ int file_cmd(ClientData clientData, Tcl_
+ whence = HFS_SEEK_END;
+ else
+ {
+- interp->result = "bad arg 3: must be start, current, or end";
++ Tcl_SetResult(interp, "bad arg 3: must be start, current, or end", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -442,7 +449,8 @@ int file_cmd(ClientData clientData, Tcl_
+ if (offset == -1)
+ return error(interp, 0);
+
+- sprintf(interp->result, "%lu", offset);
++ sprintf(buf, "%lu", offset);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else
+ {
+@@ -500,18 +508,21 @@ void file_ref(Tcl_Interp *interp, volref
+ Tcl_CmdInfo info;
+ Tcl_HashEntry *entry;
+ int new;
++ char name[CHARLEN(int) + 8];
+
+ do
+- sprintf(interp->result, "hfsfile%d", id++);
+- while (Tcl_GetCommandInfo(interp, interp->result, &info));
++ sprintf(name, "hfsfile%d", id++);
++ while (Tcl_GetCommandInfo(interp, name, &info));
+
+ fref->file = file;
+ fref->interp = interp;
+- fref->cmd = Tcl_CreateCommand(interp, interp->result,
++ fref->cmd = Tcl_CreateCommand(interp, name,
+ file_cmd, fref, file_del);
+
+ entry = Tcl_CreateHashEntry(&files, (char *) fref, &new);
+ Tcl_SetHashValue(entry, vref);
++
++ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ }
+
+ /*
+@@ -618,7 +629,7 @@ int copynative(Tcl_Interp *interp, volre
+ if (srcvref->vol == dstvref->vol &&
+ ent.cnid == cnid)
+ {
+- interp->result = "source and destination files are the same";
++ Tcl_SetResult(interp, "source and destination files are the same", TCL_STATIC);
+ hfs_close(ifile);
+ return TCL_ERROR;
+ }
+@@ -672,7 +683,7 @@ int copyin(Tcl_Interp *interp, hfsvol *v
+ copyfile = cpi_raw;
+ else
+ {
+- interp->result = "bad mode: must be macb, binh, text, or raw";
++ Tcl_SetResult(interp, "bad mode: must be macb, binh, text, or raw", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -707,7 +718,7 @@ int copyout(Tcl_Interp *interp, hfsvol *
+ copyfile = cpo_raw;
+ else
+ {
+- interp->result = "bad mode: must be macb, binh, text, or raw";
++ Tcl_SetResult(interp, "bad mode: must be macb, binh, text, or raw", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -821,7 +832,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+ switch (argc)
+ {
+ case 1:
+- interp->result = "missing command";
++ Tcl_SetResult(interp, "missing command", TCL_STATIC);
+ return TCL_ERROR;
+
+ case 2:
+@@ -835,23 +846,29 @@ int vol_cmd(ClientData clientData, Tcl_I
+ else if (strcmp(argv[1], "size") == 0)
+ {
+ hfsvolent ent;
++ char buf[2 * CHARLEN(unsigned long) + 2];
+
+ hfs_vstat(vol, &ent);
+- sprintf(interp->result, "%lu %lu", ent.totbytes, ent.freebytes);
++ sprintf(buf, "%lu %lu", ent.totbytes, ent.freebytes);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "crdate") == 0)
+ {
+ hfsvolent ent;
++ char buf[CHARLEN(long) + 1];
+
+ hfs_vstat(vol, &ent);
+- sprintf(interp->result, "%ld", (long) ent.crdate);
++ sprintf(buf, "%ld", (long) ent.crdate);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "mddate") == 0)
+ {
+ hfsvolent ent;
++ char buf[CHARLEN(long) + 1];
+
+ hfs_vstat(vol, &ent);
+- sprintf(interp->result, "%ld", (long) ent.mddate);
++ sprintf(buf, "%ld", (long) ent.mddate);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "islocked") == 0)
+ {
+@@ -859,9 +876,9 @@ int vol_cmd(ClientData clientData, Tcl_I
+
+ hfs_vstat(vol, &ent);
+ if (ent.flags & HFS_ISLOCKED)
+- interp->result = "1";
++ Tcl_SetResult(interp, "1", TCL_STATIC);
+ else
+- interp->result = "0";
++ Tcl_SetResult(interp, "0", TCL_STATIC);
+ }
+ else if (strcmp(argv[1], "umount") == 0)
+ {
+@@ -870,7 +887,12 @@ int vol_cmd(ClientData clientData, Tcl_I
+ return error(interp, 0);
+ }
+ else if (strcmp(argv[1], "cwd") == 0)
+- sprintf(interp->result, "%lu", vref->cwd);
++ {
++ char buf[CHARLEN(unsigned long) + 1];
++
++ sprintf(buf, "%lu", vref->cwd);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
++ }
+ else if (strcmp(argv[1], "path") == 0)
+ {
+ char name[HFS_MAX_FLEN + 1];
+@@ -890,7 +912,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+
+ /* reverse the resulting list */
+
+- if (Tcl_SplitList(interp, interp->result, &listc, &listv) != TCL_OK)
++ if (Tcl_SplitList(interp, Tcl_GetStringResult(interp), &listc, &listv) != TCL_OK)
+ return TCL_ERROR;
+
+ for (i = 0; i < listc / 2; ++i)
+@@ -918,7 +940,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+ return error(interp, 0);
+ }
+ else if (strcmp(argv[1], "sepchar") == 0)
+- interp->result = ":";
++ Tcl_SetResult(interp, ":", TCL_STATIC);
+ else
+ {
+ Tcl_AppendResult(interp, "bad command \"", argv[1],
+@@ -965,7 +987,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+ fref = ALLOC(fileref, 1);
+ if (fref == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -990,7 +1012,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+ str = direntstr(&ent);
+ if (str == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1043,7 +1065,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+
+ if (fargv == 0)
+ {
+- interp->result = "globbing error";
++ Tcl_SetResult(interp, "globbing error", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1099,14 +1121,14 @@ int vol_cmd(ClientData clientData, Tcl_I
+ if (strlen(argv[3]) != 4 ||
+ strlen(argv[4]) != 4)
+ {
+- interp->result = "type and creator must be 4 character strings";
++ Tcl_SetResult(interp, "type and creator must be 4 character strings", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+ fref = ALLOC(fileref, 1);
+ if (fref == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1164,7 +1186,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+
+ if (argc < 2)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1176,10 +1198,11 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ Tcl_CmdInfo info;
+ Tcl_HashEntry *entry;
+ int new;
++ char name[CHARLEN(int) + 8];
+
+ if (argc < 3 || argc > 4)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1191,6 +1214,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ else
+ {
+ int nparts;
++ char buf[64];
+
+ suid_enable();
+ nparts = hfs_nparts(argv[2]);
+@@ -1198,8 +1222,9 @@ int cmd_hfs(ClientData clientData, Tcl_I
+
+ if (nparts > 1)
+ {
+- sprintf(interp->result, "must specify partition number "
++ sprintf(buf, "must specify partition number "
+ "(%d available)", nparts);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ return TCL_ERROR;
+ }
+ else if (nparts == -1)
+@@ -1211,7 +1236,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ vref = ALLOC(volref, 1);
+ if (vref == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1232,20 +1257,23 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ entry = Tcl_CreateHashEntry(&volumes, (char *) vref, &new);
+
+ do
+- sprintf(interp->result, "hfsvol%d", id++);
+- while (Tcl_GetCommandInfo(interp, interp->result, &info));
++ sprintf(name, "hfsvol%d", id++);
++ while (Tcl_GetCommandInfo(interp, name, &info));
+
+- Tcl_CreateCommand(interp, interp->result,
++ Tcl_CreateCommand(interp, name,
+ vol_cmd, vref, vol_del);
++
++ Tcl_SetResult(interp, name, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "zero") == 0)
+ {
+ int nparts;
+ unsigned long len;
++ char buf[CHARLEN(unsigned long) + 1];
+
+ if (argc != 4)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1255,7 +1283,8 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ if (do_zero(argv[2], nparts, &len) == -1)
+ return error(interp, 0);
+
+- sprintf(interp->result, "%lu", len);
++ sprintf(buf, "%lu", len);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "mkpart") == 0)
+ {
+@@ -1263,7 +1292,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+
+ if (argc != 4)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1276,10 +1305,11 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ else if (strcmp(argv[1], "nparts") == 0)
+ {
+ int nparts;
++ char buf[CHARLEN(int) + 1];
+
+ if (argc != 3)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1287,7 +1317,8 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ nparts = hfs_nparts(argv[2]);
+ suid_disable();
+
+- sprintf(interp->result, "%d", nparts);
++ sprintf(buf, "%d", nparts);
++ Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ }
+ else if (strcmp(argv[1], "format") == 0)
+ {
+@@ -1295,7 +1326,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+
+ if (argc < 5 || argc > 6)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1316,7 +1347,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ {
+ free(listv);
+
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1356,7 +1387,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+
+ if (argc != 5)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1365,8 +1396,8 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ (strcmp(argv[3], "latin1") != 0 &&
+ strcmp(argv[3], "macroman") != 0))
+ {
+- interp->result = "bad arg to chartrans: "
+- "charsets must be one of latin1, macroman";
++ Tcl_SetResult(interp, "bad arg to chartrans: "
++ "charsets must be one of latin1, macroman", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1384,7 +1415,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+
+ if (result == 0)
+ {
+- interp->result = "out of memory";
++ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+@@ -1394,41 +1425,41 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ {
+ if (argc != 2)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+- interp->result = (char *) hfsutils_version;
++ Tcl_SetResult(interp, (char *) hfsutils_version, TCL_STATIC);
+ }
+ else if (strcmp(argv[1], "copyright") == 0)
+ {
+ if (argc != 2)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+- interp->result = (char *) hfsutils_copyright;
++ Tcl_SetResult(interp, (char *) hfsutils_copyright, TCL_STATIC);
+ }
+ else if (strcmp(argv[1], "author") == 0)
+ {
+ if (argc != 2)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+- interp->result = (char *) hfsutils_author;
++ Tcl_SetResult(interp, (char *) hfsutils_author, TCL_STATIC);
+ }
+ else if (strcmp(argv[1], "license") == 0)
+ {
+ if (argc != 2)
+ {
+- interp->result = "wrong # args";
++ Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+- interp->result = (char *) hfsutils_license;
++ Tcl_SetResult(interp, (char *) hfsutils_license, TCL_STATIC);
+ }
+ else
+ {
+@@ -1455,7 +1486,7 @@ int cmd_exit(ClientData clientData, Tcl_
+
+ if (argc > 2)
+ {
+- interp->result = "wrong # args: should be \"exit ?returnCode?\"";
++ Tcl_SetResult(interp, "wrong # args: should be \"exit ?returnCode?\"", TCL_STATIC);
+ return TCL_ERROR;
+ }
+
+--- hfsutils-3.2.6/hfswish.c 1998-04-11 09:26:57.000000000 +0100
++++ hfsutils-3.2.6/hfswish.c 2026-07-20 15:44:40.281374410 +0100
+@@ -94,7 +94,7 @@ int Tcl_AppInit(Tcl_Interp *interp)
+
+ if (Tcl_Eval(interp, xhfs) == TCL_ERROR)
+ {
+- fprintf(stderr, "Error: %s\n", interp->result);
++ fprintf(stderr, "Error: %s\n", Tcl_GetStringResult(interp));
+ exit(1);
+ }
+
diff --git a/hfsutils-3.2.6-tcl9-pointer-types.patch b/hfsutils-3.2.6-tcl9-pointer-types.patch
new file mode 100644
index 0000000..5f3c150
--- /dev/null
+++ b/hfsutils-3.2.6-tcl9-pointer-types.patch
@@ -0,0 +1,280 @@
+Fix pointer-type mismatches with the Tcl 9 API and allocator pairing
+
+This completes the Tcl 9 port so the package no longer needs
+-Wno-incompatible-pointer-types:
+
+- Tcl 9's Tcl_CmdProc takes (int argc, const char *argv[]); adjust the
+ command procedures and the helpers they hand argv to. cs_latin1()/
+ cs_macroman() only read their input, so their argument is constified
+ rather than casting away const at the call sites.
+- Tcl_SplitList() now fills in a Tcl_Size (64-bit) element count and a
+ const char ** vector. Passing the old int * misreads/clobbers stack
+ memory on 64-bit architectures, so this was a latent runtime bug, not
+ just a warning.
+- Tcl_Merge() takes const char *const *; constify direntstr()'s argv
+ and cast hfs_glob()'s result vector.
+- Pair allocators correctly for Tcl 9, where Tcl_Free() is no longer
+ interchangeable with free(): memory obtained from Tcl (Tcl_SplitList
+ vectors, Tcl_Merge strings) is released with Tcl_Free(); the "read"
+ command result is allocated with Tcl_AttemptAlloc() to match its
+ TCL_DYNAMIC free; the malloc()ed chartrans result is copied with
+ TCL_VOLATILE and freed with free().
+- Tcl_GetInt() in "hfs mkpart" needs an int, not an unsigned int.
+
+--- hfsutils-3.2.6/tclhfs.c 2026-07-20 15:51:51.339443468 +0100
++++ hfsutils-3.2.6/tclhfs.c 2026-07-20 15:58:13.697974421 +0100
+@@ -120,7 +120,7 @@ char *direntstr(hfsdirent *ent)
+ mddate[CHARLEN(long) + 1],
+ bkdate[CHARLEN(long) + 1];
+ register int argc;
+- char *argv[24];
++ const char *argv[24];
+ int locked, invis;
+
+ argc = 0;
+@@ -228,7 +228,7 @@ int getdir(Tcl_Interp *interp, volref *v
+
+ Tcl_AppendElement(interp, str);
+
+- free(str);
++ Tcl_Free(str);
+ }
+
+ if (hfs_closedir(dir) == -1)
+@@ -245,7 +245,7 @@ int getdir(Tcl_Interp *interp, volref *v
+
+ Tcl_AppendElement(interp, str);
+
+- free(str);
++ Tcl_Free(str);
+ }
+
+ return TCL_OK;
+@@ -276,7 +276,7 @@ void file_del(ClientData clientData)
+ */
+ static
+ int file_cmd(ClientData clientData, Tcl_Interp *interp,
+- int argc, char *argv[])
++ int argc, const char *argv[])
+ {
+ fileref *fref = clientData;
+ hfsfile *file = fref->file;
+@@ -383,7 +383,7 @@ int file_cmd(ClientData clientData, Tcl_
+ return TCL_ERROR;
+ }
+
+- mem = ALLOC(char, bytes + 1);
++ mem = Tcl_AttemptAlloc(bytes + 1);
+ if (mem == 0)
+ {
+ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+@@ -393,7 +393,7 @@ int file_cmd(ClientData clientData, Tcl_
+ bytes = hfs_read(file, mem, bytes);
+ if (bytes == -1)
+ {
+- free(mem);
++ Tcl_Free(mem);
+ return error(interp, 0);
+ }
+
+@@ -558,7 +558,7 @@ int do_copynative(Tcl_Interp *interp, hf
+ * DESCRIPTION: copy an HFS file to another HFS volume
+ */
+ static
+-int copynative(Tcl_Interp *interp, volref *srcvref, char *argv[])
++int copynative(Tcl_Interp *interp, volref *srcvref, const char *argv[])
+ {
+ volref *dstvref;
+ Tcl_CmdInfo info;
+@@ -666,7 +666,7 @@ int copynative(Tcl_Interp *interp, volre
+ * DESCRIPTION: copy a UNIX file into an HFS volume
+ */
+ static
+-int copyin(Tcl_Interp *interp, hfsvol *vol, char *argv[])
++int copyin(Tcl_Interp *interp, hfsvol *vol, const char *argv[])
+ {
+ cpifunc copyfile;
+
+@@ -701,7 +701,7 @@ int copyin(Tcl_Interp *interp, hfsvol *v
+ * DESCRIPTION: copy an HFS file out to a UNIX file
+ */
+ static
+-int copyout(Tcl_Interp *interp, hfsvol *vol, char *argv[])
++int copyout(Tcl_Interp *interp, hfsvol *vol, const char *argv[])
+ {
+ cpofunc copyfile;
+
+@@ -824,7 +824,7 @@ void vol_del(ClientData clientData)
+ */
+ static
+ int vol_cmd(ClientData clientData, Tcl_Interp *interp,
+- int argc, char *argv[])
++ int argc, const char *argv[])
+ {
+ volref *vref = clientData;
+ hfsvol *vol = vref->vol;
+@@ -897,8 +897,8 @@ int vol_cmd(ClientData clientData, Tcl_I
+ {
+ char name[HFS_MAX_FLEN + 1];
+ long id;
+- int listc, i;
+- char **listv;
++ Tcl_Size listc, i;
++ const char **listv;
+ char *result;
+
+ id = vref->cwd;
+@@ -917,7 +917,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+
+ for (i = 0; i < listc / 2; ++i)
+ {
+- char *tmp;
++ const char *tmp;
+
+ tmp = listv[i];
+ listv[i] = listv[listc - 1 - i];
+@@ -925,7 +925,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+ }
+
+ result = Tcl_Merge(listc, listv);
+- free(listv);
++ Tcl_Free((void *) listv);
+
+ Tcl_SetResult(interp, result, TCL_DYNAMIC);
+ }
+@@ -1051,8 +1051,10 @@ int vol_cmd(ClientData clientData, Tcl_I
+ }
+ else if (strcmp(argv[1], "glob") == 0)
+ {
+- int listc, fargc;
+- char **listv, **fargv, *result;
++ Tcl_Size listc;
++ int fargc;
++ const char **listv;
++ char **fargv, *result;
+
+ if (hfs_setcwd(vol, vref->cwd) == -1)
+ return error(interp, 0);
+@@ -1060,8 +1062,8 @@ int vol_cmd(ClientData clientData, Tcl_I
+ if (Tcl_SplitList(interp, argv[2], &listc, &listv) != TCL_OK)
+ return TCL_ERROR;
+
+- fargv = hfs_glob(vol, listc, listv, &fargc);
+- free(listv);
++ fargv = hfs_glob(vol, listc, (char **) listv, &fargc);
++ Tcl_Free((void *) listv);
+
+ if (fargv == 0)
+ {
+@@ -1069,7 +1071,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+ return TCL_ERROR;
+ }
+
+- result = Tcl_Merge(fargc, fargv);
++ result = Tcl_Merge(fargc, (const char **) fargv);
+ free(fargv);
+
+ Tcl_SetResult(interp, result, TCL_DYNAMIC);
+@@ -1180,7 +1182,7 @@ int vol_cmd(ClientData clientData, Tcl_I
+ */
+ static
+ int cmd_hfs(ClientData clientData, Tcl_Interp *interp,
+- int argc, char *argv[])
++ int argc, const char *argv[])
+ {
+ static int id = 0;
+
+@@ -1288,7 +1290,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ }
+ else if (strcmp(argv[1], "mkpart") == 0)
+ {
+- unsigned int len;
++ int len;
+
+ if (argc != 4)
+ {
+@@ -1335,8 +1337,8 @@ int cmd_hfs(ClientData clientData, Tcl_I
+
+ if (argc == 6)
+ {
+- int listc, i;
+- char **listv;
++ Tcl_Size listc, i;
++ const char **listv;
+ unsigned long *badblocks;
+
+ if (Tcl_SplitList(interp, argv[5], &listc, &listv) != TCL_OK)
+@@ -1345,7 +1347,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ badblocks = ALLOCX(unsigned long, listc);
+ if (listc && badblocks == 0)
+ {
+- free(listv);
++ Tcl_Free((void *) listv);
+
+ Tcl_SetResult(interp, "out of memory", TCL_STATIC);
+ return TCL_ERROR;
+@@ -1356,13 +1358,13 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ if (Tcl_ExprLong(interp, listv[i],
+ (long *) &badblocks[i]) != TCL_OK)
+ {
+- free(listv);
++ Tcl_Free((void *) listv);
+ FREE(badblocks);
+ return TCL_ERROR;
+ }
+ }
+
+- free(listv);
++ Tcl_Free((void *) listv);
+
+ if (do_format(argv[2], partno, 0, argv[4], listc, badblocks) == -1)
+ {
+@@ -1419,7 +1421,8 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ return TCL_ERROR;
+ }
+
+- Tcl_SetResult(interp, result, TCL_DYNAMIC);
++ Tcl_SetResult(interp, result, TCL_VOLATILE);
++ free(result);
+ }
+ else if (strcmp(argv[1], "version") == 0)
+ {
+@@ -1480,7 +1483,7 @@ int cmd_hfs(ClientData clientData, Tcl_I
+ */
+ static
+ int cmd_exit(ClientData clientData, Tcl_Interp *interp,
+- int argc, char *argv[])
++ int argc, const char *argv[])
+ {
+ int status = 0;
+
+--- hfsutils-3.2.6/charset.h 1998-04-11 09:26:53.000000000 +0100
++++ hfsutils-3.2.6/charset.h 2026-07-20 15:58:13.697974421 +0100
+@@ -23,5 +23,5 @@ typedef unsigned short UCS2;
+
+ UCS2 *cs_unicode(char *, int *);
+
+-char *cs_latin1(char *, int *);
+-char *cs_macroman(char *, int *);
++char *cs_latin1(const char *, int *);
++char *cs_macroman(const char *, int *);
+--- hfsutils-3.2.6/charset.c 1998-11-02 22:08:23.000000000 +0000
++++ hfsutils-3.2.6/charset.c 2026-07-20 15:58:13.697974421 +0100
+@@ -151,7 +151,7 @@ UCS2 *cs_unicode(char *mstr, int *lenptr
+ * NAME: charset->latin1()
+ * DESCRIPTION: return a Latin-1 (ISO 8859-1) string for MacOS Standard Roman
+ */
+-char *cs_latin1(char *mstr, int *lenptr)
++char *cs_latin1(const char *mstr, int *lenptr)
+ {
+ int ilen, olen, i;
+ char *latin1, *ptr;
+@@ -229,7 +229,7 @@ void mktable(void)
+ * NAME: charset->macroman()
+ * DESCRIPTION: return a MacOS Standard Roman string for Latin-1 (ISO 8859-1)
+ */
+-char *cs_macroman(char *lstr, int *lenptr)
++char *cs_macroman(const char *lstr, int *lenptr)
+ {
+ int ilen, olen, i;
+ char *macroman, *ptr;
diff --git a/hfsutils.spec b/hfsutils.spec
index d842303..4f7cbbe 100644
--- a/hfsutils.spec
+++ b/hfsutils.spec
@@ -1,7 +1,7 @@
Summary: Tools for reading and writing Macintosh HFS volumes
Name: hfsutils
Version: 3.2.6
-Release: 56%{?dist}
+Release: 57%{?dist}
# Automatically converted from old format: GPLv2+ - review is highly recommended.
License: GPL-2.0-or-later
Source: ftp://ftp.mars.org/pub/hfs/%{name}-%{version}.tar.gz
@@ -9,6 +9,12 @@ Patch0: hfsutils-3.2.6-errno.patch
Patch1: hfsutils-3.2.6-largefile.patch
Patch2: hfsutils-3.2.6-configure-c99.patch
Patch3: hfsutils-3.2.6-include-c99.patch
+# Tcl 9 made Tcl_Interp opaque; use Tcl_SetResult()/Tcl_GetStringResult()
+# instead of poking interp->result directly
+Patch4: hfsutils-3.2.6-tcl9-interp-result.patch
+# Tcl 9 type fixes (Tcl_Size, const argv) and Tcl_Free/free pairing, so we
+# can drop -Wno-incompatible-pointer-types
+Patch5: hfsutils-3.2.6-tcl9-pointer-types.patch
URL: http://www.mars.org/home/rob/proj/hfs/
BuildRequires: libXft-devel tcl-devel tk-devel gcc
BuildRequires: make
@@ -44,7 +50,7 @@ hfsutils-devel package.
%autosetup -p1
%build
-CFLAGS="%{optflags} -D_FILE_OFFSET_BITS=64 -DUSE_INTERP_RESULT -Wno-incompatible-pointer-types -Wno-deprecated-declarations -Wno-deprecated-declarations -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-int-to-pointer-cast"
+CFLAGS="%{optflags} -D_FILE_OFFSET_BITS=64 -Wno-deprecated-declarations -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-int-to-pointer-cast"
%{configure} --with-tcl=%{_libdir} --with-tk=%{_libdir}
make
make hfsck/hfsck
@@ -111,6 +117,10 @@ install -p -m 0755 hfsck/hfsck $RPM_BUILD_ROOT/%{_bindir}
%{_includedir}/rsrc.h
%changelog
+* Mon Jul 20 2026 Michel Lind <salimma@fedoraproject.org> - 3.2.6-57
+- Port tclhfs.c and hfswish.c to the Tcl 9 result API
+- Fix pointer-type mismatches with the Tcl 9 API and allocator pairing
+
* Thu Jul 16 2026 Fedora Release Engineering <releng@fedoraproject.org> - 3.2.6-56
- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild
reply other threads:[~2026-07-31 13:59 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178550637998.1.7278145118155512351.rpms-hfsutils-8fe66a9c2fb7@fedoraproject.org \
--to=salimma@fedoraproject.org \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox