.SH Header files Different naming of identical header files time.h sys/time.h Note that, although 4.2BSD does not require you to include sys/types.h before sys/file.h, 4.1BSD *does*. Portable way: include and and use cc -I/usr/include/sys strings.h is non-existent in 4.1BSD. It contains type declarations for the string comparison, searching and copying functions. Put in your own explicit declarations. .SH System Calls Portable system calls open close read write lseek creat link unlink chown chmod chdir stat ioctl* fork wait kill ioctl Portable ioctl functions are TIOCGETP and TIOCSETP on ttys. 4.1 and 4.2 have FIONREAD to return the number of chars waiting to be read. open 4.2's three-argument open() call is not to be used, nor are 4.2's O_RDONLY defines in . (Though you may use #ifndef O_RDONLY and define them yourself. Use only the values 0, 1 and 2, though) .SH Ioctl requests TIOCGETP Std 4.1BSD 4.2BSD Get terminal mode TIOCSETP Std 4.1BSD 4.2BSD Set terminal mode FIONREAD 4.1BSD 4.2BSD Return count of readable characters 4.2BSD also has fstat lstat .SH Libraries Different naming of identical libraries 4.2BSD others -ltermlib -ltermcap functions to perform cursor positioning etc On system V the library -lcurses also contains -ltermcap. .SH Library routines Always declare the types of the library routines you use. You *must* declare those which return types other than int, and should declare all of them. EG puts(ctime(clock)+4) will not work on the orion if char *ctime() is absent. Different naming of identical functions 4.1BSD 4.2BSD Ultrix-32 System V index(s,c) strchr(s,c) return index of leftmost char c in string s rindex(s,c) strrchr(s,c) return index of rightmost char c in string s Bugs in some systems 4.1BSD isprint(' ') returns 0 where it should return 1 (so use "if (isprint(ch) || ch==' ')" ) .SH Built-in types char May be signed or unsigned when converted into an int. short long int Probably safe to assume the values -32768 to +32767 can be held. pointers do not confuse different types of pointer. Eg struct stat stbuf; n = write(1, &stbuf, sizeof(struct stat)); will not work on Perqs. You must cast the stbuf pointer into a character pointer. .SH Stdio In version 4.2BSD, when end of file is encountered on a stdio stream, it is "sticky". That is, getchar will continue to return EOF even if more input becomes available. This is contrary to previous stdios. In systems pre-4.2, if you open (eg) a tty and want it to be line-buffered/unbuffered you must say so with a setbuf call. The setbuffer() call is unique to 4.2BSD. Do not drop off the end of main() to indicate successful completion; call exit(0) explicitly. Common errors 1) char ch; while ( (ch=getchar()) != EOF); This constuct will loop indefinately on a machine whose characters are unsigned. The return value from getchar() is an *integer* to accommodate 256 character values and EOF (-1) as well. With signed characters, this will seem to work as -1 is converted to a character and back without change. However, the program will terminate prematurely if a character 255 is found in the input. 2) int i; char *p; char *str = "Hallo"; i = str; p = i + 1; if (*p != 'a') abort(); Do not put a pointer into an integer variable, do maths with it and then use it as a pointer again. On most machines, this will work the same as maths on a char pointer, but on others (eg Orion) it performs word arithmetic. Do arithmetic on the pointer variable itself. Exotic language features enums are to be avoided because they aren't available in all compilers and don't work in others. the (void) type should be used under the define VOID, so that it can be defined to nothing for compilers which don't have it. Don't assign structures, or pass them as paramters or return values, and expect all the elements to be copied across. Not all compilers support structure assignment. Pass a pointer to it; use bcopy to assign. Identifier length Make all identifiers unique in the first six characters and unique when considered case-independently. They can be longer than this, but consider any characters past the sixth as commentary. Note however, that you must not use "normalise" and "normalize" and expect them to refer to the same object. Unix filenames should never be longer than fourteen characters. Above all, USE LINT. It knows far more about program portability than us, and will check many portability considerations (particularly type-checking the arguments to library functions) which escape the human eye. Warnings from lint, and particularly from compilers, most of which are very lax, will be fatal errors or, worse, bugs on other systems.