Our basename(3) and dirname(3) take a const argument:

  char    *basename(const char *);
  char    *dirname(const char *);

POSIX says otherwise...

  char *basename(char *path);
  char *dirname(char *path);

... and explicitly says the functions may modify the input string.


Our functions were const-ified in 1999 by espie@:

  proper const semantics for dirname & basename.
  (this follows FreeBSD and Linux. Single Unix 2 is still illogical)

Well, four years ago, FreeBSD finally switched to the POSIX prototypes
https://svnweb.freebsd.org/base/head/include/libgen.h?revision=303451&view=markup
and in fact now has an implementation that modifies the string.

Linux (GNU libc) has a bizarro solution where you get a const basename()
and no dirname() if you just include <string.h>, but POSIX basename()
and dirname() if you instead or also include <libgen.h>.

A make build with the patch below succeeds, but gains some new
warnings "passing 'const char *' to parameter of type 'char *'
discards qualifiers".

This is a portability trap.  Code written on OpenBSD may not be
prepared for basename() or dirname() to splat a '\0' into the input
string, despite the warning in the man page.

I'm in favor of moving to the POSIX prototypes, but I don't know
if there are any hidden pitfalls I may be missing.  Opinions,
comments?


Index: include/libgen.h
===================================================================
RCS file: /cvs/src/include/libgen.h,v
retrieving revision 1.9
diff -u -p -r1.9 libgen.h
--- include/libgen.h    25 Jan 2019 00:19:25 -0000      1.9
+++ include/libgen.h    11 Sep 2020 20:41:34 -0000
@@ -22,8 +22,8 @@
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
-char   *basename(const char *);
-char   *dirname(const char *);
+char   *basename(char *);
+char   *dirname(char *);
 __END_DECLS
 
 #endif /* _LIBGEN_H_ */
Index: lib/libc/gen/basename.3
===================================================================
RCS file: /cvs/src/lib/libc/gen/basename.3,v
retrieving revision 1.24
diff -u -p -r1.24 basename.3
--- lib/libc/gen/basename.3     25 Jan 2019 00:19:25 -0000      1.24
+++ lib/libc/gen/basename.3     11 Sep 2020 20:46:30 -0000
@@ -23,7 +23,7 @@
 .Sh SYNOPSIS
 .In libgen.h
 .Ft char *
-.Fn basename "const char *path"
+.Fn basename "char *path"
 .Sh DESCRIPTION
 The
 .Fn basename
Index: lib/libc/gen/basename.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/basename.c,v
retrieving revision 1.16
diff -u -p -r1.16 basename.c
--- lib/libc/gen/basename.c     25 Jan 2019 00:19:25 -0000      1.16
+++ lib/libc/gen/basename.c     11 Sep 2020 20:43:13 -0000
@@ -22,7 +22,7 @@
 #include <string.h>
 
 char *
-basename(const char *path)
+basename(char *path)
 {
        static char bname[PATH_MAX];
        size_t len;
Index: lib/libc/gen/dirname.3
===================================================================
RCS file: /cvs/src/lib/libc/gen/dirname.3,v
retrieving revision 1.23
diff -u -p -r1.23 dirname.3
--- lib/libc/gen/dirname.3      8 Mar 2019 17:33:23 -0000       1.23
+++ lib/libc/gen/dirname.3      11 Sep 2020 20:47:08 -0000
@@ -23,7 +23,7 @@
 .Sh SYNOPSIS
 .In libgen.h
 .Ft char *
-.Fn dirname "const char *path"
+.Fn dirname "char *path"
 .Sh DESCRIPTION
 The
 .Fn dirname
Index: lib/libc/gen/dirname.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/dirname.c,v
retrieving revision 1.16
diff -u -p -r1.16 dirname.c
--- lib/libc/gen/dirname.c      25 Jan 2019 00:19:25 -0000      1.16
+++ lib/libc/gen/dirname.c      11 Sep 2020 20:43:34 -0000
@@ -24,7 +24,7 @@
 /* A slightly modified copy of this file exists in libexec/ld.so */
 
 char *
-dirname(const char *path)
+dirname(char *path)
 {
        static char dname[PATH_MAX];
        size_t len;
-- 
Christian "naddy" Weisgerber                          [email protected]

Reply via email to