5.11. Selected AIX/Linux System API ComparisonsThis section takes a selected set of system APIs and compares and contrasts them with AIX and Linux in a man-page format. The APIs were chosen based on how much difference existed between AIX and Linux. Unlike in the previous section, in which the only differences that existed were ERRNO returns, the APIs listed in this section show differences that go beyond just ERRNOs. In some cases, the information returned by AIX and Linux differs significantly and must be addressed early during the porting cycle. Like a man page, each API listed in this section lists the API name, prototype for AIX and Linux, parameter listing, and the return value of the routine. In addition, a "Detail Comparison" section is included in each API section explaining the differences in the API between AIX and Linux (with examples and code snippets). If the API is not compatible between AIX and Linux, it is clearly marked with a "**Not compatible**" identifier. In such cases, examples and analytical reasoning are given as to why it is not compatible. Some are identified as "**Compatible**" but with differences, which will also be explained. In some cases, additional operating system-specific (that is, AIX or Linux) information pertinent to the porting process follows the "Detail Comparison" section. 5.11.1. getfsent(), getfsfile(), getfstype(), getfsspec()These calls retrieve information about a filesystem. See "Additional Data: Linux-Specific" for Linux-specific information. 5.11.1.1. AIX Prototype#include <fstab.h> struct fstab *getfsent(); struct fstab *getfsspec ( char *special ); struct fstab *getfsfile( char *file ); struct fstab *getfstype( char* type ); void setfsent( ); void endfsent( ); 5.11.1.2. Linux Prototype#include <fstab.h> void endfsent(void); struct fstab *getfsent(void); struct fstab *getfsfile(const char *mount_point); struct fstab *getfsspec(const char *special_file); int setfsent(void); 5.11.1.3. Detail Comparison**Not Compatible** AIX and Linux implement their filesystem differently, and as a result different information must be returned. Both platforms return an fstab struct, but information is different. AIX struct fstab{ char *fs_spec; /* block special device name */ char *fs_file; /* file system path prefix */ char *fs_type; /* read/write, etc see above defines */ int fs_check; /* true=0, false=-1, else "check" val */ int fs_freq; /* not used */ int fs_passno; /* not used */ }; Linux struct fstab { char *fs_spec; /* block device name */ char *fs_file; /* mount point */ char *fs_vfstype; /* filesystem type */ char *fs_mntops; /* mount options */ const char *fs_type; /* rw/rq/ro/sw/xx option */ int fs_freq; /* dump frequency, in days */ int fs_passno; /* pass number on parallel dump */ }; 5.11.1.4. Additional Data: Linux-SpecificHere the field fs_type contains (on a *BSD system) one of the five strings: rw, rq, ro, sw, xx (read-write, read-write with quotas, read-only, swap, ignore). The function setfsent() opens the file when required and positions it at the first line. The function getfsent() parses the next line from the file (after opening it when required). The function endfsent() closes the file when required. The function getfsspec() searches the file from the start and returns the first entry found for which the fs_spec field matches the special_file argument. The function getfsfile() searches the file from the start and returns the first entry found for which the fs_file field matches the mount_point argument. 5.11.1.5. Return ValueUpon success, the functions getfsent(), getfsfile(), and getfsspec() return a pointer to a struct fstab, whereas setfsent() returns 1. Upon failure or end of file, these functions return NULL and 0, respectively. 5.11.2. ioctl()The ioctl function manipulates the underlying device parameters of special files. In particular, many operating characteristics of character special files (for example, terminals) may be controlled with ioctl requests. The argument d must be an open file descriptor. An ioctl request has encoded in it whether the argument is an in parameter or out parameter and the size of the argument argp in bytes. Macros and defines used in specifying an ioctl request are located in the file sys/ioctl.h. 5.11.2.1. AIX Prototype#include <sys/ioctl.h> #include <sys/types.h> #include <unistd.h> int ioctl (int FileDescriptor, int Command, void *Argument); 5.11.2.2. Linux Prototype#include <sys/ioctl.h> int ioctl(int d, int request, ...) 5.11.2.3. Detail Comparison**Not Compatible** In Linux, command values are generally driver-specific. This function is not considered portable. AIXIn AIX, the ioctl subroutine performs a variety of control operations on the object associated with the specified open file descriptor. This function is typically used with character or block special files and sockets generic device support such as the termio general terminal interface. Parameters
Linux The ioctl function manipulates the underlying device parameters of special files. In particular, many operating characteristics of character special files (for example, terminals) may be controlled with ioctl requests.
An ioctl request has encoded in it whether the argument is an in parameter or out parameter, and the size of the argument argp in bytes. Macros and defines used in specifying an ioctl request are located in the file sys/ioctl.h. 5.11.2.4. Return ValueUsually, on success, 0 is returned. A few ioctls use the return value as an output parameter and return a nonnegative value on success. On error, 1 is returned, and ERRNO is set appropriately. 5.11.2.5. Errors
5.11.2.6. ERRNO(s) Not Supported in Linux
5.11.3. read(), write()To read from a file descriptor into a buffer or to write to a file descriptor from a buffer, use the read()/write() commands. 5.11.3.1. AIX Prototype#include <unistd.h> ssize_t read (int FileDescriptor, void *Buffer, size_t NBytes); ssize_t write(int fd, const void *buf, size_t NBytes); 5.11.3.2. Linux Prototype#include <unistd.h> ssize_t read(int fd, void *buf, size_t NBytes); ssize_t write(int fd, const void *buf, size_t NBytes; 5.11.3.3. Detail Comparison**Compatible** Functions are source-compatible, but ERROR return values differ. Refer to the "Errors" section that follows. On most UNIX systems, O_NONBLOCK is used on socket descriptors, in which read returns 1 and sets ERRNO EAGAIN, which signifies to the user that additional data is available on the descriptor. Linux, on the other hand, considered current available filesystems and disks to be fast enough and deemed O_NONBLOCK unnecessary. As a result, this O_NONBLOCK may not be implemented on some flavors of Linux. 5.11.3.4. Additional Info: AIX/Linux
If NBytes is 0, read() returns 0 and has no other results. If NBytes is greater than SSIZE_MAX, the result is unspecified. 5.11.3.5. Linux RestrictionsOn NFS filesystems, reading small amounts of data updates the timestamp only the first time; subsequent calls may not do so. This is caused by client-side attribute caching, because most if not all NFS clients leave atime updates to the server, and client-side reads satisfied from the client's cache will not cause atime updates on the server because there are no server-side reads. UNIX semantics can be obtained by disabling client-side attribute caching, but in most situations this substantially increases server load and decreases performance. 5.11.3.6. Return ValueOn success, the number of bytes read is returned (0 indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested. This may happen, for example, because fewer bytes are actually available right now (maybe because we were close to end of file, or because we are reading from a pipe or a terminal), or because read() was interrupted by a signal. On error, 1 is returned, and ERRNO is set appropriately. In this case, it is left unspecified whether the file position (if any) changes. 5.11.3.7. Errors
Other errors may occur, depending on the object connected to fd. POSIX allows a read that is interrupted after reading some data to return 1 (with ERRNO set to EINTR) or to return the number of bytes already read. Conforming ToSVr4, SVID, AT&T, POSIX, X/OPEN, BSD 4.3 ERRNO(s) Not Supported in Linux
5.11.4. confstr()The confstr() function provides a method for applications to get configuration-defined string values. Its use and purpose are similar to the sysconf() function; however, confstr() is used where string values (rather than numeric values) are returned. 5.11.4.1. AIX Prototype#include <unistd.h> size_t confstr (int name, char * buf, size_t len); 5.11.4.2. Linux Prototype#define _POSIX_C_SOURCE 2 or #define _XOPEN_SOURCE #include <unistd.h> size_t confstr(int name, char * buf, size_t len); 5.11.4.3. Detail Comparison**Compatible** Functions are source-compatible, but _POSIX_C_SOURCE or _XOPEN_SOURCE must be turned on in Linux. 5.11.5. opendir()The opendir() function opens a directory stream corresponding to the directory named by the name argument. 5.11.5.1. AIX Prototype#include <dirent> DIR *opendir(const char *name); struct dirent *readdir (DIR *DirectoryPointer); 5.11.5.2. Linux Prototype#include <dirent.h> DIR *opendir(const char *name); struct dirent *readdir(DIR *dir); 5.11.5.3. Detail Comparison**Compatible** Functions are source-compatible, but there are differences between the dirent structures in the two systems:
5.11.5.4. ERRNOWhen called in AIX, this function can return these ERRNOs not documented in Linux:
5.11.6. readdir()readdir() is a deprecated function. Instead, you should use geTDents(). Refer to the Linux documentation for more information on geTDents(). 5.11.7. fcntl()The fcntl subroutine performs controlling operations on the open file specified by the FileDescriptor (fd) parameter. If Network File System (NFS) is installed on your system, the open file can reside on another node. The fcntl subroutine is used to do the following:
The following commands are supported for all file types and are passed via the cmd parameter:
When a shared lock is set on a segment of a file, other processes can set shared locks on that segment or a portion of it. A shared lock prevents any other process from setting an exclusive lock on any portion of the protected area. A request for a shared lock fails if the file descriptor was not opened with read access. An exclusive lock prevents any other process from setting a shared lock or an exclusive lock on any portion of the protected area. A request for an exclusive lock fails if the file descriptor is not opened with write access. The flock and flock64 structure contains the following fields:
If l_len is positive, the affected area starts at l_start and ends at (l_start + l_len - 1). If l_len is negative, the area affected starts at (l_start + l_len) and ends at (l_start - 1). Locks may start and end beyond the current end of a file but must not be negative relative to the beginning of the file. Setting l_len to 0 sets a lock that can extend to the largest possible value of the file offset for that file. If such a lock also has l_start set to 0 and l_whence set to SEEK_SET, the whole file is locked. There can be at most one type of lock set of each byte in the file. Before a successful return from an F_SETLK, F_SETLK64, F_SETLKW, or F_SETLKW64 request when the calling process has previously existing locks on bytes in the region specified by the request, the previous lock type for each byte in the specified region is replaced by the new lock type. As specified earlier, an F_SETLK, F_SETLK64, F_SETLKW, or F_SETLKW64 request fails or blocks, respectively, when another process has existing locks on bytes in the specified region and the type of any of those locks conflicts with the type specified in the request. All locks associated with a file for a given process shall be removed when a file descriptor for that file is closed by that process or when the process holding that file descriptor terminates. Locks are not inherited by a child process. A potential for deadlock occurs if a process controlling a locked region is put to sleep by attempting to lock another process's locked region. If the system detects that sleeping until a locked region is unlocked would cause a deadlock, fcntl() returns 1 with ERRNO set to EDEADLK. 5.11.7.1. AIX Prototype#include <fcntl.h> int fcntl (int FileDescriptor, int cmd, ...); 5.11.7.2. Linux Prototype#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, struct flock *lock); 5.11.7.3. Detail Comparison**Compatible** The user should take note of the different open modes and command values between AIX and Linux. In the preceding section, the command description is mainly Linux-specific. Refer to the "File Bits" section at the end of this chapter. 5.11.7.4. Return ValueFor a successful call, the return value depends on the operation performed:
On error, 1 is returned, and ERRNO is set appropriately. 5.11.7.5. Errors
5.11.7.6. ERRNOs Not Supported in Linux
5.11.8. llseek(), lseek(), lseek64()Sometimes you do not want to start at the beginning of an open file to start reading or writing to it. llseek(), lseek(), and lseek64() reposition the read/write pointer in a file that is associated with a file descriptor (fd). 5.11.8.1. AIX Prototype#include <sys/types.h> #include <unistd.h> offset_t llseek(int fd, offset_t offset, int whence); offset_t lseek(int fd, offset_t offset, int whence); offset_t lseek64(int fd, offset_t offset, int whence); 5.11.8.2. Linux Prototype#include <sys/types.h> #include <unistd.h> off_t lseek(int fildes, off_t offset, int whence); _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh); int _llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t *result, unsigned int whence); 5.11.8.3. Detail Comparison**Compatible** Although llseek is implemented in Linux, if you are writing new code lseek should be used instead of llseek for greater portability between UNIX platforms. 5.11.8.4. Additional Info: AIX/Linux, lseek Only
5.11.8.5. Return ValueUpon successful completion, lseek returns the resulting offset location as measured in bytes from the beginning of the file. Otherwise, a value of (off_t)1 is returned and ERRNO is set to indicate the error. 5.11.8.6. Errors
5.11.8.7. ERRNOs Not Supported in Linux
Conforming To SVr4, POSIX, BSD 4.3 5.11.9. uname()Occasionally, shell programmers as well as application developers need to know information about the system they are running on at runtime. This information could be used to set specific operating system environment variables and could aid in developing install packages for specific systems. To get the name and information about the current kernel and the machine the kernel is running on, use the uname() function. 5.11.9.1. AIX Prototype#include <sys/utsname.h> int uname (struct utsname *Name); 5.11.9.2. Linux Prototype#include <sys/utsname.h> int uname(struct utsname *buf); 5.11.9.3. Details Comparison**Not Compatible** AIX does not define domainname as part of the utsname structure. The domainname enTRy is technically not compatible because it is defined in Linux only if the program is compiled with _GNU_SOURCE. 5.11.10. syslog(), closelog(), openlog()These commands provide messaging services to the system logger:
5.11.10.1. AIX Prototype#include <syslog.h> void openlog(const char *ident, int LogOption, int Facility); void syslog(int Priority, const char *Value,... ); int closelog(void); 5.11.10.2. Linux Prototype#include <syslog.h> void openlog( char *ident, int LogOption, int facility); void syslog( int priority, char *format, ...); void closelog( void ); 5.11.10.3. Details Comparison**Compatible** The facilities will require additional code changes under Linux to make use of the following: LOG_PERROR LOG_AUTHPRIV 5.11.11. swapoff(), swapon()These commands are usually used for device programming for enabling paging on a device. swapon sets the swap area to the file or block device specified by path. swapoff stops swapping to the file or block device specified by path. 5.11.11.1. AIX Prototype#include <sys/vminfo.h> int swapon (char *PathName); int swapoff(char *PathName); 5.11.11.2. Linux Prototype#include <unistd.h> #include <asm/page.h> #include <sys/swap.h> int swapon(const char *path, int swapflags); int swapoff(const char *path); 5.11.11.3. Details Comparision**Compatible** Functions are compatible, but the swapflags must be added for Linux. 5.11.11.4. Return ValueOn success, 0 is returned. On error, 1 is returned, and ERRNO is set appropriately. 5.11.11.5. ErrorsMany other errors can occur if path is not valid:
5.11.11.6. ERRNO(s) Not Implemented in Linux
5.11.12. acct()Use this command to switch process accounting on or off. 5.11.12.1. Linux/AIX Prototype#include <unistd.h> int acct (char *Path); 5.11.12.2. Detail Comparison**Compatible** 5.11.12.3. Return ValueOn success, 0 is returned. On error, 1 is returned, and ERRNO is set appropriately. 5.11.12.4. Errors
5.11.12.5. ERRNO(s) Not Implemented in Linux
5.11.13. mmap(), mmap64(),[17] munmap()
These commands are memory-mapping functions. There comes a time when you want to read and write to and from files so that the information is shared between processes. Think of it this way: two processes both open the same file and both read and write from it, thus sharing the information. Wouldn't it be easier if you could just map a section of the file to memory and get a pointer to it? Then you could simply use pointer arithmetic to get (and set) data in the file. Another great advantage to using memory-mapped files is to speed up performance. It would take a lot of I/O resources if more than one process needs to manipulate a large file. You would have to open, read and write to the file, and close it. If the file is already mapped in memory, access to the file is much quicker, which greatly improves I/O access. mmap(), mmap64(), and munmap() enable you to map and unmap a file in memory to be shared by two or more processes for I/O processing, and they are really easy to use. A few simple calls, mixed with a few simple rules, and you are mapping like a mad person. 5.11.13.1. AIX Prototype#include <sys/types.h> #include <sys/mman.h> void *mmap (void *addr, size_t len, int prot, int flags, int fildes, off_t off); void *mmap64 (void *addr, size_t len, int prot, int flags, int fildes, off_t off); int munmap (void *addr, size_t len); 5.11.13.2. Linux Prototype#include <unistd.h> #include <sys/mman.h> #ifdef _POSIX_MAPPED_FILES void * mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); void * mmap64(void *start, size_t length, int prot, int flags, int fd, off_t off); int munmap(void *start, size_t length); #endif 5.11.13.3. Detail Comparison**Compatible** Values for prot are identical to AIX. In AIX, mmap() and munmap() are system calls. The mmap function asks to map length bytes starting at offset from the file (or other object) specified by the file descriptor fd into memory, preferably at address start. If MAP_FIXED is used, the start address (addr) is a hint only and is usually specified as 0. The actual place where the object is mapped is returned by mmap and is never 0. The prot argument describes the desired memory protection (and must not conflict with the open mode of the file). It is either PROT_NONE or is the bitwise OR of one or more of the other PROT_* flags:
The flags parameter specifies the type of the mapped object, mapping options, and whether modifications made to the mapped copy of the page are private to the process or are to be shared with other references. Bits (below) are used to tell the system how the file will be mapped:
You must specify exactly one of MAP_SHARED and MAP_PRIVATE. The preceding three flags are described in POSIX.1b (formerly POSIX.4) and SUSv2. Linux also is aware of the following nonstandard flags:
Some systems document the additional flags MAP_AUTOGROW, MAP_AUTORESRV, MAP_COPY, and MAP_LOCAL. fd should be a valid file descriptor, unless MAP_ANONYMOUS is set, in which case the argument is ignored. offset should be a multiple of the page size as returned by getpagesize. Memory mapped by mmap is preserved across fork(), with the same attributes. A file is mapped in multiples of the page size. For a file that is not a multiple of the page size, the remaining memory is zeroed when mapped and writes to that region are not written out to the file. The effect of changing the size of the underlying file of a mapping on the pages that correspond to added or removed regions of the file is unspecified. The munmap system call deletes the mappings for the specified address range and causes further references to addresses within the range to generate invalid memory references. The region is also automatically unmapped when the process is terminated. That said, closing the file descriptor does not unmap the region. The address start must be a multiple of the page size. All pages containing a part of the indicated range are unmapped, and subsequent references to these pages will generate SIGSEGV. It is not an error if the indicated range does not contain any mapped pages. For file-backed mappings, the st_atime field for the mapped file may be updated at any time between the mmap() and the corresponding unmapping; the first reference to a mapped page will update the field if necessary. The st_ctime and st_mtime fields for a file mapped with PROT_WRITE and MAP_SHARED will be updated after a write to the mapped region, and before a subsequent msync(), with the MS_SYNC or MS_ASYNC flag, if one occurs. 5.11.13.4. Return ValueOn success, mmap returns a pointer to the mapped area. On error, MAP_FAILED (1) is returned, and ERRNO is set appropriately. On success, munmap returns 0, on failure 1, and ERRNO is set (probably to EINVAL). 5.11.13.5. Errors
Use of a mapped region can result in these signals:
5.11.13.6. ERRNO(s) Not Implemented in Linux
Conforming ToSVr4, POSIX.1b (formerly POSIX.4), 4.4BSD, SUSv2. SVr4 documents additional error codes ENXIO and ENODEV. SUSv2 documents additional error codes EMFILE and EOVERFLOW. 5.11.14. pread(), pwrite()This command reads from or writes to a file descriptor at a given offset. 5.11.14.1. Linux Prototypeb#define _XOPEN_SOURCE 500 #include <unistd.h> ssize_t pread(int fd, void *buf, size_t count, off_t offset); ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); 5.11.14.2. AIX Prototype#include <unistd.h> ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); ssize_t pwrite (int FileDescriptor, const void *Buffer, size_t NBytes, off_t Offset); 5.11.14.3. Detail Comparison**Compatible** pread() reads up to count bytes from file descriptor fd at offset offset (from the start of the file) into the buffer starting at buf. The file offset is not changed. pwrite() writes up to count bytes from the buffer starting at buf to the file descriptor fd at offset offset. The file offset is not changed. The file referenced by fd must be capable of seeking. 5.11.14.4. Additional Data: Linux-SpecificFunctions are source-compatible, but note the #define _XOPEN_SOURCE 500 for Linux. _XOPEN_SOURCE 500 does not have to be explicitly defined by the user for all versions of Linux. 5.11.14.5. Return ValueOn success, the number of bytes read or written is returned (0 indicates that nothing was written, in the case of pwrite, or end of file, in the case of pread), or 1 on error, in which case ERRNO is set to indicate the error. 5.11.14.6. Errorspread can fail and set ERRNO to any error specified for read or lseek. pwrite can fail and set ERRNO to any error specified for write or lseek. 5.11.14.7. ERRNO(s) Not Implemented in Linux
Conforming ToUnix98 5.11.15. stat(), lstat(), fstat()These functions return information about the specified file. You do not need any access rights to the file to get this information, but you need search rights to all directories named in the path leading to the file. 5.11.15.1. AIX Prototype#include <sys/stat.h> int stat(const char * Path, struct stat * Buffer); int lstat (const char * Path, struct stat * Buffer); int fstat (int FileDescriptor, struct stat * Buffer); 5.11.15.2. Linux Prototype#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *file_name, struct stat * buf); int fstat(int filedes, struct stat * buf); int lstat(const char *file_name, struct stat * buf); 5.11.15.3. Detail Comparison**Compatible** Functions are source-compatible. Code that references dev_ts may not work correctly unless the macros major(), minor(), and makedev() are used. These are found in sys/sysmacros.h. 5.11.15.4. ERRNO(s) Not Implemented in AIX
5.11.16. ptrace()The ptrace system call provides a means by which a parent process may observe and control the execution of another process and examine and change its core image and registers. It is primarily used to implement breakpoint debugging and system call tracing. 5.11.16.1. AIX Prototype#include <sys/reg.h> #include <sys/ptrace.h> #include <sys/ldr.h> int ptrace(int Request, int Identifier, int *Address, int Data, int *Buffer); 5.11.16.2. AIX5L Prototype#define _LINUX_SOURCE_COMPAT #include <sys/ptrace.h> long int ptrace(enum ptrace_request request, pid_t pid, void *addr, void *data); 5.11.16.3. Linux Prototype#include <sys/ptrace.h> long int ptrace(enum ptrace_request request, pid_t pid, void *addr, void *data); 5.11.16.4. Detail Comparison**Not Compatible** Although the service the API provides is similar between AIX and Linux, the way the tracing service is implemented differs. In Linux, kernel-level thread debugging is not possible with the ptrace as in AIX. And, in AIX, code built with the _LINUX_SOURCE_COMPAT directive is more compatible with the Linux ptrace. The parent can initiate a trace by calling fork and having the resulting child do a PTRACE_TRACEME, followed (typically) by an exec. Alternatively, the parent may commence trace of an existing process using PTRACE_ATTACH. While being traced, the child will stop each time a signal is delivered, even if the signal is being ignored. (The exception is SIGKILL, which has its usual effect.) The parent will be notified at its next wait and may inspect and modify the child process while it is stopped. The parent then causes the child to continue, optionally ignoring the delivered signal (or even delivering a different signal instead). When the parent is finished tracing, it can terminate the child with PTRACE_KILL or cause it to continue executing in a normal, untraced mode via PTRACE_DETACH. The value of request determines the action to be performed:
5.11.16.5. ERRNO(s) Not Implemented in Linux
5.11.17. setgid(), setregid()These commands are used to set the user and group permission on a particular file or device. 5.11.17.1. AIX/Linux Prototype#include <unistd.h> int setgid(gid_t gid); int setregid(gid_t rgid, gid_t egid); 5.11.17.2. Detail Comparison**Compatible** Functions are source-compatible, but in AIX setgid sets the effective group ID of the current process. In Linux if the caller is the super user, the real and saved group IDs are also set. setreuid sets real and effective user IDs of the current process. Unprivileged users may only set the real user ID to the real user ID or the effective user ID, and may only set the effective user ID to the real user ID, the effective user ID, or the saved user ID. 5.11.17.3. Return ValueOn success, 0 is returned. On error, 1 is returned, and ERRNO is set appropriately. 5.11.17.4. Errors
5.11.17.5. ERRNO(s) Not Implemented in Linux
5.11.18. sync()Reading from a disk is very slow compared to accessing (real) memory. In addition, it is common to read the same part of a disk several times during relatively short periods of time. For example, one might first read an e-mail message, then read the letter into an editor when replying to it, and then make the mail program read it again when copying it to a folder. Or, consider how often the command ls might be run on a system with many users. By reading the information from disk only once and then keeping it in memory until no longer needed, one can speed up all but the first read. This is called disk buffering, and the memory used for this purpose is called the buffer cache. sync() commits buffer cache to disk. 5.11.18.1. AIX Prototype#include <unistd.h> void sync(void); 5.11.18.2. Linux Prototype#include <unistd.h> int sync(void); 5.11.18.3. Detail ComparisonFunctions are not quite compatible. In AIX, sync() is a void system call. In Linux, sync() always returns 0. Any code that tests or assigns the return value of sync() will cause compile errors. 5.11.19. wait3(), wait4()Often in multiprocess-programming you want to suspend execution of one process until an event of some sort happens either in the current process or in another process. The wait3 and wait4 functions control the running of processes. The wait3 function suspends execution of the current process until a child has exited, or until a signal is delivered whose action is to terminate the current process or to call a signal handling function. If a child has already exited by the time of the call (a so-called zombie process), the function returns immediately. Any system resources used by the child are freed. The wait4 function suspends execution of the current process until a child as specified by the pid argument has exited, or until a signal is delivered whose action is to terminate the current process or to call a signal handling function. If a child as requested by pid has already exited by the time of the call (a zombie process), the function returns immediately. Any system resources used by the child are freed. 5.11.19.1. AIX Prototype#define _ALL_SOURCE #include <sys/types.h> #include <sys/resource.h> #include <sys/wait.h> pid_t wait3(int *StatusLocation, int Options, struct rusage *ResourceUsage); pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage); 5.11.19.2. Linux Prototype#define _USE_BSD #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> #include <sys/wait.h> pid_t wait3(int *status, int options, struct rusage *rusage); pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage); 5.11.19.3. Detail Comparison**Compatible** The value of pid can be one of the following:
The value of options is a bitwise OR of zero or more of the following constants:
If status is not NULL, wait3 or wait4 stores status information in the location pointed to by status. This status can be evaluated with the following macros. (These macros take the stat buffer (an int) as an argument, not a pointer to the buffer!)
If rusage is not NULL, the struct rusage as defined in sys/resource.h or bit/resource.h it points to will be filled with accounting information. 5.11.19.4. Return ValueThe process ID of the child that exited is 1 on error (in particular, when no unwaited-for child processes of the specified kind exist) or 0 if WNOHANG was used and no child was available yet. In the latter two cases, ERRNO will be set appropriately. 5.11.19.5. Errors
5.11.19.6. ERRNO(s) Not Implemented in Linux
5.11.20. getcwd()The getcwd() function copies the absolute path name of the current working directory to the array pointed to by buf, which is of length size. If the current absolute path name would require a buffer longer than size elements, NULL is returned, and ERRNO is set to ERANGE; an application should check for this error and allocate a larger buffer if necessary. As an extension to the POSIX.1 standard, getcwd() allocates the buffer dynamically using malloc() if buf is NULL on call. In this case, the allocated buffer has the length size unless size is less than 0, when buf is allocated as big as necessary. It is possible (and, indeed, advisable) to free() the buffers if they have been obtained this way. get_current_dir_name, which is only prototyped if __USE_GNU is defined, will malloc() an array big enough to hold the current directory name. If the environment variable PWD is set, and its value is correct, that value will be returned. getwd, which is only prototyped if __USE_BSD is defined, will malloc() an array big enough to hold the absolute path name of the current working directory. 5.11.20.1. AIX Prototype#include <unistd.h> char *getcwd (char *Buffer, size_t Size); char *getwd(char *buf); 5.11.20.2. Linux Prototype#include <unistd.h> char *getcwd(char *buf, size_t size); char *get_current_dir_name(void); char *getwd(char *buf); 5.11.20.3. Detail Comparison**Compatible** AIX does not provide get_current_dir_name(). 5.11.20.4. Errors
5.11.20.5. ERRNO(s) Not Implemented in Linux
5.11.21. mount(), umount(), vmount()A file hierarchy is usually made available to the filesystem through the mount command. The umount command detaches the filesystem(s) mentioned from the file hierarchy. A filesystem is specified by giving the directory where it has been mounted. Giving the special device on which the filesystem lives may also work, but this is obsolete, mainly because it will fail in case this device was mounted on more than one directory. Note that a filesystem cannot be unmounted when it is "busy"for example, when there are open files on it, or when some process has its working directory there, or when a swap file on it is in use. The offending process could even be umount. 5.11.21.1. AIX Prototype#include <sys/vmount.h> int vmount (struct vmount *VMount, int size) int mount(char *Device, char *Path, int Flags) int umount (char *Device) 5.11.21.2. Linux Prototype#include <sys/mount.h> int mount(const char *specialfile, const char *dir, const char * filesystemtype, unsigned long rwflag, const void *data); int umount(const char *specialfile); int umount(const char *dir); int umount2(const char *target, int flags); 5.11.21.3. Detail Comparison**Not Compatible** Semantics differ between AIX and Linux. Specifically, AIX users must convert their application usage of this API to that of Linux. Older applications that run on earlier versions of AIX (4.3.3 or before) will have an easier conversion as they most likely would have used an older mount subroutine instead of vmount. But that comparison is only based on the equal number of arguments. The semantics still differ. umount functions are compatible. 5.11.21.4. Additional Data: Linux-SpecificThese functions are Linux-specific and should not be used in programs intended to be portable. mount attaches the filesystem specified by source (which is often a device name, but can also be a directory name or a dummy) to the directory specified by target. umount and umount2 remove the attachment of the (topmost) filesystem mounted on target. Only the super user may mount and unmount filesystems. Since Linux 2.4, a single filesystem can be visible at multiple mount points, and multiple mounts can be stacked on the same mount point. Values for the filesystemtype argument supported by the kernel are listed in /proc/filesystems (minix, ext2, msdos, proc, nfs, iso9660, and so on). More types may become available when the appropriate modules are loaded. The mountflags argument may have the magic number 0xC0ED (MS_MGC_VAL) in the top 16 bits (this was required in kernel versions prior to 2.4 but is no longer required and is ignored if specified), and various mount flags (as defined in linux/fs.h for libc4 and libc5 and in sys/mount.h for glibc2) in the low-order 16 bits:
From Linux 2.4 onward, the MS_NODEV, MS_NOEXEC, and MS_NOSUID flags are settable on a per-mount point basis. The data argument is interpreted by the different file systems. Typically, it is a string of comma-separated options understood by this filesystem. See mount for details of the options available for each filesystem type. Linux 2.1.116 added the umount2() system call, which, like umount(), unmounts a target, but allows additional flags controlling the behavior of the operation:
5.11.21.5. Return ValueOn success, 0 is returned. On error, 1 is returned, and ERRNO is set appropriately. 5.11.21.6. ErrorsThe error values given next result from filesystem-type-independent errors. Each filesystem type may have its own special errors and its own special behavior. See the kernel source code for details.
PortabilityThese functions are Linux-specific and should not be used in programs intended to be portable. 5.11.22. readv(), writev()These commands read and write data into multiple buffers. readv reads data from file descriptor filedes and puts the result in the buffers described by vector. The number of buffers is specified by count. The buffers are filled in the order specified. It operates just like read except that data is put in vector rather than a contiguous buffer. writev writes data to file descriptor filedes and from the buffers described by vector. The number of buffers is specified by count. The buffers are used in the order specified. It operates just like write except that data is taken from vector rather than a contiguous buffer. 5.11.22.1. AIX Prototype#include <sys/uio.h> ssize_t readv (int FileDescriptor, const struct iovec *iov, int iovCount); ssize_t writev (int FileDescriptor, const struct iovec *iov, int iovCount); 5.11.22.2. Linux Prototype#include <sys/uio.h> int readv(int filedes, const struct iovec *vector, int count); int writev(int filedes, const struct iovec *vector, int count); 5.11.22.3. Detail Comparison**Not Compatible** Functions return different types. On some systems this may be as simple as casting the return value to an int. Other than return values, semantics are the same. 5.11.22.4. Return ValueOn success readv returns the number of bytes read. On success writev returns the number of bytes written. On error, 1 is returned, and ERRNO is set appropriately. 5.11.22.5. Errors
Other errors may occur, depending on the object connected to filedes. 5.11.22.6. ERRNO(s) Not Implemented in Linux
Conforming To4.4BSD (the readv and writev functions first appeared in BSD 4.2), Unix98. Linux libc5 used size_t as the type of the count parameter. 5.11.23. select()select enables synchronous I/O multiplexing on a file descriptor. It checks the specified file descriptors and message queues (fd_set) to see whether they are ready for reading (receiving) or writing (sending). 5.11.23.1. AIX Prototype#include <sys/time.h> #include <sys/select.h> #include <sys/types.h> int select (int Nfdsmsgs, struct sellist *ReadList, struct sellist *WriteList, struct sellist *ExceptList, struct timeval *TimeOut); 5.11.23.2. Linux Prototype#include <sys/time.h> #include <sys/types.h> #include <unistd.h> int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask); 5.11.23.3. select(), pselect()**Not Compatible** Functions are source-compatible, but semantics differ. In AIX, the select is used for I/O multiplexing as well as exception and event handling. This is not so in Linux. For event and exception notification in Linux, you must use both select and sigprocmask system calls. Following is a brief example of how to handle the equivalent AIX exception and event notification in Linux: sigprocmask (SIG_BLOCK, &orig_sigmask, 0); r = select (n, &rd, &wr, &er, 0); sigprocmask (SIG_BLOCK, &sigmask, 0); In AIX, users call select with all three sets empty, n zero, and a non-null timeout as a fairly portable way to sleep with subsecond precision. On Linux, the function select modifies timeout to reflect the amount of time not slept, which is different from most other implementations. This causes problems both when porting to Linux from other platforms and vice versa because the timeout is unusable after the call to select in Linux. Therefore, in Linux, consider timeout to be undefined after select returns. The file sys/time.h contains compatibility defines for fd_set and the prototype for select(). The FD_* macros are also defined there. The sizes of the fd_set types differ, but code is source-compatible. In AIX, select is a system call. In Linux, an fd_set is 128 bytes. In AIX, it is 4096 bytes. If your set is larger than 128 bytes in AIX, this will have to be shortened. 5.11.23.4. Return ValueOn success, select and pselect return the number of descriptors contained in the descriptor sets, which may be zero if the timeout expires before anything interesting happens. On error, 1 is returned, and ERRNO is set appropriately; the sets and timeout become undefined, so do not rely on their contents after an error. 5.11.23.5. Errors
5.11.23.6. Example#include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int main(void) { fd_set rfds; struct timeval tv; int retval; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /* Don't rely on the value of tv now! */ if (retval) printf("Data is available now.\n"); /* FD_ISSET(0, &rfds) will be true. */ else printf("No data within five seconds.\n"); return 0; } 5.11.23.7. ERRNO(s) Not Implemented in Linux
Conforming To4.4BSD (the select function first appeared in 4.2BSD). Generally portable to/from non-BSD systems supporting clones of the BSD socket layer (including System V variants). However, note that the System V variant typically sets the timeout variable before exit, but the BSD variant does not. The pselect function is defined in IEEE Std 1003.1g-2000 (POSIX.1g) and part of POSIX 1003.1-2001. It is found in glibc 2.1 and later. glibc 2.0 has a function with this name, but it does not take a sigmask parameter. 5.11.24. reboot()Use reboot to enable or disable rebooting of a system. 5.11.24.1. AIX Prototype#include <sys/reboot.h> void reboot (int HowTo, void *Argument) #define _LINUX_SOURCE_COMPAT #include <sys/reboot.h> int reboot (int flag); 5.11.24.2. Linux PrototypeUnder glibc, some of the constants involved have gotten symbolic names RB_*, and the library call is a one-argument wrapper around the three-argument system call: #include <unistd.h> #include <sys/reboot.h> int reboot (int flag); For libc4 and libc5, the library call and the system call are identical, and since kernel version 2.1.30 there are symbolic names LINUX_REBOOT_* for the constants and a fourth argument to the call: #include <unistd.h> #include <linux/reboot.h> int reboot(int magic, int magic2, int flag, void *arg); 5.11.24.3. Detail Comparison**Not Compatible** In AIX, reboot is a system call. This command is a platform-specific command and is generally not portable for obvious reasons. However, IBM has made this command portable from Linux to AIX by providing the following flags when _LINUX_SOURCE_COMPAT is defined (the list also shows the Linux to AIX mapping if enabled [only on AIX5L]): LINUX_REBOOT_CMD_RESTART -> RB_SOFTIPL LINUX_REBOOT_CMD_HALT -> RB_HALT_POWERED LINUX_REBOOT_CMD_POWER_OFF -> RB_HALT LINUX_REBOOT_CMD_RESTART2 -> RB_POWIPL LINUX_REBOOT_CMD_CAD_ON -> return(ENOSYS) LINUX_REBOOT_CMD_CAD_OFF -> return(0) AIX did not implement CAD (Ctrl-Alt-Del) for Linux compatibility. 5.11.24.4. Return ValueOn success, the system reboots. On error, 1 is returned, and ERRNO is set appropriately. 5.11.24.5. Errors
5.11.24.6. ERRNO(s) Not Implemented in Linux
5.11.25. chroot()chroot() is a UNIX system call that is often used to provide an additional layer of security when untrusted programs are run. The call to chroot() is normally used to ensure that code run after it can only access files at or below a given directory. Generally this is /, but the chroot() system call can change this. When chroot() is successfully called, the calling process has its idea of the root directory changed to the directory given as the argument to chroot(). The root directory is inherited by all children of the current process. Only the super user may change the root directory. 5.11.25.1. AIX/Linux Prototype#include <unistd.h> int chroot(const char *path); 5.11.25.2. Details Comparison**Compatible** In AIX, this is a system call. 5.11.25.3. Return ValueOn success, 0 is returned. On error, 1 is returned, and ERRNO is set appropriately. 5.11.25.4. ErrorsDepending on the filesystem, other errors can be returned. The more general errors are listed here:
5.11.25.5. ERRNO(s) Not Implemented in Linux
Conforming ToSVr4, SVID, 4.4BSD, X/OPEN. This function is not part of POSIX.1. SVr4 documents additional EINTR, ENOLINK, and EMULTIHOP error conditions. X/OPEN does not document EIO, ENOMEM, or EFAULT error conditions. This interface is marked as legacy by X/OPEN. 5.11.26. fstatfs(), statfs()statfs returns information about a mounted filesystem. path is the path name of any file within the mounted filesystem. buf is a pointer to a statfs structure. Refer to the "Detail Comparison" section for the definition of statfs structure fstatfs returns the same information about an open file referenced by descriptor fd. 5.11.26.1. AIX/Linux Prototype#include <sys/vfs.h> int statfs(const char *path, struct statfs *buf); int fstatfs(int fd, struct statfs *buf); 5.11.26.2. Detail ComparisonFunctions are compatible. In AIX, the sys/vfs.h file includes sys/statfs.h. Although compatible, the definitions of struct statfs are not identical. Refer to the following struct to identify differences. Linuxstruct statfs { long f_type; /* type of filesystem (see below) */ long f_bsize; /* optimal transfer block size */ long f_blocks; /* total data blocks in file system */ long f_bfree; /* free blocks in fs */ long f_bavail; /* free blocks avail to non-superuser */ long f_files; /* total file nodes in file system */ long f_ffree; /* free file nodes in fs */ fsid_t f_fsid; /* file system id */ long f_namelen; /* maximum length of filenames */ long f_spare[6]; /* spare for later */ }; File system types: linux/affs_fs.h: AFFS_SUPER_MAGIC 0xADFF linux/efs_fs.h: EFS_SUPER_MAGIC 0x00414A53 linux/ext_fs.h: EXT_SUPER_MAGIC 0x137D linux/ext2_fs.h: EXT2_OLD_SUPER_MAGIC 0xEF51 EXT2_SUPER_MAGIC 0xEF53 linux/hpfs_fs.h: HPFS_SUPER_MAGIC 0xF995E849 linux/iso_fs.h: ISOFS_SUPER_MAGIC 0x9660 linux/minix_fs.h: MINIX_SUPER_MAGIC 0x137F /* orig. minix */ MINIX_SUPER_MAGIC2 0x138F /* 30 char minix */ MINIX2_SUPER_MAGIC 0x2468 /* minix V2 */ MINIX2_SUPER_MAGIC2 0x2478 /* minix V2, 30 char names */ linux/msdos_fs.h: MSDOS_SUPER_MAGIC 0x4d44 linux/ncp_fs.h: NCP_SUPER_MAGIC 0x564c linux/nfs_fs.h: NFS_SUPER_MAGIC 0x6969 linux/proc_fs.h: PROC_SUPER_MAGIC 0x9fa0 linux/smb_fs.h: SMB_SUPER_MAGIC 0x517B linux/sysv_fs.h: XENIX_SUPER_MAGIC 0x012FF7B4 SYSV4_SUPER_MAGIC 0x012FF7B5 SYSV2_SUPER_MAGIC 0x012FF7B6 COH_SUPER_MAGIC 0x012FF7B7 linux/ufs_fs.h: UFS_MAGIC 0x00011954 linux/xfs_fs.h: XFS_SUPER_MAGIC 0x58465342 linux/xia_fs.h: _XIAFS_SUPER_MAGIC 0x012FD16D AIXstruct statfs { int f_version; /* version/type of statfs, 0 for now */ int f_type; /* type of info, zero for now */ ulong_t f_bsize; /* optimal file system block size */ fsblkcnt_t f_blocks; /* total data blocks in file system */ fsblkcnt_t f_bfree; /* free block in fs */ fsblkcnt_t f_bavail; /* free blocks avail to non-superuser */ fsfilcnt_t f_files; /* total file nodes in file system */ fsfilcnt_t f_ffree; /* free file nodes in fs */ #if !defined(_KERNEL) && defined(__64BIT__) fsid64_t f_fsid; /* file system id */ #else fsid_t f_fsid; /* file system id */ #endif int f_vfstype; /* what type of vfs this is */ ulong_t f_fsize; /* fundamental file system block size */ int f_vfsnumber; /* vfs indentifier number */ int f_vfsoff; /* reserved, for vfs specific data offset */ int f_vfslen; /* reserved, for len of vfs specific data */ int f_vfsvers; /* reserved, for vers of vfs specific data * char f_fname[32]; /* file system name (usually mount pt.) */ char f_fpack[32]; /* file system pack name */ int f_name_max; /* maximum component name length for posix */ }; Fields that are undefined for a particular filesystem are set to 0. 5.11.26.3. Return ValueOn success, 0 is returned. On error, 1 is returned, and ERRNO is set appropriately. 5.11.26.4. ErrorsFor statfs:
For fstatfs:
5.11.26.5. ERRNO(s) Not Implemented in Linux
Conforming ToThe Linux statfs was inspired by the 4.4BSD statfs (but they do not use the same structure). 5.11.27. poll()poll() (alone with select()) indicates when a procedure is safe to execute on an open file descriptor without any delays. For instance, a programmer can use these calls to know when there is data to be read on a socket. By delegating responsibility to select() and poll(), you do not have to constantly check whether there is data to be read. Instead, select() and poll() can be placed in the background by the operating system and woken up when the event is satisfied or a specified timeout has elapsed. This process can significantly increase execution efficiency of a program. 5.11.27.1. AIX Prototype#include <sys/poll.h> int poll(void *ListPointer, unsigned long Nfdsmsgs, long Timeout); 5.11.27.2. Linux Prototype#include <sys/poll.h> int poll(struct pollfd *ufds, unsigned int nfds, int timeout); 5.11.27.3. Detail Comparison**Not Compatible** poll: wait for some event on a file descriptor. Functions are source-compatible, but the pollfd structs differ. For maximum performance and scalability, Linux introduced epoll in version 2.5, but in Linux 2.6 the function was deprecated and is no longer supported. AIXstruct pollist { struct pollfd fds[3]; struct pollmsg msgs[2]; } list; Linuxpoll is a variation on the theme of select. It specifies an array of nfds structures of the following type (and a timeout in milliseconds): struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ }; A negative value means infinite timeout. The field fd contains a file descriptor for an open file. The field events is an input parameter, a bitmask specifying the events the application is interested in. The field revents is an output parameter, filled by the kernel with the events that actually occurred, either of the type requested, or of one of the types POLLERR or POLLHUP or POLLNVAL. (These 3 bits are meaningless in the events field and are set in the revents field whenever the corresponding condition is true.) If none of the events requested (and no error) has occurred for any of the file descriptors, the kernel waits for timeout milliseconds for one of these events to occur. The following possible bits in these masks are defined in <sys/poll.h>: #define POLLIN 0x0001 /* There is data to read */ #define POLLPRI 0x0002 /* There is urgent data to read */ #define POLLOUT 0x0004 /* Writing now will not block */ #define POLLERR 0x0008 /* Error condition */ #define POLLHUP 0x0010 /* Hung up */ #define POLLNVAL 0x0020 /* Invalid request: fd not open */ In asm/poll.h, too, the values POLLRDNORM, POLLRDBAND, POLLWRNORM, POLLWRBAND, and POLLMSG are defined. 5.11.27.4. Return ValueOn success, a positive number is returned, where the number returned is the number of structures that have nonzero revents fields (in other words, those descriptors with events or errors reported). A value of 0 indicates that the call timed out and no file descriptors have been selected. On error, 1 is returned, and ERRNO is set appropriately. 5.11.27.5. Errors
5.11.27.6. ERRNO(s) Not Implemented in Linux
Conforming ToXPG4-UNIX 5.11.28. quotactl()The quotactl() call manipulates disk quotas. cmd indicates a command to be applied to UID id or GID id. To set the type of quota, use the QCMD(cmd, type) macro. special is a pointer to a null-terminated string containing the path name of the block special device for the filesystem being manipulated. addr is the address of an optional, command-specific data structure that is copied in or out of the system. The interpretation of addr is given with each of the following commands. 5.11.28.1. AIX Prototype#include <jfs/quota.h> int quotactl (char *Path, int Cmd, int ID, char *Addr); 5.11.28.2. Linux Prototype#include <sys/types.h> #include <sys/quota.h> int quotactl(int cmd, const char *special, qid_t id, caddr_t addr); 5.11.28.3. Detail Comparison**Not Compatible** The header is in a different location for AIX and Linux. The arguments are in a different order. The Linux cmd includes all the AIX commands as a subset plus their own. The remaining documentation is from the Linux man page.
The new quota format also allows following additional calls:
For XFS filesystems making use of the XFS Quota Manager (XQM), the preceding commands are bypassed and the following commands are used:
There is no command equivalent to Q_SYNC for XFS because sync writes quota information to disk (in addition to the other filesystem metadata it writes out). 5.11.28.4. Return Valuesquotactl() returns 0 on success and 1on failure and sets ERRNO to indicate the error. 5.11.28.5. Errors
If cmd is Q_QUOTAON, quotactl() may set ERRNO to the following:
|