When I search the web for information about the origin of UNIX symbolic links, I see "Symbolic links were first introduced into Unix with 4.1c-BSD". But when I go to fact check that, it doesn't appear to be true. What I see instead is that Dennis Ritchie modified nami.c on Eighth Edition research UNIX (A.K.A "version 8" or just "v8") and his modifications to nami.c were added to "4.1BSD".

I put "4.1BSD" in quotes because the CSRG appears to have put more work into release engineering after they won their DARPA contract. After winning the contract they started adding "point release versions", e.g. 4.1a, 4.1b and 4.1c. Before that they just cut release tapes from a "staging" file system that received updates instead of a master tape, which resulted in "4.1BSD du jour". See Mike Haertel's reconstruction of the September 1, 1981 release of 4.1BSD for details about this.

The presence or absence of symlinks in BSD can be determined by the number of arguments that the nami() function has. A third argument was added to nami() that indicates path name traversal is following a symlink, nami(func, flags) vs. nami(func, flags, follow)

SCCS version control updates certain tokens by replacing them with the version number and date of the check-in to the SCCS file. The tokens are added to comments in the source code files so the version of the file can be identified that way. The CSRG ISO is the one sold by Marshall Kirk McKusick. I use md5 hashes to show that the content matches.

4.0BSD (CSRG ISO) Nov 9, 1980 4.0/usr/src/sys/sys/nami.c does not have symbolic links
       /*      nami.c  4.2     11/9/80 */
       978150343fb19f4cac166487bc576144  4.0/usr/src/sys/sys/nami.c

4.1BSD reconstructed September 1, 1981 does not have symbolic links
       /*      nami.c  4.5     81/03/09        */
       1ba9cdcbaed3a418aa62b1212425ec40  nami.c

4.1BSD (4.1.snap from CSRG ISO) May 17, 1981 4.1.snap/sys/sys/nami.c does not have symbolic links
       /*      nami.c  4.5     81/03/09        */
       1ba9cdcbaed3a418aa62b1212425ec40  4.1.snap/sys/sys/nami.c

       /*      nami.c  4.5     81/03/09        */
       1ba9cdcbaed3a418aa62b1212425ec40  nami.c

At some point in the 4.1BSD series, file and directory names were reorganized. nami.c became ufs_nami.c. The limitations of SCCS version control do not allow changes to file names to be seen.

Eight Edition UNIX (no official release, not everything has SCCS IDs) has symlinks usr/sys/sys/nami.c; it is a hybrid of having both symlinks and the old name "nami.c", pre "ufs_nami.c". I doubt that Bell Labs would undo the large number of file and directory name changes in 4.1c. I don't have the source code to the 4.1c kernel, it isn't on the CSRG ISO.

I checked three different V8 archives:

The first two appear to be identical, while the third one has the same source code as the other two, only the kernel has been configured for a VAX/11-750 instead of a VAX/11-780.

The CSRG ISO has an SCCS repository file: 4.1c.1/sys/sys/SCCS/s.ufs_nami.c In that file the first commit that contains symlinks: nami(func, flags, follow) is version 4.9. The commit comment says: dmr's nami. "dmr" are Dennis Ritchie's initials and his UNIX account name was always "dmr".

D 4.9 82/02/26 16:43:04 wnj 13 12       00190/00141/00089
dmr's nami

The contents of the commit:

$ sccsdiff -u -r 4.9 -r 4.10 s.ufs_nami.c
------- ufs_nami.c -------
--- /tmp/geta852    1981-11-08 16:55:52.529794597 -0500
+++ /tmp/getb852    1982-02-26 16:43:04.533404771 -0500
@@ -11,7 +11,7 @@ 
  * Convert a pathname into a pointer to
- * an inode. Note that the inode is locked.
+ * a locked inode.
  * func = function called to get next char of name
  * &uchar if name is in user space
@@ -19,190 +19,221 @@
  * flag = 0 if name is sought
  * 1 if name is to be created
  * 2 if name is to be deleted
+ * follow = 1 if links are to be followed at the end of the name
 struct inode *
-namei(func, flag)
-   int (*func)();
+namei(func, flag, follow)
+   int (*func)(), flag, follow;
[...truncated for brevity...]

The next commit, less than 24 hours later contains (mostly additional) code, which is not in the V8 nami.c, to deal with some aspects of parent directories, etc.

D 4.10 82/02/27 14:54:34 wnj 14 13      00013/00006/00273
symbolic links

I doubt Dennis Ritchie would have removed that code from V8. In 1987 he wrote a reply to a thread on USNET about symbolic link parent directory handling. ...the BSD and V8 conventions for dealing with symbolic links are well-chosen....

