The openpartition function in tunefs(8) will currently set devicep, a char** passed in from main, to the path it attempted to opendev(3). This doesn't actually work as intended; it should be setting the value devicep points to instead of devicep itself.
Also, section 6.9.1 clause 9 of C99[0] says that "each parameter has automatic storage duration", so I think it's not safe to rely on a function parameter still being a valid object outside of openpartition (please correct me if I'm wrong on that). The diff below addresses both of these issues, and while here, also cleans up some path-wrangling baggage dating from prior to opendev(3). [0] http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf Index: tunefs.c =================================================================== RCS file: /cvs/src/sbin/tunefs/tunefs.c,v retrieving revision 1.37 diff -u -p -r1.37 tunefs.c --- tunefs.c 7 Feb 2015 02:09:14 -0000 1.37 +++ tunefs.c 23 Aug 2015 09:11:58 -0000 @@ -309,21 +309,22 @@ bread(daddr_t blk, char *buffer, int cnt static int openpartition(char *name, int flags, char **devicep) { - char rawspec[PATH_MAX], *p; + static char realname[PATH_MAX]; + char *p; struct fstab *fs; int fd; fs = getfsfile(name); if (fs) { - if ((p = strrchr(fs->fs_spec, '/')) != NULL) { - snprintf(rawspec, sizeof(rawspec), "%.*s/r%s", - (int)(p - fs->fs_spec), fs->fs_spec, p + 1); - name = rawspec; - } else - name = fs->fs_spec; + name = fs->fs_spec; + if ((p = strrchr(name, '/')) != NULL) + name = p + 1; } fd = opendev(name, flags, 0, devicep); - if (fd == -1 && errno == ENOENT) - devicep = &name; + if (fd == -1 && errno == ENOENT) { + /* Only used in err(3), truncation is ok. */ + (void)strlcpy(realname, name, sizeof(realname)); + *devicep = realname; + } return (fd); }
