mv's copies of cp.c and rm.c were imported about 10 months ago so that mv can avoid the fork+exec; instead, mv just calls the relevant cp/rm code itself.
What was the motivation for that? Was that a step needed to have a stricter pledge() for mv (no forking and execing)? Currently, mv does not make a pledge. Would it make sense to pledge what cp+rm does (diff below)? Or is having the embedded copies beneficial in itself, even without the pledge? It saves a fork+exec, but we have duplicit code now: while the imported copies of cp.c and rm.c were streamlined a bit over the time (usage, locale, unused flags), the actual fts traversal and the copying/unlinking needs to be there, obviously. Jan Index: mv.c =================================================================== RCS file: /cvs/src/bin/mv/mv.c,v retrieving revision 1.43 diff -u -p -r1.43 mv.c --- mv.c 17 Nov 2015 18:34:00 -0000 1.43 +++ mv.c 11 Oct 2016 06:46:19 -0000 @@ -92,6 +92,9 @@ main(int argc, char *argv[]) if (argc < 2) usage(); + if (pledge("stdio rpath wpath cpath fattr getpw", NULL) == -1) + err(1, "pledge"); + stdin_ok = isatty(STDIN_FILENO); /*