© Loren Heal 2003, 2004.
| Linux History | The DMCA | The claimed files | Header files Table | USL v BSDI |
(The views expressed in this document may or may not reflect the views of the site hosting it. Distributed under the Creative Commons License. Permission is granted to distribute this document in whole or in part, as long as this URL is provided or linked: http://healconsulting.com/SCO/sco-letter.html. Please post any suggestions, requests for attribution, or other comments on the site where you saw it linked. Seek competent legal advice before acting on anything you read online.)
The following is a commentary on the letter of December 19, 2003, from Ryan E. Tibbitts, General Counsel for The SCO Group, Inc. ("SCO"). In the letter, sent to UNIX® licensees, he claims that portions of 65 Linux source code files were "copied verbatim" from SCO's version of Unix. SCO also claims that some application binary interfaces are their proprietary products. The claims SCO makes in the letter are false, misleading, and utterly without merit.
I am not a lawyer, but I know right from wrong. This commentary is intended to consolidate and clarify the response by software specialists so that those in the legal community can have a more constructive discourse. The SCO letter lacks the specificity needed for a quick rebuttal, so this commentary will be much longer than would rationally be necessary. A goal and obstacle we shall face throughout is the search for claims: we have to decipher exactly what it is that SCO says infringes on its rights.
The structure of this commentary more or less follows the SCO letter's structure. We'll first delve into the introductory portion of the letter, explaining some of the more confusing parts as a warm up exercise to motivate the methods used to analyze SCO's claims. We will then comment in some detail on each of the files SCO claims infringe, and then follow the letter to its conclusion. Along the way we will see some examples of the allegedly infringing files and examples of those files from other Unix-like operating systems. None of the code shown is complex, so please look it over.
Let's examine the SCO letter in detail. (Sections in blockquoted italics are quoted from the letter unless otherwise explained.)
Dear Unix Licensee,
In May 2003, SCO warned about enterprise use of the Linux operating system in violation of its intellectual property rights in UNIX technology.
Referring to an earlier letter on the subject, the introduction includes the phrase "intellectual property rights". One of SCO's tactics is to use the phrase "intellectual property" or "IP" without specifying (or incorrectly claiming) copyright, patent, trade secret, trademark, or contractual rights. By doing so they generate confusion between the various forms of intellectual property. The December 19 letter suffers from that flaw, so we will need to clarify the meaning whenever the IP Flaw emerges. In this case, "rights in UNIX" specifies neither which rights nor which version of UNIX is meant.
Without exhausting or explaining all potential claims, this letter addresses one specific area in which certain versions of Linux violate SCO's rights in UNIX.
He begins by asserting that this particular letter may not be the last. After compliance with this one, or if this one is proved meritless, there may be others. He doesn't limit his claims only to one version of Linux. He explicitly doesn't specify what type of IP rights he will assert in future letters. Note the repeated IP Flaw.
In this letter we are identifying a portion of our copyright protected code that has been incorporated into Linux without our authorization. Also, our copyright management information has been removed from these files.
SCO may or may not own any copyright to UNIX System V or the other versions of UNIX. SCO's claim to the UNIX copyrights comes from their purchase of certain UNIX licensing business from Novell. On October 14, 2003, Novell registered conflicting copyrights to UNIX System V. That fact may serve to obviate any SCO claim to Linux copyrights, but this commentary will try to discourage any owner of UNIX System V copyrights from asserting rights to Linux as well. Until the copyright dispute is resolved, any suits involving UNIX copyrights may simply be set aside or delayed. Again, I'm not a lawyer.
Alleging that some code has been incorporated into Linux leads one to ask how he knows that it hasn't always been there. That is, where did Linux come from?
When AT&T made tighter restrictions on UNIX Version 7 than were on Version 6, it caused problems for those teaching about Unix and operating systems. The University of California at Berkeley (UCB) was working closely with AT&T on Unix, but their work was at the time more encumbered in various ways than it is now.
Professor Andrew S. Tanenbaum had been teaching about Unix from the source code of Version 6. Tanenbaum wrote Minix® without using any UNIX code. The entire source code for Minix was published in the classic book Operating Systems: Design and Implementation ("OSDI") (Andrew S. Tanenbaum, Prentice-Hall, 1987), but with some awkward copyright restrictions on its use. Torvalds and many Linux contributors learned about operating system design from Minix, and it could be expected that early Linux code would resemble that of Minix, though Minix code was not actually used in Linux. Torvalds created Linux in part to make an operating system that would be free of awkward copyright restrictions.
The details are very well documented; see for example this Linux history page. Furthermore, every version of Linux, from 0.01 to the present, is available online.
With respect to what SCO calls its "copyright protected code", it is clear from the foregoing discussion of Linux' origins that there are many sources of Unix code. Nevertheless, SCO alleges that the code itself, not merely the ideas it expresses, has been used without permission. He also implies that it was a deliberate misuse, since the code was copied and then comments containing the copyright notice removed.
Alleging that "copyright management information has been removed" is necessary to bring the DMCA to bear, as he attempts in his next paragraph. However, something obviously can't be removed if it isn't first there. Therefore, (in the search for claims) he must be alleging that entire SCO files were copied, then perhaps slightly altered, stripped of copyright notices, and used in Linux.
Except for copyright notices embedded in online documentation, error messages, or other output of a program, copyright notices are put in comments at the top of the source code for a program. The comments are designed to be blatantly obvious for a human reading the source code but are totally ignored by the compiler that is run to generate an executable program from that source code. The commented copyright notices must be the ones he is alleging were removed. As noted, the commented copyright notices will never appear in any binary translation. He is alleging that it was the source code which was copied, and not binary (object) code.
These facts support our position that the use of the Linux operating system in a commercial setting violates our rights under the United States Copyright Act, including the Digital Millennium Copyright Act. We are notifying you of these facts so you can take steps to discontinue these violations. We believe these violations are serious, and we will take appropriate actions to protect our rights. No one may use our copyrighted code except as authorized by us. The details of our position are set forth below. Once you have reviewed our position, we will be happy to further discuss your options and work with you to remedy this problem.
Why does SCO object to the use of Linux "in a commercial setting"? Why not everywhere?
The Digital Millennium Copyright Act ("DMCA") was enacted to implement the WIPO Treaty. It prohibits improper circumvention of copy protection and the alteration of copyright information (§ 1202). It also provides controversial methods for copyright owners to have infringing material taken offline, the "takedown" mechanism. In 1997, while the DMCA was being formed, the The Register of Copyrights said this to the Committee on the Judiciary Subcommittee on Courts and Intellectual Property:
The provisions in section 1202 do not apply to those who act innocently. The acts covered all must have been performed knowingly. In addition, the provision of false information is only unlawful where it is done "with the intent to induce, enable, facilitate, or conceal infringement." Liability for the removal or alteration of information requires the actor to know or have reason to know that his acts "will induce, enable, facilitate or conceal" infringement.
Clearly, someone simply using a copy of Linux downloaded from a web site or purchased commercially has no liability under the DMCA.
The same document makes clear that the Copyright Office searched the existing laws to see if they applied to alteration of copyright management information. They found that existing laws had a loophole around the management information itself. With that in mind, § 1202 makes more sense, and it explains why § 1202 covers only the removal or alteration of copyright notices, not the mere creation of an infringing work (since the existing law covered that already). In particular, 17 U.S.C. § 1202 refers only to works in which the copyright management information has been removed, not to workalike products:
Sec. 1202. Integrity of copyright management information -STATUTE- (a) False Copyright Management Information. - No person shall knowingly and with the intent to induce, enable, facilitate, or conceal infringement - (1) provide copyright management information that is false, or (2) distribute or import for distribution copyright management information that is false. (b) Removal or Alteration of Copyright Management Information. - No person shall, without the authority of the copyright owner or the law - (1) intentionally remove or alter any copyright management information, (2) distribute or import for distribution copyright management information knowing that the copyright management information has been removed or altered without authority of the copyright owner or the law, or (3) distribute, import for distribution, or publicly perform works, copies of works, or phonorecords, knowing that copyright management information has been removed or altered without authority of the copyright owner or the law, knowing, or, with respect to civil remedies under section 1203, having reasonable grounds to know, that it will induce, enable, facilitate, or conceal an infringement of any right under this title.
The DMCA doesn't apply in this instance.
Now for the heart of the letter:
Certain copyrighted application binary interfaces ("ABI Code") have been copied verbatim from our copyrighted UNIX code base and contributed to Linux for distribution under the General Public License ("GPL") without proper authorization and without copyright attribution. While some application programming interfaces ("API Code") have been made available over the years through POSIX and other open standards, the UNIX ABI Code has only been made available under copyright restrictions. AT&T made these binary interfaces available in order to support application development to UNIX operating systems and to assist UNIX licensees in the development process. The UNIX ABIs were never intended or authorized for unrestricted use or distribution under the GPL in Linux. As the copyright holder, SCO has never granted such permission. Nevertheless, many of the ABIs contained in Linux, and improperly distributed under the GPL, are direct copies of our UNIX copyrighted software code.
This paragraph attempts to draw a distinction between API and ABI code. The actual difference is rather subtle, and may or may not have any legal meaning, or give SCO a basis to argue if it does have a legal meaning. It is commonly held that neither ABIs nor APIs are copyrightable in that they are mechanisms and concepts, but strangely SCO disagrees.
What is even stranger is that Caldera (now called the SCO Group) employee Christoph Hellwig announced the release of the Linux-ABI for SVR4 and other SCO Unixes on 18 Nov 2001. See the release anouncement. The Linux-ABI documentation provides some nice tables with the information SCO is now apparently claiming was "never intended or authorized for unrestricted use or distribution under the GPL in Linux".
An API is a specification in a given programming language of functions, procedures, and other standard operations that a programmer can use to call on the services provided. An ABI, on the other hand, is a specification for a given computing environment of function addresses, function call mechanisms, actual values, and instruction sequences that a programmer can assume will be present when the program is run.
An ABI is made to specify the way programs made for one environment can run in another. It can include or reference APIs, but it does so within the limited scope of the target architecture and function call mechanism.
In short, an API is about uncompiled source code compatibility, while an ABI is about compiled binary compatibility.
SCO (The Santa Cruz Operation) collaborated with a number of entities in the establishment of extensions of the System V ABI for the IA64 architecture. The most recent revision of the documentation of which is available from Intel (pdf).
Section 1.1 of the document not only makes clear that SCO knew of and affirmed of The Open Group's policies relative to the exact "IP" that they place at issue, but that the members of the defining group for the IA64 ABI extensions they now claim as their own included Cygnus Systems and VA Linux.
The "scope, audience and purpose" of the Single UNIX Specification, IEEE Std. 1003.1 and correlatively ISO/IEC 9945:2003 are documented and explained in this background piece from The Open Group.
The use of the loaded phrase "copied verbatim" distinguishes the alleged copying from any other kind of copying, and indicates complete, word for word copying. Verbatim copying connotes copying an entire file, or an entire functional piece of one, with cut-and-paste operations or by loading the copyrighted work into a text editor.
The only way it makes sense to say that an ABI was "copied verbatim" is if the source code used to create it were copied verbatim from somewhere. The above listed Linux-ABI is a patch to the Linux Kernel to make it use the SCO UNIX ABIs (so that programs compiled for SCO UNIX would run under Linux). If the System V ABIs were "copied verbatim" into Linux, then Caldera/SCO would not have to create a patch to make them compatible.
It will become apparent to the reader that verbatim copying did not occur. We must therefore assume an oxymoronic use of the phrase "copied verbatim": copying certain pieces of code but not others. It isn't reasonable to label that kind of copying "verbatim", but prudence and charity compell us to see if even piecewise copying occurred.
While closely examining all of the files SCO listed in the letter, I put each one through the following tests or filters:
There is not much in the claimed files that remains open to claim by SCO, and even that doesn't suggest that it is theirs. In fact, I found no type definition, function call mechanism, or file structure detail that pass the above filters. The only things left in most cases are the values for certain standard constants.
The files with names ending in ".h" are "header" files that contain shorthand definitions to be used in common among other source files that need those definitions. Different architectures require slightly different header files, often to maintain compatibility with a vendor Unix implementation.
The ".h" files are accessed with the statement
#include <filename.h>The C compiler inserts the lines from filename.h in place of the "#include" line. The header files can have complex dependency structures. We shall see, for example, that the dependency structure for Linux ioctl.h is unlike that of BSD or System V.
Many of the files listed comply with the published POSIX standard. These files must be present in a POSIX-compliant system, and must contain certain elements. The elements in a header file are typically:
While SCO listed 65 files listed in the December 19 letter, that number is inflated by listing 9 files and a bunch of architecture-dependent duplicates. I examined each file to make sure that was the case, and categorize them below.
Mr. Tibbitts lists files some of which he claims contain a piece or pieces of code that was or were "copied verbatim". The scope of the copying is not specified, so in our search for claims we have to figure out how much of each Linux file could have come from some unnamed SCO Unix file.
Any part of any Linux file that includes the copyrighted binary interface code must be removed. Files in Linux version 2.4.21 and other versions that incorporate the copyrighted binary interfaces include:
Here is a table listing the files to which SCO is actually laying claim, followed by a discussion of each. The files marked with a "V7" were published in 1978 in UNIX Version 7, without any copyright notices. Similarly, a link is provided for each of the following Unix versions, if the file appeared in that version:
Please note that while some of these versions (such as AIX, Quick C, and Solaris) are proprietary products, inclusion of them here is important to the analysis. As such, the "fair use" doctrine [1] of copyright law allows their inclusion here.
Navigation note: click the filename at the top of each column to go the the detailed description for that class of files. Click the entry in the first column for all the files from that operating system. Click an individual table entry to see that file.
| System | a.out.h | acct.h | ctype.c | ctype.h | ecoff.h | errno.h | ioctl.h | ipc.h | signal.h | stat.h | |
| Docs | Tru64 | Linux | Linux | POSIX | Tru64 | POSIX 2 | POSIX | POSIX | POSIX | POSIX | |
| V7 | V7 | V7 | V7 | V7 | (tty.h) | V7 | V7 | ||||
| 32V | 32V | 32V | 32V | 32V | (tty.h) | 32V | 32V | ||||
| 3BSD | 3BSD | 3BSD | 3BSD | 3BSD | 3BSD | 3BSD | 3BSD | ||||
| SysIII | SysIII | SysIII | SysIII | SysIII | SysIII | SysIII | SysIII | ||||
| Minix 1.1 | inc | inc | inc | inc | |||||||
| SunOS4 | exec.h | S4 | S4 | S4 | S4 | S4 | S4 | S4 | S4 | ||
| Quick C | QC | QC | QC | QC | |||||||
| Solaris 1.1.2 | S1 | S1 | SysV | S1 | S1 | S1 | S1 | S1 | S1 | S1 | |
| Net2 | Net2 | Net2 | Net2 | Net2 | Net2 | Net2 | Net2 | Net2 | |||
| AIX | AIX | AIX | AIX | AIX | AIX | AIX | AIX | ||||
| Co4.2 | Co | Co | Co | Co | Co | Co | Co | Co | Co | ||
| AIX43 | AIX4 | AIX4 | AIX4 | xcoff.h | AIX4 | AIX4 | AIX4 | AIX4 | AIX4 | ||
| SCO OS | SCO | SCO | fh s.h | SCO | SCO | ||||||
| Plan9 | P9 | P9 | P9 | P9 | |||||||
| ABI | map | ABI | ABI | ABI | |||||||
| 20 | 20 | 20 | 20 | 20 | 20 | 20 | 20 | 20 | 20 | 20 | |
| 21 | 21 | 21 | 21 | 21 | 21 | 21 | 21 | 21 | |||
| 22 | 22 | 22 | 22 | 22 | 22 | 22 | 22 | 22 | |||
| Sol9 | exec.h | S9 | S9 | exechdr.h | S9 | S9 | S9 | S9 | S9 | ||
"Errno.h" lists human-readable labels for the various error numbers in a POSIX operating system. The list is generally sorted numerically by error value, with a comment for each error number. The comments are generally taken from the POSIX description for the error.
This file does not infringe on any SCO copyrights for at least six (6) distinct reasons. Against the specific charge of verbatim copying, Linus Torvalds points to the publicly available history of the Linux errno.h, and that it differs significantly from other Unix implementations (original article).
I have a very strong memory of having written the original "errno.h" myself too, and I really think that at least the i386 version of errno.h actually has different numbers from "real UNIX". Some of the first ones match, but not the rest. That one I explain by just having a list of error codes, and just giving numbers in order, but maybe I'm wrong.
I have this distinct memory of figuring out only later that I _should_ have made the numbers be the same, so that I could have been binary compatible. After all, I do actually have the book "Intel386 Family Binary Compatibility Specification 2" (copyright Intel corporation, btw, not SCO, and it lists the error numbers right there. They are different from what Linux uses on x86.
Other architectures fixed that mistake, but the point is that the history of "errno.h" is definitely _not_ from UNIX sources.
Linus
Later, after some research, Linus used the files available in 1992 to recreate errno.h as it appeared in its current Linux form.
Other reasons this code does not infringe are:
The Linux kernel source tree contains several copies of "errno.h", each of which differs only slightly from the others. That very fact highlights the contradiction in SCO's claim: the files differ from each other; how could they all have been "copied verbatim" from the same source?
The file name "errno.h" and the labels for the various values are industry-wide C language and POSIX standards that come not from a particular Unix vendor but from the ISO and IEEE, as referenced in IEEE Std 1003.1, 2003 Edition, the System Interfaces Volume, Section 2.3, Error Numbers. It is also given in this document by The Open Group as part of the POSIX standard. SCO applied for and received Unixware 7.1 POSIX certification, indicating SCO's acceptance of the POSIX standard.
The error numbers themselves appear printed in the UNIX Programmer's Reference Manual (PRM) 4.3 BSD Virtual VAX-11 Version, April, 1986. © The Regents of the University of California at Berkeley and /or Bell Telephone Laboratories, 1979-1986. While no permission is given to copy the text of this copyrighted work, the facts and ideas contained in it are available to anyone. The numbers are also printed in the Sun intro(2) manual page. The Linux-ABI Error Number Map was also made available by Caldera, and shows the error numbers for a number of Unix types.
A programmer attempting to conform to the standard could easily produce an errno.h with exactly the same contents. In fact, a programmer attempting to produce a different errno.h from those below would need uniqueness as a primary goal. That effort would endanger proper function.
Note that while the first 34 or so error codes are similar or the same in the versions listed here, after that they completely diverge.
Here is the top of <sys/errno.h> file from Solaris® (a licensed System V version), then from Linux 2.4.20, then from Cygwin (a free Unix environment for Microsoft Windows). Last, but not least, is the <errno.h> from UNIX Version 7 (from 1979). Note how simple and uncreative the code is:
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ /* * PROPRIETARY NOTICE (Combined) * * This source code is unpublished proprietary information * constituting, or derived under license from AT&T's Unix(r) System V. * In addition, portions of such source code were derived from Berkeley * 4.3 BSD under license from the Regents of the University of * California. * * * * Copyright Notice * * Notice of copyright on this source code product does not indicate * publication. * * (c) 1986-2000 Sun Microsystems, Inc. * (c) 1983,1984,1985,1986,1987,1988,1989 AT&T. * All rights reserved. */ [ some Solaris-specific code, redacted for brevity] /* * Error codes */ #define EPERM 1 /* Not super-user */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* interrupted system call */ #define EIO 5 /* I/O error */ [... skipping to error 34 ...] #define ERANGE 34 /* Math result not representable */ #define ENOMSG 35 /* No message of desired type */ #define EIDRM 36 /* Identifier removed */ #define ECHRNG 37 /* Channel number out of range */ #define EL2NSYNC 38 /* Level 2 not synchronized */ #define EL3HLT 39 /* Level 3 halted */ #define EL3RST 40 /* Level 3 reset */ #define ELNRNG 41 /* Link number out of range */ #define EUNATCH 42 /* Protocol driver not attached */ #define ENOCSI 43 /* No CSI structure available */ #define EL2HLT 44 /* Level 2 halted */ #define EDEADLK 45 /* Deadlock condition. */ #define ENOLCK 46 /* No record locks available. */ #define ECANCELED 47 /* Operation canceled */ #define ENOTSUP 48 /* Operation not supported */ /* Filesystem Quotas */ #define EDQUOT 49 /* Disc quota exceeded */ [...]
Selecting the correct version of errno.h for the target architecture eventually leads to:
#define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ [... skipping to error 34 ...] #define ERANGE 34 /* Math result not representable */ #define EDEADLK 35 /* Resource deadlock would occur */ #define ENAMETOOLONG 36 /* File name too long */ #define ENOLCK 37 /* No record locks available */ #define ENOSYS 38 /* Function not implemented */ #define ENOTEMPTY 39 /* Directory not empty */ #define ELOOP 40 /* Too many symbolic links encountered */ #define EWOULDBLOCK EAGAIN /* Operation would block */ #define ENOMSG 42 /* No message of desired type */ #define EIDRM 43 /* Identifier removed */ #define ECHRNG 44 /* Channel number out of range */ #define EL2NSYNC 45 /* Level 2 not synchronized */ #define EL3HLT 46 /* Level 3 halted */ #define EL3RST 47 /* Level 3 reset */ #define ELNRNG 48 /* Link number out of range */ #define EUNATCH 49 /* Protocol driver not attached */ [...]
[... top has lots of cygwin-specific stuff, no copyright notice ...] #define EPERM 1 /* Not super-user */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ [...]
/* * Error codes */ #define EPERM 1 #define ENOENT 2 #define ESRCH 3 #define EINTR 4 #define EIO 5 #define ENXIO 6 #define E2BIG 7 #define ENOEXEC 8 #define EBADF 9 #define ECHILD 10 #define EAGAIN 11 #define ENOMEM 12 #define EACCES 13 #define EFAULT 14 #define ENOTBLK 15 #define EBUSY 16 #define EEXIST 17 #define EXDEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32 /* math software */ #define EDOM 33 #define ERANGE 34
The portion of Linux errno.h that is most like the modern System V version is only the first 34 entries. That portion of Linux errno.h is different in layout but identical in content to the public domain one from Version 7.
In looking at several implementations of errno.h, I conclude that the similarity of each one to the others arises from conformance to industry standards, not from copying one to another. The Linux versions in particular are different from the UNIX Version 7 and UNIX System V versions.
Signals are another set of values, used to pass messages among processes and the kernel. There is a much smaller range to signal numbers, typically from 1 to 32, and the most common ones are often used numerically. For instance, the "hang up" signal, numeric value 1, has the mnemonic label SIGHUP. Programmers and savvy users use the values HUP and 1 interchangeably. Still, not all of the signal values are as standardized as SIGHUP or SIGKILL. Quoting Linus Torvalds from the Linux Kernel Mailing List public archive:
... while a lot of the standard signals are well documented (ie "SIGKILL is 9"), historically we had lots of confusion (ie I think "real UNIX" has SIGBUS at 10, while Linux didn't originally have any SIGBUS at all, and later put it at 7 which was originally SIGUNUSED.[...]
...most architectures still have SIGBUS at 7 (original Linux value), while alpha, sparc , parisc and mips have it at 10 (to match "real UNIX"). [links added]
What that means is that the signal's number values between Linux and UNIX don't match exactly. Furthermore, UNIX Version 7 contained a signal.h, which was published in 1978 without copyright management information. It is in the public domain, and even if it is not, Caldera gave anyone a license to use it.
#define NSIG 17 #define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt */ #define SIGQUIT 3 /* quit */ #define SIGILL 4 /* illegal instruction (not reset when caught) */ #define SIGTRAP 5 /* trace trap (not reset when caught) */ #define SIGIOT 6 /* IOT instruction */ #define SIGEMT 7 /* EMT instruction */ #define SIGFPE 8 /* floating point exception */ #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGBUS 10 /* bus error */ #define SIGSEGV 11 /* segmentation violation */ #define SIGSYS 12 /* bad argument to system call */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #define SIGTERM 15 /* software termination signal from kill */ int (*signal())(); #define SIG_DFL (int (*)())0 #define SIG_IGN (int (*)())1
The <sys/stat.h> header shall define the structure of the data returned by the functions fstat(), lstat(), and stat(). The stat structure shall contain at least the following members: dev_t st_dev Device ID of device containing file. ino_t st_ino File serial number. mode_t st_mode Mode of file (see below). nlink_t st_nlink Number of hard links to the file. uid_t st_uid User ID of file. gid_t st_gid Group ID of file. [XSI] dev_t st_rdev Device ID (if file is character or block special). off_t st_size For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. [SHM] For a shared memory object, the length in bytes. [TYM] For a typed memory object, the length in bytes. For other file types, the use of this field is unspecified. time_t st_atime Time of last access. time_t st_mtime Time of last data modification. time_t st_ctime Time of last status change. [XSI] blksize_t st_blksize A file system-specific preferred I/O block size for this object. In some file system types, this may vary from file to file. blkcnt_t st_blocks Number of blocks allocated for this object.
I tried to find the closest match I could between part of a System V stat.h and a corresponding part of a Linux stat.h, paying closest attention to the kernel source. The System V and Linux stat.h structures follow much the same ordering of the fields in the stat(2) structure. Note that the Linux version doesn't really match the System V one, looking more like the 1987 Minix version. Both structures follow the same order suggested by POSIX. The Linux stat(2) manual page defines the stat structure as:
struct stat {
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last change */
};
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/*
* Copyright (c) 1998-1999, by Sun Microsystems, Inc.
* All rights reserved.
*/
[...]
/*
* stat structure, used by stat(2) and fstat(2)
*/
#if defined(_KERNEL)
/* Old SVID stat struct (SVR3.x) */
struct o_stat {
o_dev_t st_dev;
o_ino_t st_ino;
o_mode_t st_mode;
o_nlink_t st_nlink;
o_uid_t st_uid;
o_gid_t st_gid;
o_dev_t st_rdev;
off32_t st_size;
time32_t st_atime;
time32_t st_mtime;
time32_t st_ctime;
};
/* Expanded stat structure */
#if defined(_LP64)
struct stat {
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
timestruc_t st_atim;
timestruc_t st_mtim;
timestruc_t st_ctim;
blksize_t st_blksize;
blkcnt_t st_blocks;
char st_fstype[_ST_FSTYPSZ];
};
[...]
struct stat {
short int st_dev;
unsigned short st_ino;
unsigned short st_mode;
short int st_nlink;
short int st_uid;
short int st_gid;
short int st_rdev;
long st_size;
long st_atime;
long st_mtime;
long st_ctime;
};
[...]
(all of the stat.h files are like this one):
[...]
struct __old_kernel_stat {
unsigned short st_dev;
unsigned short st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned long st_size;
unsigned long st_atime;
unsigned long st_mtime;
unsigned long st_ctime;
};
struct stat {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned short __pad2;
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
unsigned long __unused1;
unsigned long st_mtime;
unsigned long __unused2;
unsigned long st_ctime;
unsigned long __unused3;
unsigned long __unused4;
unsigned long __unused5;
};
Stat.h also defines several mnemonics representing values for the values of the type "mode_t", which is an integral type (a C language type that can be treated as an integer). Here are the constant definitions, again from Solaris, Minix, and Linux. Note that the System V version calls the definitions "de facto standards", referring to the fact that both the labels and the values are in common use.
[...] /* de facto standard definitions */ #define S_IFMT 0xF000 /* type of file */ #define S_IAMB 0x1FF /* access mode bits */ #define S_IFIFO 0x1000 /* fifo */ #define S_IFCHR 0x2000 /* character special */ #define S_IFDIR 0x4000 /* directory */ #define S_IFNAM 0x5000 /* XENIX special named file */ #define S_INSEM 0x1 /* XENIX semaphore subtype of IFNAM */ #define S_INSHD 0x2 /* XENIX shared data subtype of IFNAM */ #define S_IFBLK 0x6000 /* block special */ #define S_IFREG 0x8000 /* regular */ #define S_IFLNK 0xA000 /* symbolic link */ #define S_IFSOCK 0xC000 /* socket */ #define S_IFDOOR 0xD000 /* door */ #define S_ISUID 0x800 /* set user id on execution */ #define S_ISGID 0x400 /* set group id on execution */ #define S_ISVTX 0x200 /* save swapped text even after use */ #define S_IREAD 00400 /* read permission, owner */ #define S_IWRITE 00200 /* write permission, owner */ #define S_IEXEC 00100 /* execute/search permission, owner */ #define S_ENFMT S_ISGID /* record locking enforcement flag */ /* the following macros are for POSIX conformance */ #define S_IRWXU 00700 /* read, write, execute: owner */ #define S_IRUSR 00400 /* read permission: owner */ #define S_IWUSR 00200 /* write permission: owner */ #define S_IXUSR 00100 /* execute permission: owner */ #define S_IRWXG 00070 /* read, write, execute: group */ #define S_IRGRP 00040 /* read permission: group */ #define S_IWGRP 00020 /* write permission: group */ #define S_IXGRP 00010 /* execute permission: group */ #define S_IRWXO 00007 /* read, write, execute: other */ #define S_IROTH 00004 /* read permission: other */ #define S_IWOTH 00002 /* write permission: other */ #define S_IXOTH 00001 /* execute permission: other */ #define S_ISFIFO(mode) (((mode)&0xF000) == 0x1000) #define S_ISCHR(mode) (((mode)&0xF000) == 0x2000) #define S_ISDIR(mode) (((mode)&0xF000) == 0x4000) #define S_ISBLK(mode) (((mode)&0xF000) == 0x6000) #define S_ISREG(mode) (((mode)&0xF000) == 0x8000) #define S_ISLNK(mode) (((mode)&0xF000) == 0xa000) #define S_ISSOCK(mode) (((mode)&0xF000) == 0xc000) #define S_ISDOOR(mode) (((mode)&0xF000) == 0xd000) [...]
[...] /* Some common definitions. */ #define S_IFMT 00170000 /* type of file */ #define S_IFDIR 0040000 /* directory */ #define S_IFCHR 0020000 /* character special */ #define S_IFBLK 0060000 /* block special */ #define S_IFREG 0100000 /* regular */ #define S_ISUID 04000 /* set user id on execution */ #define S_ISGID 02000 /* set group id on execution */ #define S_ISVTX 01000 /* save swapped text even after use */ #define S_IREAD 00400 /* read permission, owner */ #define S_IWRITE 00200 /* write permission, owner */ #define S_IEXEC 00100 /* execute/search permission, owner */
[...] #define S_IFMT 00170000 #define S_IFSOCK 0140000 #define S_IFLNK 0120000 #define S_IFREG 0100000 #define S_IFBLK 0060000 #define S_IFDIR 0040000 #define S_IFCHR 0020000 #define S_IFIFO 0010000 #define S_ISUID 0004000 #define S_ISGID 0002000 #define S_ISVTX 0001000 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) #define S_IRWXU 00700 #define S_IRUSR 00400 #define S_IWUSR 00200 #define S_IXUSR 00100 #define S_IRWXG 00070 #define S_IRGRP 00040 #define S_IWGRP 00020 #define S_IXGRP 00010 #define S_IRWXO 00007 #define S_IROTH 00004 #define S_IWOTH 00002 #define S_IXOTH 00001 [...]Note that as with errno.h, these stat.h values are much the same in Linux and System V, though the Solaris version defines more values in this section (under Linux the values may be defined elsewhere). Some are expressed differently (some in octal, some in hexadecimal), but when compiled the octal value "0017000" and the hexadecimal value "0xF000" are both equivalent to decimal 61440.
Note also that the labels are defined by POSIX. The Linux values are in much the same format as the values published in OSDI for Minix. Many of the Linux stat.h values look like they were taken from study of the Minix source code (rather than from System V).
The macro definitions are straightforward and trivial given what the standard says they should do. It looks as if more work has gone into the Linux versions of the macros, but both sets would generate exactly the same binary code if interchanged.
Paraphrasing and condensing the comments of Linux Torvalds on the files
"include/linux/ctype.h" and "lib/ctype.h", some trivial digging in the
public archives of Linux code showed him that those files are actually
there in the original 0.01 distribution of Linux (from September of
1991). He states, with much detail that any programmer could follow,
that:
See also the implementations of :
tableThis file concerns the ioctl() system call and the Linux device control implementation, as defined in POSIX. In UNIX Version 7, the functionality was included in tty.h. The Linux implementation is nothing like that of System V, except that many of the same macro names are used. I should stop there and go on to the next group of files, but here are the laborious details.
ioctl() is a standard system call, implemented for every device on the system, used for device manipulations that don't easily fit into read/write semantics. Terminal settings, many network operations, sound card modes, etc., are defined here.
The POSIX standard mostly just says there should be an ioctl() call, and that STREAMS® should be implemented in ioctl.h. System V STREAMS never gained popularity, since TCP/IP dominance caused standardization around the Berkeley Sockets abstraction instead.
I apologize in advance for the amount of text included here. Since the POSIX and C standards only loosely specify the ioctl() functions, I can't simply say that all of this is covered by POSIX. Further, since SCO did not specify how these files allegedly infringe on their copyrights, I have to provide much more detail in order to show that the files are different. Here are the relevant files. First, here are ioctl.h and ioccom.h from System V:
For our purposes, this file is basically an AT&T copyright notice and the lines
#include <sys/ioccom.h> #include <sys/filio.h> #include <sys/sockio.h>
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ #ifndef _SYS_IOCCOM_H #define _SYS_IOCCOM_H #pragma ident "@(#)ioccom.h 1.14 97/10/22 SMI" /* SVr4.0 1.4 */ /* ioccom.h 1.3 88/02/08 SMI; from UCB ioctl.h 7.1 6/4/86 */ /* * PROPRIETARY NOTICE (Combined) * * This source code is unpublished proprietary information * constituting, or derived under license from AT&T's Unix(r) System V. * In addition, portions of such source code were derived from Berkeley * 4.3 BSD under license from the Regents of the University of * California. * * * * Copyright Notice * * Notice of copyright on this source code product does not indicate * publication. * * (c) 1986,1987,1988,1989 Sun Microsystems, Inc. * (c) 1983,1984,1985,1986,1987,1988,1989 AT&T. * All rights reserved. */ [...] /* * Ioctl's have the command encoded in the lower word, * and the size of any in or out parameters in the upper * word. The high 2 bits of the upper word are used * to encode the in/out status of the parameter; for now * we restrict parameters to at most 255 bytes. */ #define IOCPARM_MASK 0xff /* parameters must be < 256 bytes */ #define IOC_VOID 0x20000000 /* no parameters */ #define IOC_OUT 0x40000000 /* copy out parameters */ #define IOC_IN 0x80000000 /* copy in parameters */ #define IOC_INOUT (IOC_IN|IOC_OUT) /* * The 0x20000000 is so we can distinguish new ioctl's from old. */ #define _IO(x, y) (IOC_VOID|(x<<8)|y) #define _IOR(x, y, t) \ ((int)((uint32_t) \ (IOC_OUT|(((sizeof (t))&IOCPARM_MASK)<<16)|(x<<8)|y))) #define _IORN(x, y, t) ((int)((uint32_t)(IOC_OUT|(((t)&IOCPARM_MASK)<<16)| \ (x<<8)|y))) #define _IOW(x, y, t) \ ((int)((uint32_t)(IOC_IN|(((sizeof (t))&IOCPARM_MASK)<<16)| \ (x<<8)|y))) #define _IOWN(x, y, t) ((int32_t)(uint32_t)(IOC_IN|(((t)&IOCPARM_MASK)<<16)| \ (x<<8)|y)) #define _IOWR(x, y, t) \ ((int)((uint32_t)(IOC_INOUT|(((sizeof (t))&IOCPARM_MASK)<<16)| \ (x<<8)|y))) #define _IOWRN(x, y, t) \ ((int)((uint32_t)(IOC_INOUT|(((t)&IOCPARM_MASK)<<16)| \ (x<<8)|y))) [...]
For our purposes, this file is just a BSD (not AT&T) copyright notice and the lines
#include <sys/dkio.h> #include <sys/filio.h> #include <sys/ioccom.h> #include <sys/sockio.h>
Under BSD and System V, the values for many of the constants and macros are defined in several different files (filio.h contains file labels, sockio.h contains socket I/O labels, etc.). Linux bundles them into ioctls.h. Here is part of a BSD filio.h, to show where the values like originated. Note the copyright:
1 /* $OpenBSD: filio.h,v 1.4 2003/06/02 23:28:21 millert Exp $ */
2 /* $NetBSD: filio.h,v 1.5 1994/06/29 06:44:14 cgd Exp $ */
3
4 /*-
5 * Copyright (c) 1982, 1986, 1990, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
7 * (c) UNIX System Laboratories, Inc.
8 * All or some portions of this file are derived from material licensed
9 * to the University of California by American Telephone and Telegraph
10 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11 * the permission of UNIX System Laboratories, Inc.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)filio.h 8.1 (Berkeley) 3/28/94
38 */
39
40 #ifndef _SYS_FILIO_H_
41 #define _SYS_FILIO_H_
42
43 #include <sys/ioccom.h>
44
45 /* Generic file-descriptor ioctl's. */
46 #define FIOCLEX _IO('f', 1) /* set close on exec on fd */
47 #define FIONCLEX _IO('f', 2) /* remove close on exec */
48 #define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
49 #define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
50 #define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
51 #define FIOSETOWN _IOW('f', 124, int) /* set owner */
52 #define FIOGETOWN _IOR('f', 123, int) /* get owner */
53 #define FIBMAP _IOWR('f', 122, daddr_t) /* get logical block */
54
55 #endif /* !_SYS_FILIO_H_ */
56
1 /* $OpenBSD: ioccom.h,v 1.3 2003/06/02 23:28:21 millert Exp $ */ 2 /* $NetBSD: ioccom.h,v 1.4 1994/10/30 21:49:56 cgd Exp $ */ 3 4 /*- 5 * Copyright (c) 1982, 1986, 1990, 1993, 1994 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)ioccom.h 8.2 (Berkeley) 3/28/94 33 */ 34 35 #ifndef _SYS_IOCCOM_H_ 36 #define _SYS_IOCCOM_H_ 37 38 /* 39 * Ioctl's have the command encoded in the lower word, and the size of 40 * any in or out parameters in the upper word. The high 3 bits of the 41 * upper word are used to encode the in/out status of the parameter. 42 */ 43 #define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ 44 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) 45 #define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16)) 46 #define IOCGROUP(x) (((x) >> 8) & 0xff) 47 48 #define IOCPARM_MAX NBPG /* max size of ioctl args, mult. of NBPG */ 49 /* no parameters */ 50 #define IOC_VOID (unsigned long)0x20000000 51 /* copy parameters out */ 52 #define IOC_OUT (unsigned long)0x40000000 53 /* copy parameters in */ 54 #define IOC_IN (unsigned long)0x80000000 55 /* copy paramters in and out */ 56 #define IOC_INOUT (IOC_IN|IOC_OUT) 57 /* mask for IN/OUT/VOID */ 58 #define IOC_DIRMASK (unsigned long)0xe0000000 59 60 #define _IOC(inout,group,num,len) \ 61 (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) 62 #define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) 63 #define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) 64 #define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) 65 /* this should be _IORW, but stdio got there first */ 66 #define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) 67 68 #endif /* !_SYS_IOCCOM_H_ */ 69
Linux ioctl.h was originally authored by H. Bergman. I contacted Mr. Bergman while preparing this commentary, and this is what he said:
I wrote the initial ioctl.h as part of my tpqic02 tape driver for Linux. It is a long time ago and I am not certain I remember all the details but I needed a few include files to make userlevel programs like 'mt' from the GNU cpio package and GNU 'tar' work. As I remember it, there were no ioctl.h and mtio.h (which uses ioctl.h) at the time, nor was there enough 'kernel infrastructure' for stuff like character devices, IO/IRQ/DMA reservation/allocation. So I had to write them myself and/or wait for Linus to build the necessary infrastructure. I recall that there was a BSD driver, 'wt.c'. in the sources that BSD released to public around that time which provided me with an example tape driver. Needless to say, BSD and Linux are totally different (I suppose Linux was more like Minix than BSD at the time) so my driver and wt.c have little in common, other than being drivers for the same hardware.
/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $ * * linux/ioctl.h for Linux by H.H. Bergman. */ #ifndef _LINUX_IOCTL_H #define _LINUX_IOCTL_H /* ioctl command encoding: 32 bits total, command in lower 16 bits, * size of the parameter structure in the lower 14 bits of the * upper 16 bits. * Encoding the size of the parameter structure in the ioctl request * is useful for catching programs compiled with old versions * and to avoid overwriting user space outside the user buffer area. * The highest 2 bits are reserved for indicating the ``access mode''. * NOTE: This limits the max parameter size to 16kB -1 ! */ #define IOC_VOID 0x00000000 /* param in size field */ #define IOC_IN 0x40000000 /* user --> kernel */ #define IOC_OUT 0x80000000 /* kernel --> user */ #define IOC_INOUT (IOC_IN | IOC_OUT) /* both */ #define IOCSIZE_MASK 0x3fff0000 /* size (max 16k-1 bytes) */ #define IOCSIZE_SHIFT 16 /* how to get the size */ #define IOCCMD_MASK 0x0000ffff /* command code */ #define IOCCMD_SHIFT 0 /* _IO(magic, subcode); size field is zero and the * subcode determines the command. */ #define _IO(c,d) (IOC_VOID | ((c)<<8) | (d)) /* param encoded */ /* _IOXX(magic, subcode, arg_t); where arg_t is the type of the * (last) argument field in the ioctl call, if present. */ #define _IOW(c,d,t) (IOC_IN | ((sizeof(t)<<16) & IOCSIZE_MASK) | \ ((c)<<8) | (d)) #define _IOR(c,d,t) (IOC_OUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \ ((c)<<8) | (d)) /* WR rather than RW to avoid conflict with stdio.h */ #define _IOWR(c,d,t) (IOC_INOUT | ((sizeof(t)<<16) & IOCSIZE_MASK) | \ ((c)<<8) | (d)) #endif /* _LINUX_IOCTL_H */
/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $ * * linux/ioctl.h for Linux by H.H. Bergman. */ #ifndef _ASMI386_IOCTL_H #define _ASMI386_IOCTL_H /* ioctl command encoding: 32 bits total, command in lower 16 bits, * size of the parameter structure in the lower 14 bits of the * upper 16 bits. * Encoding the size of the parameter structure in the ioctl request * is useful for catching programs compiled with old versions * and to avoid overwriting user space outside the user buffer area. * The highest 2 bits are reserved for indicating the ``access mode''. * NOTE: This limits the max parameter size to 16kB -1 ! */ /* * The following is for compatibility across the various Linux * platforms. The i386 ioctl numbering scheme doesn't really enforce * a type field. De facto, however, the top 8 bits of the lower 16 * bits are indeed used as a type field, so we might just as well make * this explicit here. Please be sure to use the decoding macros * below from now on. */ #define _IOC_NRBITS 8 #define _IOC_TYPEBITS 8 #define _IOC_SIZEBITS 14 #define _IOC_DIRBITS 2 #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) #define _IOC_NRSHIFT 0 #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) /* * Direction bits. */ #define _IOC_NONE 0U #define _IOC_WRITE 1U #define _IOC_READ 2U #define _IOC(dir,type,nr,size) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) /* used to create numbers */ #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) #define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) /* used to decode ioctl numbers.. */ #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) #define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) #define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) #define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) /* ...and for the drivers/sound files... */ #define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) #define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) #define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) #define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) #define IOCSIZE_SHIFT (_IOC_SIZESHIFT) #endif /* _ASMI386_IOCTL_H */
Note that Linux uses constant values for these labels, while BSD defines them in terms of macros (that appear to resolve to constant values also).
#ifndef __ARCH_I386_IOCTLS_H__
#define __ARCH_I386_IOCTLS_H__
#include <asm/ioctl.h>
/* 0x54 is just a magic number to make these relatively unique ('T') */
#define TCGETS 0x5401
#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
#define TCSETSW 0x5403
#define TCSETSF 0x5404
#define TCGETA 0x5405
#define TCSETA 0x5406
#define TCSETAW 0x5407
#define TCSETAF 0x5408
#define TCSBRK 0x5409
#define TCXONC 0x540A
#define TCFLSH 0x540B
#define TIOCEXCL 0x540C
#define TIOCNXCL 0x540D
#define TIOCSCTTY 0x540E
#define TIOCGPGRP 0x540F
#define TIOCSPGRP 0x5410
#define TIOCOUTQ 0x5411
#define TIOCSTI 0x5412
#define TIOCGWINSZ 0x5413
#define TIOCSWINSZ 0x5414
#define TIOCMGET 0x5415
#define TIOCMBIS 0x5416
#define TIOCMBIC 0x5417
#define TIOCMSET 0x5418
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
#define FIONREAD 0x541B
#define TIOCINQ FIONREAD
#define TIOCLINUX 0x541C
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
#define TIOCPKT 0x5420
#define FIONBIO 0x5421
#define TIOCNOTTY 0x5422
#define TIOCSETD 0x5423
#define TIOCGETD 0x5424
#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
#define TIOCSBRK 0x5427 /* BSD compatibility */
#define TIOCCBRK 0x5428 /* BSD compatibility */
#define TIOCGSID 0x5429 /* Return the session ID of FD */
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define FIOCLEX 0x5451
#define FIOASYNC 0x5452
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
#define TIOCSERSWILD 0x5455
#define TIOCGLCKTRMIOS 0x5456
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TIOCSERGETLSR 0x5459 /* Get line status register */
#define TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TIOCSERSETMULTI 0x545B /* Set multiport config */
#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
#define FIOQSIZE 0x5460
/* Used for packet mode */
#define TIOCPKT_DATA 0
#define TIOCPKT_FLUSHREAD 1
#define TIOCPKT_FLUSHWRITE 2
#define TIOCPKT_STOP 4
#define TIOCPKT_START 8
#define TIOCPKT_NOSTOP 16
#define TIOCPKT_DOSTOP 32
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
#endif
Under the BSD Unixes, ioctl.h contains a BSD copyright notice, but no mention of AT&T or anyone else. An ioctl.h first appeared in Linux in version 0.99, authored by Hennus Bergman. I've included that version here to show its evolution to Linux 2.4.22. It clearly wasn't copied from System V, since the design of the macros and the dependencies in the include structure are just too different.
While POSIX defines only STREAMS as standard, there are de facto standards for ioctl() function numbers and parameter values. Linux implements many of those in the standard kernel. The iBCS patch (released by Caldera, as mentioned above) provides further ioctl() compatibility.
Since the Linux ioctl.h file was clearly not derived from the System V or BSD versions, no System V or BSD copyright notice appears.
See also the implementations of :
tableIPC stands for Inter-Process Communication. The ipc.h file defines structures and constants needed for two processes to communicate either on the same computer or across a network link.
The two implementations of ipc.h are radically different. Both supply the required POSIX structure definitions, but the structures are defined differently within the confines of the standard.
The layout of the files and the order in which the standard items are defined is so different that "ipc.h" required a different technique than the other files. All of the lines defining constant values were selected, sorted, and then got some hand-editing to remove the lines unique to one version or the other. The individual lines were left as they were.
The following are hand-selected lines from Solaris <sys/ipc.h>
#define IPC_CREAT 0001000 /* create entry if key doesn't exist */ #define IPC_EXCL 0002000 /* fail if key exists */ #define IPC_NOWAIT 0004000 /* error if request must wait */ #define IPC_O_RMID 0 /* remove identifier */ #define IPC_O_SET 1 /* set options */ #define IPC_O_STAT 2 /* get options */ #define IPC_PRIVATE (key_t)0 /* private key */ #define IPC_RMID 10 /* remove identifier */ #define IPC_SET 11 /* set options */ #define IPC_STAT 12 /* get options */
The following are hand-selected lines from Linux <linux/ipc.h>
#define IPC_CREAT 00001000 /* create if key is nonexistent */ #define IPC_EXCL 00002000 /* fail if key exists */ #define IPC_NOWAIT 00004000 /* return error on wait */ #define IPC_RMID 0 /* remove resource */ #define IPC_SET 1 /* set ipc_perm options */ #define IPC_STAT 2 /* get ipc_perm options */ #define IPC_PRIVATE ((__kernel_key_t) 0)
Note that there is some similarity, but that few of the values are actually the same. There is no infringement here.
See also the implementations of :
tableThe acct.h file defines the standard process accounting structures and values. The similarities between Linux and System V are:
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ /* * Copyright (c) 1997, by Sun Microsystems, Inc. * All rights reserved. */ [...] #define AFORK 0001 /* has executed fork, but no exec */ #define ASU 0002 /* used super-user privileges */ #ifdef SUN_SRC_COMPAT #define ACOMPAT 0004 /* used compatibility mode (VAX) */ #define ACORE 0010 /* dumped core */ #define AXSIG 0020 /* killed by a signal */ #endif /* SUN_SRC_COMPAT */ #define AEXPND 0040 /* expanded acct structure */ #define ACCTF 0300 /* record type: 00 = acct */ [...]
/*
* BSD Process Accounting for Linux - Definitions
*
* Author: Marco van Wieringen (mvw@planets.elm.net)
*
* This header file contains the definitions needed to implement
* BSD-style process accounting. The kernel accounting code and all
* user-level programs that try to do something useful with the
* process accounting log must include this file.
*
* Copyright (C) 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
*
*/
[...]
/*
* accounting flags
*/
/* bit set when the process ... */
#define AFORK 0x01 /* ... executed fork, but did not exec */
#define ASU 0x02 /* ... used super-user privileges */
#define ACOMPAT 0x04 /* ... used compatibility mode (VAX only not used) */
#define ACORE 0x08 /* ... dumped core */
#define AXSIG 0x10 /* ... was killed by a signal */
#define AHZ 100
[...]
Reversing their roles from stat.h, here System V uses octal values and Linux uses hexadecimal. Note the comments. This file doesn't infringe.
The files a.out.h, ecoff.h, and exechdr.h are used variously in different versions of Unix. They are part of the implementation of two general types of obsolescent executable files: the original "a.out" format, from ancient UNIX such as Version 7, and the OSF/1 Common Object File Format (COFF) format. Support for them is optional in the Linux kernel build process.
The COFF structures and the values for the constants used in the a.out.h file are listed in this Compaq manual page.
The only things in <linux/a.out.h> or <asm-sparc/a.out.h> that looks like anything in System V are the "magic" constants. and the format for a.out and COFF executables. See the discussion on ecoff.h below:
/* Code indicating object file or impure executable. */ #define OMAGIC 0407 /* Code indicating pure executable. */ #define NMAGIC 0410 /* Code indicating demand-paged executable. */ #define ZMAGIC 0413 /* This indicates a demand-paged executable with the header in the text. The first page is unmapped to help trap NULL pointer references */ #define QMAGIC 0314 /* Code indicating core file. */ #define CMAGIC 0421
#define OMAGIC 0407 /* old impure format */ #define NMAGIC 0410 /* read-only text */ #define ZMAGIC 0413 /* demand load format */
#define OMAGIC 0407 #define NMAGIC 0410 #define ZMAGIC 0413 #define SMAGIC 0411 #define LIBMAGIC 0443
The following table is taken from the Digital UNIX Assembly Language Programmer's Guide (© Digital Equipment Corporation 1996 and possibly © MIPS Computer Systems, Inc. 1990)
| Table 7-5: Optional Header Magic Numbers | ||
| Symbol | Value | Description |
| OMAGIC | 0407 | Impure format The text is not write-protected or shareable; the data segment is contiguous with the text segment. |
| NMAGIC | 0410 | Shared text The data segment starts at the next page following the text segment, and the text segment is writeprotected. |
| ZMAGIC | 0413 | The object file is to be paged in on demand (demand paged) and has a special format; the text and data segments are separated. The Alpha system provides write-protection for the text segment. (Other systems using COFF may not provide write-protection.) The object can be either dynamic or static. |
| See Section 7.3 for information on the format of OMAGIC, NMAGIC, and ZMAGIC files. | ||
It's clear that the labels and values were published by Digital or MIPS to promote binary compatibility. SCO has no claim whatsoever.
Continuing with SCO's letter, we now see Mr. Tibbitts rehashing the allegations from the first part of the letter, as if he's given enough evidence to prove his case:
The code identified above was also part of a settlement agreement between the University of California at Berkeley and Berkeley Systems Development, Inc. (collectively "BSDI") and UNIX Systems Laboratories, Inc. regarding alleged violations by BSDI of USL's rights in UNIX technology. The settlement agreement between USL and BSDI addressed conditions upon which BSDI could continue to distribute its version of UNIX, BSD Lite 4.4, or any successor versions, including certain "UNIX Derived Files" which include the ABI Code. A complete listing of the UNIX Derived Files is attached. The ABI Code identified above is part of the UNIX Derived Files and, as such, must carry USL / SCO copyright notices and may not be used in any GPL distribution, inasmuch as the affirmative consent of the copyright holder has not been obtained, and will not be obtained, for such a distribution under the GPL.
I believe the above paragraph mischaracterizes the settlement agreement between USL and UCB. The agreement was reached in 1995 after the original creation of most of the files. The copyright notice does allow use of the files, but requires a USL copyright notice. Adding the notice should cure any further violation, if those are indeed the same files. Of all the files listed, Solaris gives only errno.h a BSD copyright notice.
There are portions of the Linux files in question that are similar to modern System V and BSD code. Actually, given that there are millions of lines of code in the Linux kernel, it would be surprising not to find individual lines that are the same as individual lines in other versions of Unix.
UNIX Version 7 contained:
a.out.h ctype.h/ctype.c errno.h signal.h sys/acct.h sys/stat.h
All were published in 1978 without copyright management information. They are in the public domain, and even if not, clearly no copyright information was stripped off of them, since they didn't have any, ever.
The SCO Group also (in a gesture that now seems less than magnanimous) gave the public a no-cost license (pdf) to use the Version 7 files.
That leaves only:
ioctl.h ipc.h ecoff.h
... for SCO to question.
Furthermore, I don't know what legal authority a confidential settlement agreement to which I was not a party could possibly have over me. Here we have another example of the SCO IP Flaw: they confuse contractual obligations with other intellectual property. The files in question are not the same, even if they do the same things and have the same names. These are new files, not covered by any agreement.
SCO has failed to show their code on which Linux allegedly infringes. It's not enough to say that certain portions of certain Linux files infringe.
Use in Linux of any ABI Code or other UNIX Derived Files identified above constitutes a violation of the United States Copyright Act. Distribution of the copyrighted ABI Code, or binary code compiled using the ABI code, with copyright management information deleted or altered, violates the Digital Millennium Copyright Act ("DMCA") codified by Congress at 17 U.S.C. §1202. DMCA liability extends to those who have reasonable grounds to know that a distribution (or re-distribution as required by the GPL) of the altered code or copyright information will induce, enable, facilitate, or conceal an infringement of any right under the DMCA. In addition, neither SCO nor any predecessor in interest has ever placed an affirmative notice in Linux that the copyrighted code in question could be used or distributed under the GPL. As a result, any distribution of Linux by a software vendor or a re-distribution of Linux by an end user that contains any of the identified UNIX code violates SCO's rights under the DMCA, insofar as the distributor knows of these violations.
The DMCA has multiple independent sections. SCO is using people's fear of the law to hide the fact they are conflating the sections and applying them in incorrect ways.
It is apparent that the author of this letter sought to make as many references to the DMCA as he could. He tried so hard that he even misquotes the law to his own detriment:
DMCA liability extends to those who have reasonable grounds to know that a distribution (or re-distribution as required by the GPL) of the altered code or copyright information will induce, enable, facilitate, or conceal an infringement of any right under the DMCA. (Emphasis added)
The DMCA doesn't define any rights on its own. The statute says "any right under this title." "This title" is Title 17 of the U.S. Code (Copyrights), not the DMCA, which is only part of it. The rights would be those defined in 17 USC § 106 and 106A.
The above quoted paragraph also mischaracterizes the relationship of the DMCA and GPL. SCO appears to believe that the of receipt of software licensed under the GPL constitutes copying it under the DMCA. It does not. Copying is only done by someone who has a copy, makes another, and redistributes a copy to someone else. Merely being licensed to do something doesn't mean you've done it. And the GPL explicitly states that if redistributing the software would violate a legal obligation, then you may not redistribute. So even if SCO's ludicrous claims were somehow legitimized, it would only mean that a user couldn't redistribute Linux, not that they couldn't use it.
SCO implies that they will invoke the DMCA "takedown" mechanism to Linux use at some point, unless recipients of the letter comply with SCO demands. SCO has no grounds on which to make that assertion explicit, since the DMCA "takedown" mechanism applies only material posted online, not to its mere use.
The DMCA doesn't apply to Linux distributors unless it is proven that SCO copyrights were removed from SCO code and published as non-SCO code in Linux (or compiled and distributed that way). 17 USC § 1202 refers only to the removal of copyright management information, not the failure to add it. Furthermore, the burden is still on SCO to show code that is infringed upon.
As stated above, SCO's review is ongoing and will involve additional disclosures of code misappropriation. Certain UNIX code, methods and concepts, which we also claim are being used improperly in Linux, will be produced in the pending litigation between SCO and IBM under a confidentiality order.
There can't be "additional disclosures" until there's a first disclosure (not simply a list of files). And there's that flaw again. Note paragraph (b) from 17 USC § 102:
In no case does copyright protection for an original work of authorship extend to any idea, procedure, process, system, method of operation, concept, principle, or discovery, regardless of the form in which it is described, explained, illustrated, or embodied in such work.
The only items that appear in common throughout these files are the numeric values for constants specified in the industry standards documents. I conclude that SCO is claiming ownership of the correspondence between the standard human-readable mnemonic labels and the actual values themselves. They are claiming, in essence, to own the use of a particular set of numbers.
The correspondence between mnemonic labels and a particular set of numeric values is a fact that has been widely published. It is my understanding SCO can claim copyright on the text and layout of their source and manuals, but not the facts they represent. That would require a patent or some other mechanism that can protect an idea or method; copyrights just protect expression.
The ABIs are facts or ideas that are not copyrightable. The documents which describe the ABIs and the source code which implements the ABIs can be copyrighted if they meet the other copyright criteria. It is obvious that no piece of SCO UNIX source code has been copied into Linux. SCO hasn't shown any evidence suggesting that any copying occurred, nor have they claimed a single line of copyrightable code from Linux. What they actually claimed was copyright to a method of operation.
The argument that the ABIs are proprietary SCO code is obviously meritless.
This article would not have been possible without the contributions of the community at the Groklaw web site, especially Harlan Wilkerson, Dr. Horst H. von Brand, Ross Coombs, Rusty Carruth, and many others.
UNIX is a registered trademark of The Open Group in the United States and other countries.[1] The appearance herein of material copyrighted by others, whether previously published or not, is made under 17 USC § 107 ("fair use"); I claim no right to that content. The use of these materials
<asm-ia64/errno.h>,<asm-ia64/ioctl.h> © 1998, 1999 David Mosberger-Tang
<asm-ia64/errno.h>, <asm-ia64/ioctl.h> © 1998, 1999 Hewlett-Packard Co
<asm-ia64/signal.h> © 1998-2001 Hewlett-Packard Co
<asm-mips/errno.h>, <asm-mips/ioctl.h> © 1995, 1996, 2001 by Ralf Baechle
<asm-mips/signal.h> © 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
<asm-mips/signal.h>, <asm-mips64/signal.h> © 1999 Silicon Graphics, Inc.
<asm-mips64/errno.h> © 1995, 2001 by Ralf Baechle
<asm-mips64/errno.h> © 2001 Silicon Graphics, Inc.
<asm-mips64/ioctl.h> © 1995, 1996, 1999, 2001 by Ralf Baechle
<asm-mips64/ioctls.h> © 1995, 1996, 2001 Ralf Baechle
<asm-mips64/ioctls.h> © 2001 MIPS Technologies, Inc.
<asm-mips64/signal.h> © 1995 - 1999 by Ralf Baechle
<asm-sparc/bsderrno.h>,<asm-sparc/solerrno.h> © 1995 David S. Miller
<asm-sparc64/bsderrno.h>, <asm-sparc64/solerrno.h> © 1996 David S. Miller
<lib/ctype.c> © 1991, 1992 Linus Torvalds
<linux/acct.h> © 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.