Subsequent BSD versions on the CSRG ISO show that by 4.1c an additional 26 commits occurred from February 27, 1982 to February 10, 1983. This casts doubt on the statements that symlinks were first in 4.1cBSD instead of an earlier version.

4.1c.1BSD CSRG ISO - file modification timestamp May 16, 1983 - 4.1c.1/sys/sys/ufs_nami.c
       /*      ufs_nami.c      4.35    83/02/10        */
       451cb3ea57422cf356d48c853cb2321d  ufs_nami.c

4.1c.2BSD CSRG ISO - file modification timestamp Feb 10, 1983 - 4.1c.2/a/sys/sys/ufs_nami.c
       /*      ufs_nami.c      4.35    83/02/10        */
       451cb3ea57422cf356d48c853cb2321d  ufs_nami.c

Is anyone able to add anything more to this? I welcome any rebuttals, more supporting evidence, etc.

  • 6
    That same usenet thread contains at least a couple of threads giving Dennis the credit: e.g. I should perhaps report that Dennis Ritchie implemented symlinks first, but doesn't take sole credit for the idea, which came up in a group discussion at Berkeley. (post by 'gw...' at Jun 14, 1987, 12:00:11 AM) Mar 9 at 23:08
  • Yes, I have observed a lot of evidence that code and ideas were shared between Bell Labs and UCB CSRG. Here's a 1988 UCB CSRG paper on XUNET which connected UCB and Bell Labs. It mentions a VAX750 at UCB named Monet and the kernel configuration file VM.snapshot.2/vax/conf/conf.old/MONET on the CSRG ISO contains Datakit options. digitalassets.lib.berkeley.edu/techreports/ucb/text/… Mar 10 at 16:15
  • @AcceptableName Ken Thompson was a UCB alum and went back there on sabbatical in 1975-76; it was he who installed V6 there ;-). Mar 10 at 16:21
  • 1
    If you look at UNIX family trees they (pretty much?) all show one line from 4.1BSD to Eighth Edition while there should be lines back-and-forth between them. It's not even clear which BSD version Eighth Edition was derived from. Bell Labs might have started with 32/V or some 4.1BSD and merged code from BSD into it while exporting code that was merged into BSD. Rob Pike wrote about it, indicating that the origins of the select(2) system call appear to be a shared idea. inbox.vuxu.org/tuhs/… Mar 10 at 16:35

2 Answers 2


Looking at the user side of things, ln didn’t support symlinks in V7, and did in V8, which confirms that V8 supported symlinks. The V7 man page is actually incomplete — V7 ln supports a -f flag — but its source code confirms that it doesn’t support symlinks.

  • It is interesting to see that ln -f predates ln -sf but I think even hard links could benefit from having an option to forcibly remove the target prior to making a new hard link. It would be interesting to see if there are any scripts or makefiles that use ln -f on V7 or 32/V. Mar 10 at 13:28
  • 2
    @AcceptableName in V7, -f is required if the link targets a directory; its meaning has changed since then. Mar 10 at 13:40
  • 2
    I went and checked on 32/V (which is "V7 on a VAX"). The -f flag does not appear on the usage line: Usage: ln target [ newname ] and the ln(1) man page not only omits -f it states It is forbidden to link to a directory. The -f option is in the source /usr/src/cmd/ln.c and it appears to allow ln -f dir1 dir2 where dir2 does not already exist. That creates the "not a tree" case in the file system since path name traversal can go back towards the root directory instead of only away from it. It's what you said but using my own wording. Mar 10 at 16:05

I have the impression symbolic links were a standard feature of operating systems developed at MIT: e.g. CTSS, Multics, ITS, MagicSix. Since BSD received some other MIT technology (e.g. job control), I wonder if symbolic links come through that path as well?

The Wikipedia page about symbolic links is not very strong on the history, but there is some more detailed information here: https://gunkies.org/wiki/Symbolic_link Frankston's 1984 comment is especially interesting.

  • 1
    Confirmed for Multics in A General-Purpose File System For Secondary Storage (Daley, Neumann, 1965) (3rd paragraph in section 2.1 - "Basic Concepts") - I knew about multiple names for entries - that's the basis of having multiple entry points to libraries for the system linker - but I didn't remember about symbolic links.
    – davidbak
    2 days ago
  • Probably worth quoting Frankston rather than just linking to that page ("answer in another castle"). Probably best to include the original source (the Amber write-up). That would make this answer self-complete and worthy of an upvote from me. yesterday
  • Guess I didn't word my question in a way that suffiently guarded against conceptual origins. yesterday

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.