T
his file documents the GNU C library.
This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of The GNU C Library Reference Manual, for Version 2.1 Beta.
Copyright (C) 1993, '94, '95, '96, '97, '98, '99 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the section entitled "GNU Library General Public License" is included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the text of the translation of the section entitled "GNU Library General Public License" must be approved for accuracy by the Foundation.
This is Edition 0.08 DRAFT, last updated 11 Jan 1999, of The GNU C Library Reference Manual, for Version 2.1 Beta of the GNU C Library.
Add-ons
Appendices
Indices
--- The Detailed Node Listing ---
Introduction
Standards and Portability
Using the Library
Error Reporting
Memory Allocation
malloc facility allows fully general
dynamic allocation.
Unconstrained Allocation
malloc.
malloc. xmalloc.
free to free a block you
got with malloc.
realloc to make a block
bigger or smaller.
calloc to allocate a
block and clear it.
memalign and valloc.
mallopt to adjust allocation
parameters.
malloc.
malloc and related functions.
Allocation Debugging
Obstacks
Variable Size Automatic
alloca.
alloca.
alloca.
Character Handling
String and Array Utilities
Argz and Envz Vectors
Character Set Handling
Restartable multibyte conversion
Non-reentrant Conversion
Generic Charset Conversion
iconv example.
iconv
Implementations.
iconv Implementation in the GNU C
library.
Locales
Locale Information
localeconv.
nl_langinfo.
The Lame Way to Locale Data
$).
Message Translation
catgets family of functions.
gettext family of functions.
Message catalogs a la X/Open
catgets function family.
catgets interface.
The Uniforum approach
gettext family of functions.
gettext.
Message catalogs with gettext
gettext works.
Searching and Sorting
bsearch function.
qsort function.
hsearch function.
tsearch function.
Pattern Matching
Globbing
glob.
glob.
glob.
Regular Expressions
regcomp to prepare to match.
regcomp.
regexec to match the compiled
pattern that you get from regcomp.
Word Expansion
wordexp.
wordexp.
I/O Overview
I/O Concepts
File Names
I/O on Streams
printf and related functions.
printf and friends.
scanf and related functions.
Unreading
ungetc to do unreading.
Formatted Output
vprintf and friends.
parse_printf_format.
Customizing Printf
register_printf_function
to register a new output conversion.
register_printf_function.
printf
handler function.
printf handlers.
Formatted Input
malloc the buffer.
vscanf and friends.
Stream Buffering
Other Kinds of Streams
Custom Streams
Formatted Messages
fmtmsg function.
fmtmsg and addseverity.
Low-Level I/O
Stream/Descriptor Precautions
Asynchronous I/O
File Status Flags
open.
File System Interface
Accessing Directories
File Attributes
Pipes and FIFOs
pipe function.
Sockets
Socket Addresses
struct sockaddr.
Local Namespace
Internet Namespace
Host Addresses
Open/Close Sockets
Connections
Transferring Data
send.
recv.
send and recv.
Datagrams
Inetd
Socket Options
Low-Level Terminal Interface
Terminal Modes
struct termios and
related types.
Special Characters
Pseudo-Terminals
Mathematics
Pseudo-Random Numbers
rand and friends.
random and friends.
drand48 and friends.
Arithmetic
Floating Point Errors
Arithmetic Functions
Parsing of Numbers
Date and Time
Processor Time
clock function.
times function.
Calendar Time
Parsing Date and Time
Non-Local Exits
Signal Handling
open,
read, write and other functions.
Concepts of Signals
Standard Signals
Signal Actions
signal function.
sigaction function.
Defining Handlers
Atomic Data Access
Generating Signals
kill.
kill for Communication.
Blocking Signals
Waiting for a Signal
pause.
BSD Signal Handling
Process Startup
Program Arguments
Parsing Program Arguments
getopt.
argp_parse.
mount.
Environment Variables
Program Termination
exit, a
process terminates normally.
exit status provides information
about why the process terminated.
abort function causes
abnormal program termination.
Processes
Job Control
Implementing a Shell
Functions for Job Control
Name Service Switch
NSS Configuration File
NSS Module Internals
Extending NSS
Users and Groups
User Accounting Database
User Database
Group Database
Netgroup Database
System Information
System Configuration
Sysconf
sysconf.
sysconf can read.
sysconf and the parameter
macros properly together.
Cryptographic Functions
POSIX Threads
Language Features
assert to abort if
something ``impossible'' happens.
NULL.
Variadic Functions
How Variadic
Data Type Measurements
Floating Type Macros
Installation
Maintenance
Porting
sysdeps hierarchy.
The C language provides no built-in facilities for performing such common operations as input/output, memory management, string manipulation, and the like. Instead, these facilities are defined in a standard library, which you compile and link with your programs.
The GNU C library, described in this document, defines all of the library functions that are specified by the ISO C standard, as well as additional features specific to POSIX and other derivatives of the Unix operating system, and extensions specific to the GNU system.
The purpose of this manual is to tell you how to use the facilities of the GNU library. We have mentioned which features belong to which standards to help you identify things that are potentially non-portable to other systems. But the emphasis in this manual is not on strict portability.
This manual is written with the assumption that you are at least somewhat familiar with the C programming language and basic programming concepts. Specifically, familiarity with ISO standard C (see ISO C), rather than "traditional" pre-ISO C dialects, is assumed.
The GNU C library includes several header files, each of which
provides definitions and declarations for a group of related facilities;
this information is used by the C compiler when processing your program.
For example, the header file stdio.h declares facilities for
performing input and output, and the header file string.h
declares string processing utilities. The organization of this manual
generally follows the same division as the header files.
If you are reading this manual for the first time, you should read all of the introductory material and skim the remaining chapters. There are a lot of functions in the GNU C library and it's not realistic to expect that you will be able to remember exactly how to use each and every one of them. It's more important to become generally familiar with the kinds of facilities that the library provides, so that when you are writing your programs you can recognize when to make use of library functions, and where in this manual you can find more specific information about them.
This section discusses the various standards and other sources that the GNU C library is based upon. These sources include the ISO C and POSIX standards, and the System V and Berkeley Unix implementations.
The primary focus of this manual is to tell you how to make effective use of the GNU library facilities. But if you are concerned about making your programs compatible with these standards, or portable to operating systems other than GNU, this can affect how you use the library. This section gives you an overview of these standards, so that you will know what they are when they are mentioned in other parts of the manual.
See Library Summary, for an alphabetical list of the functions and other symbols provided by the library. This list also states which standards each function or symbol comes from.
The GNU C library is compatible with the C standard adopted by the American National Standards Institute (ANSI): American National Standard X3.159-1989--"ANSI C" and later by the International Standardization Organization (ISO): ISO/IEC 9899:1990, "Programming languages--C". We here refer to the standard as ISO C since this is the more general standard in respect of ratification. The header files and library facilities that make up the GNU library are a superset of those specified by the ISO C standard.
If you are concerned about strict adherence to the ISO C standard, you
should use the -ansi option when you compile your programs with
the GNU C compiler. This tells the compiler to define only ISO
standard features from the library header files, unless you explicitly
ask for additional features. See Feature Test Macros, for
information on how to do this.
Being able to restrict the library to include only ISO C features is important because ISO C puts limitations on what names can be defined by the library implementation, and the GNU extensions don't fit these limitations. See Reserved Names, for more information about these restrictions.
This manual does not attempt to give you complete details on the differences between ISO C and older dialects. It gives advice on how to write programs to work portably under multiple C dialects, but does not aim for completeness.
The GNU library is also compatible with the ISO POSIX family of standards, known more formally as the Portable Operating System Interface for Computer Environments (ISO/IEC 9945). They were also published as ANSI/IEEE Std 1003. POSIX is derived mostly from various versions of the Unix operating system.
The library facilities specified by the POSIX standards are a superset of those required by ISO C; POSIX specifies additional features for ISO C functions, as well as specifying new additional functions. In general, the additional requirements and functionality defined by the POSIX standards are aimed at providing lower-level support for a particular kind of operating system environment, rather than general programming language support which can run in many diverse operating system environments.
The GNU C library implements all of the functions specified in ISO/IEC 9945-1:1996, the POSIX System Application Program Interface, commonly referred to as POSIX.1. The primary extensions to the ISO C facilities specified by this standard include file system interface primitives (see File System Interface), device-specific terminal control functions (see Low-Level Terminal Interface), and process control functions (see Processes).
Some facilities from ISO/IEC 9945-2:1993, the POSIX Shell and Utilities standard (POSIX.2) are also implemented in the GNU library. These include utilities for dealing with regular expressions and other pattern matching facilities (see Pattern Matching).
The GNU C library defines facilities from some versions of Unix which are not formally standardized, specifically from the 4.2 BSD, 4.3 BSD, and 4.4 BSD Unix systems (also known as Berkeley Unix) and from SunOS (a popular 4.2 BSD derivative that includes some Unix System V functionality). These systems support most of the ISO C and POSIX facilities, and 4.4 BSD and newer releases of SunOS in fact support them all.
The BSD facilities include symbolic links (see Symbolic Links), the
select function (see Waiting for I/O), the BSD signal
functions (see BSD Signal Handling), and sockets (see Sockets).
The System V Interface Description (SVID) is a document describing the AT&T Unix System V operating system. It is to some extent a superset of the POSIX standard (see POSIX).
The GNU C library defines most of the facilities required by the SVID that are not also required by the ISO C or POSIX standards, for compatibility with System V Unix and other Unix systems (such as SunOS) which include these facilities. However, many of the more obscure and less generally useful facilities required by the SVID are not included. (In fact, Unix System V itself does not provide them all.)
The supported facilities from System V include the methods for
inter-process communication and shared memory, the hsearch and
drand48 families of functions, fmtmsg and several of the
mathematical functions.
The X/Open Portability Guide, published by the X/Open Company, Ltd., is a more general standard than POSIX. X/Open owns the Unix copyright and the XPG specifies the requirements for systems which are intended to be a Unix system.
The GNU C library complies to the X/Open Portability Guide, Issue 4.2, with all extensions common to XSI (X/Open System Interface) compliant systems and also all X/Open UNIX extensions.
The additions on top of POSIX are mainly derived from functionality available in System V and BSD systems. Some of the really bad mistakes in System V systems were corrected, though. Since fulfilling the XPG standard with the Unix extensions is a precondition for getting the Unix brand chances are good that the functionality is available on commercial systems.
This section describes some of the practical issues involved in using the GNU C library.
Libraries for use by C programs really consist of two parts: header files that define types and macros and declare variables and functions; and the actual library or archive that contains the definitions of the variables and functions.
(Recall that in C, a declaration merely provides information that a function or variable exists and gives its type. For a function declaration, information about the types of its arguments might be provided as well. The purpose of declarations is to allow the compiler to correctly process references to the declared variables and functions. A definition, on the other hand, actually allocates storage for a variable or says what a function does.)
In order to use the facilities in the GNU C library, you should be sure that your program source files include the appropriate header files. This is so that the compiler has declarations of these facilities available and can correctly process references to them. Once your program has been compiled, the linker resolves these references to the actual definitions provided in the archive file.
Header files are included into a program source file by the
#include preprocessor directive. The C language supports two
forms of this directive; the first,
#include "header"
is typically used to include a header file header that you write yourself; this would contain definitions and declarations describing the interfaces between the different parts of your particular application. By contrast,
#include <file.h>
is typically used to include a header file file.h that contains
definitions and declarations for a standard library. This file would
normally be installed in a standard place by your system administrator.
You should use this second form for the C library header files.
Typically, #include directives are placed at the top of the C
source file, before any other code. If you begin your source files with
some comments explaining what the code in the file does (a good idea),
put the #include directives immediately afterwards, following the
feature test macro definition (see Feature Test Macros).
For more information about the use of header files and #include
directives, see Header Files.
The GNU C library provides several header files, each of which contains the type and macro definitions and variable and function declarations for a group of related facilities. This means that your programs may need to include several header files, depending on exactly which facilities you are using.
Some library header files include other library header files automatically. However, as a matter of programming style, you should not rely on this; it is better to explicitly include all the header files required for the library facilities you are using. The GNU C library header files have been written in such a way that it doesn't matter if a header file is accidentally included more than once; including a header file a second time has no effect. Likewise, if your program needs to include multiple header files, the order in which they are included doesn't matter.
Compatibility Note: Inclusion of standard header files in any order and any number of times works in any ISO C implementation. However, this has traditionally not been the case in many older C implementations.
Strictly speaking, you don't have to include a header file to use a function it declares; you could declare the function explicitly yourself, according to the specifications in this manual. But it is usually better to include the header file because it may define types and macros that are not otherwise available and because it may define more efficient macro replacements for some functions. It is also a sure way to have the correct declaration.
If we describe something as a function in this manual, it may have a macro definition as well. This normally has no effect on how your program runs--the macro definition does the same thing as the function would. In particular, macro equivalents for library functions evaluate arguments exactly once, in the same way that a function call would. The main reason for these macro definitions is that sometimes they can produce an inline expansion that is considerably faster than an actual function call.
Taking the address of a library function works even if it is also defined as a macro. This is because, in this context, the name of the function isn't followed by the left parenthesis that is syntactically necessary to recognize a macro call.
You might occasionally want to avoid using the macro definition of a function--perhaps to make your program easier to debug. There are two ways you can do this:
#undef preprocessor directive, unless otherwise stated
explicitly in the description of that facility.
For example, suppose the header file stdlib.h declares a function
named abs with
extern int abs (int);
and also provides a macro definition for abs. Then, in:
#include <stdlib.h>
int f (int *i) { return abs (++*i); }
the reference to abs might refer to either a macro or a function.
On the other hand, in each of the following examples the reference is
to a function and not a macro.
#include <stdlib.h>
int g (int *i) { return (abs) (++*i); }
#undef abs
int h (int *i) { return abs (++*i); }
Since macro definitions that double for a function behave in exactly the same way as the actual function version, there is usually no need for any of these methods. In fact, removing macro definitions usually just makes your program slower.
The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names. All other library names are reserved if your program explicitly includes the header file that defines or declares them. There are several reasons for these restrictions:
exit to do something completely different from
what the standard exit function does, for example. Preventing
this situation helps to make your programs easier to understand and
contributes to modularity and maintainability.
In addition to the names documented in this manual, reserved names
include all external identifiers (global functions and variables) that
begin with an underscore (_) and all identifiers regardless of
use that begin with either two underscores or an underscore followed by
a capital letter are reserved names. This is so that the library and
header files can define functions, variables, and macros for internal
purposes without risk of conflict with names in user programs.
Some additional classes of identifier names are reserved for future extensions to the C language or the POSIX.1 environment. While using these names for your own purposes right now might not cause a problem, they do raise the possibility of conflict with future versions of the C or POSIX standards, so you should avoid these names.
E followed a digit or uppercase
letter may be used for additional error code names. See Error Reporting.
is or to followed by a
lowercase letter may be used for additional character testing and
conversion functions. See Character Handling.
LC_ followed by an uppercase letter may be
used for additional macros specifying locale attributes.
See Locales.
f or l are reserved for corresponding
functions that operate on float and long double arguments,
respectively.
SIG followed by an uppercase letter are
reserved for additional signal names. See Standard Signals.
SIG_ followed by an uppercase letter are
reserved for additional signal actions. See Basic Signal Handling.
str, mem, or wcs followed by a
lowercase letter are reserved for additional string and array functions.
See String and Array Utilities.
_t are reserved for additional type names.
In addition, some individual header files reserve names beyond those that they actually define. You only need to worry about these restrictions if your program includes that particular header file.
dirent.h reserves names prefixed with
d_.
fcntl.h reserves names prefixed with
l_, F_, O_, and S_.
grp.h reserves names prefixed with gr_.
limits.h reserves names suffixed with _MAX.
pwd.h reserves names prefixed with pw_.
signal.h reserves names prefixed with sa_
and SA_.
sys/stat.h reserves names prefixed with st_
and S_.
sys/times.h reserves names prefixed with tms_.
termios.h reserves names prefixed with c_,
V, I, O, and TC; and names prefixed with
B followed by a digit.
The exact set of features available when you compile a source file is controlled by which feature test macros you define.
If you compile your programs using gcc -ansi, you get only the
ISO C library features, unless you explicitly request additional
features by defining one or more of the feature macros.
See Invoking GCC,
for more information about GCC options.
You should define these macros by using #define preprocessor
directives at the top of your source code files. These directives
must come before any #include of a system header file. It
is best to make them the very first thing in the file, preceded only by
comments. You could also use the -D option to GCC, but it's
better if you make the source files indicate their own meaning in a
self-contained way.
This system exists to allow the library to conform to multiple standards.
Although the different standards are often described as supersets of each
other, they are usually incompatible because larger standards require
functions with names that smaller ones reserve to the user program. This
is not mere pedantry -- it has been a problem in practice. For instance,
some non-GNU programs define functions named getline that have
nothing to do with this library's getline. They would not be
compilable if all features were enabled indiscriminately.
This should not be used to verify that a program conforms to a limited standard. It is insufficient for this purpose, as it will not protect you from including header files outside the standard, or relying on semantics undefined within the standard.
| _POSIX_SOURCE | Macro |
|
If you define this macro, then the functionality from the POSIX.1
standard (IEEE Standard 1003.1) is available, as well as all of the
ISO C facilities.
The state of |
| _POSIX_C_SOURCE | Macro |
|
Define this macro to a positive integer to control which POSIX
functionality is made available. The greater the value of this macro,
the more functionality is made available.
If you define this macro to a value greater than or equal to If you define this macro to a value greater than or equal to If you define this macro to a value greater than or equal to Greater values for The Single Unix Specification specify that setting this macro to the
value |
| _BSD_SOURCE | Macro |
|
If you define this macro, functionality derived from 4.3 BSD Unix is
included as well as the ISO C, POSIX.1, and POSIX.2 material.
Some of the features derived from 4.3 BSD Unix conflict with the corresponding features specified by the POSIX.1 standard. If this macro is defined, the 4.3 BSD definitions take precedence over the POSIX definitions. Due to the nature of some of the conflicts between 4.3 BSD and POSIX.1,
you need to use a special BSD compatibility library when linking
programs compiled for BSD compatibility. This is because some functions
must be defined in two different ways, one of them in the normal C
library, and one of them in the compatibility library. If your program
defines |
| _SVID_SOURCE | Macro |
| If you define this macro, functionality derived from SVID is included as well as the ISO C, POSIX.1, POSIX.2, and X/Open material. |
| _XOPEN_SOURCE | Macro |
| _XOPEN_SOURCE_EXTENDED | Macro |
If you define this macro, functionality described in the X/Open
Portability Guide is included. This is a superset of the POSIX.1 and
POSIX.2 functionality and in fact _POSIX_SOURCE and
_POSIX_C_SOURCE are automatically defined.
As the unification of all Unices, functionality only available in BSD and SVID is also included. If the macro If the macro |
| _LARGEFILE_SOURCE | Macro |
If this macro is defined some extra functions are available which
rectify a few shortcomings in all previous standards. More concrete
the functions fseeko and ftello are available. Without
these functions the difference between the ISO C interface
(fseek, ftell) and the low-level POSIX interface
(lseek) would lead to problems.
This macro was introduced as part of the Large File Support extension (LFS). |
| _LARGEFILE64_SOURCE | Macro |
|
If you define this macro an additional set of function gets available
which enables to use on 32 bit systems to use files of sizes beyond
the usual limit of 2GB. This interface is not available if the system
does not support files that large. On systems where the natural file
size limit is greater than 2GB (i.e., on 64 bit systems) the new
functions are identical to the replaced functions.
The new functionality is made available by a new set of types and
functions which replace existing. The names of these new objects
contain This macro was introduced as part of the Large File Support extension
(LFS). It is a transition interface for the time 64 bit offsets are
not generally used (see |
| _FILE_OFFSET_BITS | Macro |
This macro lets decide which file system interface shall be used, one
replacing the other. While _LARGEFILE64_SOURCE makes the 64 bit interface available as an additional interface
_FILE_OFFSET_BITS allows to use the 64 bit interface to
replace the old interface.
If If the macro is defined to the value This macro should only be selected if the system provides mechanisms for
handling large files. On 64 bit systems this macro has no effect
since the This macro was introduced as part of the Large File Support extension (LFS). |
| _GNU_SOURCE | Macro |
|
If you define this macro, everything is included: ISO C, POSIX.1,
POSIX.2, BSD, SVID, X/Open, LFS, and GNU extensions. In the cases where
POSIX.1 conflicts with BSD, the POSIX definitions take precedence.
If you want to get the full effect of #define _GNU_SOURCE #define _BSD_SOURCE #define _SVID_SOURCE Note that if you do this, you must link your program with the BSD
compatibility library by passing the |
| _REENTRANT | Macro |
| _THREAD_SAFE | Macro |
|
If you define one of these macros, reentrant versions of several functions get
declared. Some of the functions are specified in POSIX.1c but many others
are only available on a few other systems or are unique to GNU libc.
The problem is that the standardization of the thread safe C library
interface still is behind.
Unlike on some other systems no special version of the C library must be used for linking. There is only one version but while compiling this it must have been specified to compile as thread safe. |
We recommend you use _GNU_SOURCE in new programs. If you don't
specify the -ansi option to GCC and don't define any of these
macros explicitly, the effect is the same as defining
_POSIX_C_SOURCE to 2 and _POSIX_SOURCE,
_SVID_SOURCE, and _BSD_SOURCE to 1.
When you define a feature test macro to request a larger class of features,
it is harmless to define in addition a feature test macro for a subset of
those features. For example, if you define _POSIX_C_SOURCE, then
defining _POSIX_SOURCE as well has no effect. Likewise, if you
define _GNU_SOURCE, then defining either _POSIX_SOURCE or
_POSIX_C_SOURCE or _SVID_SOURCE as well has no effect.
Note, however, that the features of _BSD_SOURCE are not a subset of
any of the other feature test macros supported. This is because it defines
BSD features that take precedence over the POSIX features that are
requested by the other macros. For this reason, defining
_BSD_SOURCE in addition to the other feature test macros does have
an effect: it causes the BSD features to take priority over the conflicting
POSIX features.
Here is an overview of the contents of the remaining chapters of this manual.
sizeof
operator and the symbolic constant NULL, how to write functions
accepting variable numbers of arguments, and constants describing the
ranges and other properties of the numerical types. There is also a simple
debugging mechanism which allows you to put assertions in your code, and
have diagnostic messages printed if the tests fail.
isspace) and functions for
performing case conversion.
FILE * objects). These are the normal C library functions
from stdio.h.
char data type.
setjmp and
longjmp functions. These functions provide a facility for
goto-like jumps which can jump from one function to another.
If you already know the name of the facility you are interested in, you can look it up in Library Summary. This gives you a summary of its syntax and a pointer to where you can find a more detailed description. This appendix is particularly useful if you just want to verify the order and type of arguments to a function, for example. It also tells you what standard or system each function, variable, or macro is derived from.
Many functions in the GNU C library detect and report error conditions, and sometimes your programs need to check for these error conditions. For example, when you open an input file, you should verify that the file was actually opened correctly, and print an error message or take other appropriate action if the call to the library function failed.
This chapter describes how the error reporting facility works. Your
program should include the header file errno.h to use this
facility.
Most library functions return a special value to indicate that they have
failed. The special value is typically -1, a null pointer, or a
constant such as EOF that is defined for that purpose. But this
return value tells you only that an error has occurred. To find out
what kind of error it was, you need to look at the error code stored in the
variable errno. This variable is declared in the header file
errno.h.
| volatile int errno | Variable |
The variable errno contains the system error number. You can
change the value of errno.
Since The initial value of Many library functions can set Portability Note: ISO C specifies There are a few library functions, like |
All the error codes have symbolic names; they are macros defined in
errno.h. The names start with E and an upper-case
letter or digit; you should consider names of this form to be
reserved names. See Reserved Names.
The error code values are all positive integers and are all distinct,
with one exception: EWOULDBLOCK and EAGAIN are the same.
Since the values are distinct, you can use them as labels in a
switch statement; just don't use both EWOULDBLOCK and
EAGAIN. Your program should not make any other assumptions about
the specific values of these symbolic constants.
The value of errno doesn't necessarily have to correspond to any
of these macros, since some library functions might return other error
codes of their own for other situations. The only values that are
guaranteed to be meaningful for a particular library function are the
ones that this manual lists for that function.
On non-GNU systems, almost any system call can return EFAULT if
it is given an invalid pointer as an argument. Since this could only
happen as a result of a bug in your program, and since it will not
happen on the GNU system, we have saved space by not mentioning
EFAULT in the descriptions of individual functions.
In some Unix systems, many system calls can also return EFAULT if
given as an argument a pointer into the stack, and the kernel for some
obscure reason fails in its attempt to extend the stack. If this ever
happens, you should probably try using statically or dynamically
allocated memory instead of stack memory on that system.
The error code macros are defined in the header file errno.h.
All of them expand into integer constant values. Some of these error
codes can't occur on the GNU system, but they can occur using the GNU
library on other systems.
| int EPERM | Macro |
| Operation not permitted; only the owner of the file (or other resource) or processes with special privileges can perform the operation. |
| int ENOENT | Macro |
| No such file or directory. This is a "file doesn't exist" error for ordinary files that are referenced in contexts where they are expected to already exist. |
| int ESRCH | Macro |
| No process matches the specified process ID. |
| int EINTR | Macro |
|
Interrupted function call; an asynchronous signal occurred and prevented
completion of the call. When this happens, you should try the call
again.
You can choose to have functions resume after a signal that is handled,
rather than failing with |
| int EIO | Macro |
| Input/output error; usually used for physical read or write errors. |
| int ENXIO | Macro |
| No such device or address. The system tried to use the device represented by a file you specified, and it couldn't find the device. This can mean that the device file was installed incorrectly, or that the physical device is missing or not correctly attached to the computer. |
| int E2BIG | Macro |
Argument list too long; used when the arguments passed to a new program
being executed with one of the exec functions (see Executing a File) occupy too much memory space. This condition never arises in the
GNU system.
|
| int ENOEXEC | Macro |
Invalid executable file format. This condition is detected by the
exec functions; see Executing a File.
|
| int EBADF | Macro |
| Bad file descriptor; for example, I/O on a descriptor that has been closed or reading from a descriptor open only for writing (or vice versa). |
| int ECHILD | Macro |
| There are no child processes. This error happens on operations that are supposed to manipulate child processes, when there aren't any processes to manipulate. |
| int EDEADLK | Macro |
| Deadlock avoided; allocating a system resource would have resulted in a deadlock situation. The system does not guarantee that it will notice all such situations. This error means you got lucky and the system noticed; it might just hang. See File Locks, for an example. |
| int ENOMEM | Macro |
| No memory available. The system cannot allocate more virtual memory because its capacity is full. |
| int EACCES | Macro |
| Permission denied; the file permissions do not allow the attempted operation. |
| int EFAULT | Macro |
| Bad address; an invalid pointer was detected. In the GNU system, this error never happens; you get a signal instead. |
| int ENOTBLK | Macro |
| A file that isn't a block special file was given in a situation that requires one. For example, trying to mount an ordinary file as a file system in Unix gives this error. |
| int EBUSY | Macro |
| Resource busy; a system resource that can't be shared is already in use. For example, if you try to delete a file that is the root of a currently mounted filesystem, you get this error. |
| int EEXIST | Macro |
| File exists; an existing file was specified in a context where it only makes sense to specify a new file. |
| int EXDEV | Macro |
An attempt to make an improper link across file systems was detected.
This happens not only when you use link (see Hard Links) but
also when you rename a file with rename (see Renaming Files).
|
| int ENODEV | Macro |
| The wrong type of device was given to a function that expects a particular sort of device. |
| int ENOTDIR | Macro |
| A file that isn't a directory was specified when a directory is required. |
| int EISDIR | Macro |
| File is a directory; you cannot open a directory for writing, or create or remove hard links to it. |
| int EINVAL | Macro |
| Invalid argument. This is used to indicate various kinds of problems with passing the wrong argument to a library function. |
| int EMFILE | Macro |
|
The current process has too many files open and can't open any more.
Duplicate descriptors do count toward this limit.
In BSD and GNU, the number of open files is controlled by a resource
limit that can usually be increased. If you get this error, you might
want to increase the |
| int ENFILE | Macro |
| There are too many distinct file openings in the entire system. Note that any number of linked channels count as just one file opening; see Linked Channels. This error never occurs in the GNU system. |
| int ENOTTY | Macro |
| Inappropriate I/O control operation, such as trying to set terminal modes on an ordinary file. |
| int ETXTBSY | Macro |
| An attempt to execute a file that is currently open for writing, or write to a file that is currently being executed. Often using a debugger to run a program is considered having it open for writing and will cause this error. (The name stands for "text file busy".) This is not an error in the GNU system; the text is copied as necessary. |
| int EFBIG | Macro |
| File too big; the size of a file would be larger than allowed by the system. |
| int ENOSPC | Macro |
| No space left on device; write operation on a file failed because the disk is full. |
| int ESPIPE | Macro |
| Invalid seek operation (such as on a pipe). |
| int EROFS | Macro |
| An attempt was made to modify something on a read-only file system. |
| int EMLINK | Macro |
Too many links; the link count of a single file would become too large.
rename can cause this error if the file being renamed already has
as many links as it can take (see Renaming Files).
|
| int EPIPE | Macro |
Broken pipe; there is no process reading from the other end of a pipe.
Every library function that returns this error code also generates a
SIGPIPE signal; this signal terminates the program if not handled
or blocked. Thus, your program will never actually see EPIPE
unless it has handled or blocked SIGPIPE.
|
| int EDOM | Macro |
| Domain error; used by mathematical functions when an argument value does not fall into the domain over which the function is defined. |
| int ERANGE | Macro |
| Range error; used by mathematical functions when the result value is not representable because of overflow or underflow. |
| int EAGAIN | Macro |
Resource temporarily unavailable; the call might work if you try again
later. The macro EWOULDBLOCK is another name for EAGAIN;
they are always the same in the GNU C library.
This error can happen in a few different situations:
|
| int EWOULDBLOCK | Macro |
In the GNU C library, this is another name for EAGAIN (above).
The values are always the same, on every operating system.
C libraries in many older Unix systems have |
| int EINPROGRESS | Macro |
An operation that cannot complete immediately was initiated on an object
that has non-blocking mode selected. Some functions that must always
block (such as connect; see Connecting) never return
EAGAIN. Instead, they return EINPROGRESS to indicate that
the operation has begun and will take some time. Attempts to manipulate
the object before the call completes return EALREADY. You can
use the select function to find out when the pending operation
has completed; see Waiting for I/O.
|
| int EALREADY | Macro |
| An operation is already in progress on an object that has non-blocking mode selected. |
| int ENOTSOCK | Macro |
| A file that isn't a socket was specified when a socket is required. |
| int EMSGSIZE | Macro |
| The size of a message sent on a socket was larger than the supported maximum size. |
| int EPROTOTYPE | Macro |
| The socket type does not support the requested communications protocol. |
| int ENOPROTOOPT | Macro |
| You specified a socket option that doesn't make sense for the particular protocol being used by the socket. See Socket Options. |
| int EPROTONOSUPPORT | Macro |
| The socket domain does not support the requested communications protocol (perhaps because the requested protocol is completely invalid). See Creating a Socket. |
| int ESOCKTNOSUPPORT | Macro |
| The socket type is not supported. |
| int EOPNOTSUPP | Macro |
| The operation you requested is not supported. Some socket functions don't make sense for all types of sockets, and others may not be implemented for all communications protocols. In the GNU system, this error can happen for many calls when the object does not support the particular operation; it is a generic indication that the server knows nothing to do for that call. |
| int EPFNOSUPPORT | Macro |
| The socket communications protocol family you requested is not supported. |
| int EAFNOSUPPORT | Macro |
| The address family specified for a socket is not supported; it is inconsistent with the protocol being used on the socket. See Sockets. |
| int EADDRINUSE | Macro |
| The requested socket address is already in use. See Socket Addresses. |
| int EADDRNOTAVAIL | Macro |
| The requested socket address is not available; for example, you tried to give a socket a name that doesn't match the local host name. See Socket Addresses. |
| int ENETDOWN | Macro |
| A socket operation failed because the network was down. |
| int ENETUNREACH | Macro |
| A socket operation failed because the subnet containing the remote host was unreachable. |
| int ENETRESET | Macro |
| A network connection was reset because the remote host crashed. |
| int ECONNABORTED | Macro |
| A network connection was aborted locally. |
| int ECONNRESET | Macro |
| A network connection was closed for reasons outside the control of the local host, such as by the remote machine rebooting or an unrecoverable protocol violation. |
| int ENOBUFS | Macro |
The kernel's buffers for I/O operations are all in use. In GNU, this
error is always synonymous with ENOMEM; you may get one or the
other from network operations.
|
| int EISCONN | Macro |
| You tried to connect a socket that is already connected. See Connecting. |
| int ENOTCONN | Macro |
The socket is not connected to anything. You get this error when you
try to transmit data over a socket, without first specifying a
destination for the data. For a connectionless socket (for datagram
protocols, such as UDP), you get EDESTADDRREQ instead.
|
| int EDESTADDRREQ | Macro |
No default destination address was set for the socket. You get this
error when you try to transmit data over a connectionless socket,
without first specifying a destination for the data with connect.
|
| int ESHUTDOWN | Macro |
| The socket has already been shut down. |
| int ETOOMANYREFS | Macro |
| ??? |
| int ETIMEDOUT | Macro |
| A socket operation with a specified timeout received no response during the timeout period. |
| int ECONNREFUSED | Macro |
| A remote host refused to allow the network connection (typically because it is not running the requested service). |
| int ELOOP | Macro |
| Too many levels of symbolic links were encountered in looking up a file name. This often indicates a cycle of symbolic links. |
| int ENAMETOOLONG | Macro |
Filename too long (longer than PATH_MAX; see Limits for Files) or host name too long (in gethostname or
sethostname; see Host Identification).
|
| int EHOSTDOWN | Macro |
| The remote host for a requested network connection is down. |
| int EHOSTUNREACH | Macro |
| The remote host for a requested network connection is not reachable. |
| int ENOTEMPTY | Macro |
| Directory not empty, where an empty directory was expected. Typically, this error occurs when you are trying to delete a directory. |
| int EPROCLIM | Macro |
This means that the per-user limit on new process would be exceeded by
an attempted fork. See Limits on Resources, for details on
the RLIMIT_NPROC limit.
|
| int EUSERS | Macro |
| The file quota system is confused because there are too many users. |
| int EDQUOT | Macro |
| The user's disk quota was exceeded. |
| int ESTALE | Macro |
| Stale NFS file handle. This indicates an internal confusion in the NFS system which is due to file system rearrangements on the server host. Repairing this condition usually requires unmounting and remounting the NFS file system on the local host. |
| int EREMOTE | Macro |
| An attempt was made to NFS-mount a remote file system with a file name that already specifies an NFS-mounted file. (This is an error on some operating systems, but we expect it to work properly on the GNU system, making this error code impossible.) |
| int EBADRPC | Macro |
| ??? |
| int ERPCMISMATCH | Macro |
| ??? |
| int EPROGUNAVAIL | Macro |
| ??? |
| int EPROGMISMATCH | Macro |
| ??? |
| int EPROCUNAVAIL | Macro |
| ??? |
| int ENOLCK | Macro |
| No locks available. This is used by the file locking facilities; see File Locks. This error is never generated by the GNU system, but it can result from an operation to an NFS server running another operating system. |
| int EFTYPE | Macro |
|
Inappropriate file type or format. The file was the wrong type for the
operation, or a data file had the wrong format.
On some systems |
| int EAUTH | Macro |
| ??? |
| int ENEEDAUTH | Macro |
| ??? |
| int ENOSYS | Macro |
Function not implemented. This indicates that the function called is
not implemented at all, either in the C library itself or in the
operating system. When you get this error, you can be sure that this
particular function will always fail with ENOSYS unless you
install a new version of the C library or the operating system.
|
| int ENOTSUP | Macro |
|
Not supported. A function returns this error when certain parameter
values are valid, but the functionality they request is not available.
This can mean that the function does not implement a particular command
or option value or flag bit at all. For functions that operate on some
object given in a parameter, such as a file descriptor or a port, it
might instead mean that only that specific object (file
descriptor, port, etc.) is unable to support the other parameters given;
different file descriptors might support different ranges of parameter
values.
If the entire function is not available at all in the implementation,
it returns |
| int EILSEQ | Macro |
| While decoding a multibyte character the function came along an invalid or an incomplete sequence of bytes or the given wide character is invalid. |
| int EBACKGROUND | Macro |
In the GNU system, servers supporting the term protocol return
this error for certain operations when the caller is not in the
foreground process group of the terminal. Users do not usually see this
error because functions such as read and write translate
it into a SIGTTIN or SIGTTOU signal. See Job Control,
for information on process groups and these signals.
|
| int EDIED | Macro |
| In the GNU system, opening a file returns this error when the file is translated by a program and the translator program dies while starting up, before it has connected to the file. |
| int ED | Macro |
| The experienced user will know what is wrong. |
| int EGREGIOUS | Macro |
| You did what? |
| int EIEIO | Macro |
| Go home and have a glass of warm, dairy-fresh milk. |
| int EGRATUITOUS | Macro |
| This error code has no purpose. |
| int EBADMSG | Macro |
| int EIDRM | Macro |
| int EMULTIHOP | Macro |
| int ENODATA | Macro |
| int ENOLINK | Macro |
| int ENOMSG | Macro |
| int ENOSR | Macro |
| int ENOSTR | Macro |
| int EOVERFLOW | Macro |
| int EPROTO | Macro |
| int ETIME | Macro |
The following error codes are defined by the Linux/i386 kernel. They are not yet documented.
| int ERESTART | Macro |
| int ECHRNG | Macro |
| int EL2NSYNC | Macro |
| int EL3HLT | Macro |
| int EL3RST | Macro |
| int ELNRNG | Macro |
| int EUNATCH | Macro |
| int ENOCSI | Macro |
| int EL2HLT | Macro |
| int EBADE | Macro |
| int EBADR | Macro |
| int EXFULL | Macro |
| int ENOANO | Macro |
| int EBADRQC | Macro |
| int EBADSLT | Macro |
| int EDEADLOCK | Macro |
| int EBFONT | Macro |
| int ENONET | Macro |
| int ENOPKG | Macro |
| int EADV | Macro |
| int ESRMNT | Macro |
| int ECOMM | Macro |
| int EDOTDOT | Macro |
| int ENOTUNIQ | Macro |
| int EBADFD | Macro |
| int EREMCHG | Macro |
| int ELIBACC | Macro |
| int ELIBBAD | Macro |
| int ELIBSCN | Macro |
| int ELIBMAX | Macro |
| int ELIBEXEC | Macro |
| int ESTRPIPE | Macro |
| int EUCLEAN | Macro |
| int ENOTNAM | Macro |
| int ENAVAIL | Macro |
| int EISNAM | Macro |
| int EREMOTEIO | Macro |
| int ENOMEDIUM | Macro |
| int EMEDIUMTYPE | Macro |
The library has functions and variables designed to make it easy for
your program to report informative error messages in the customary
format about the failure of a library call. The functions
strerror and perror give you the standard error message
for a given error code; the variable
program_invocation_short_name gives you convenient access to the
name of the program that encountered the error.
| char * strerror (int errnum) | Function |
The strerror function maps the error code (see Checking for Errors) specified by the errnum argument to a descriptive error
message string. The return value is a pointer to this string.
The value errnum normally comes from the variable You should not modify the string returned by The function |
| char * strerror_r (int errnum, char *buf, size_t n) | Function |
The strerror_r function works like strerror but instead of
returning the error message in a statically allocated buffer shared by
all threads in the process, it returns a private copy for the
thread. This might be either some permanent global data or a message
string in the user supplied buffer starting at buf with the
length of n bytes.
At most n characters are written (including the NUL byte) so it is up to the user to select the buffer large enough. This function should always be used in multi-threaded programs since
there is no way to guarantee the string returned by This function |
| void perror (const char *message) | Function |
This function prints an error message to the stream stderr;
see Standard Streams.
If you call If you supply a non-null message argument, then The function |
strerror and perror produce the exact same message for any
given error code; the precise text varies from system to system. On the
GNU system, the messages are fairly short; there are no multi-line
messages or embedded newlines. Each error message begins with a capital
letter and does not include any terminating punctuation.
Compatibility Note: The strerror function is a new
feature of ISO C. Many older C systems do not support this function
yet.
Many programs that don't read input from the terminal are designed to
exit if any system call fails. By convention, the error message from
such a program should start with the program's name, sans directories.
You can find that name in the variable
program_invocation_short_name; the full file name is stored the
variable program_invocation_name:
| char * program_invocation_name | Variable |
This variable's value is the name that was used to invoke the program
running in the current process. It is the same as argv[0]. Note
that this is not necessarily a useful file name; often it contains no
directory names. See Program Arguments.
|
| char * program_invocation_short_name | Variable |
This variable's value is the name that was used to invoke the program
running in the current process, with directory names removed. (That is
to say, it is the same as program_invocation_name minus
everything up to the last slash, if any.)
|
The library initialization code sets up both of these variables before
calling main.
Portability Note: These two variables are GNU extensions. If
you want your program to work with non-GNU libraries, you must save the
value of argv[0] in main, and then strip off the directory
names yourself. We added these extensions to make it possible to write
self-contained error-reporting subroutines that require no explicit
cooperation from main.
Here is an example showing how to handle failure to open a file
correctly. The function open_sesame tries to open the named file
for reading and returns a stream if successful. The fopen
library function returns a null pointer if it couldn't open the file for
some reason. In that situation, open_sesame constructs an
appropriate error message using the strerror function, and
terminates the program. If we were going to make some other library
calls before passing the error code to strerror, we'd have to
save it in a local variable instead, because those other library
functions might overwrite errno in the meantime.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *
open_sesame (char *name)
{
FILE *stream;
errno = 0;
stream = fopen (name, "r");
if (stream == NULL)
{
fprintf (stderr, "%s: Couldn't open file %s; %s\n",
program_invocation_short_name, name, strerror (errno));
exit (EXIT_FAILURE);
}
else
return stream;
}
The GNU system provides several methods for allocating memory space under explicit program control. They vary in generality and in efficiency.
malloc facility allows fully general
dynamic allocation.
Dynamic memory allocation is a technique in which programs determine as they are running where to store some information. You need dynamic allocation when the number of memory blocks you need, or how long you continue to need them, depends on the data you are working on.
For example, you may need a block to store a line read from an input file; since there is no limit to how long a line can be, you must allocate the storage dynamically and make it dynamically larger as you read more of the line.
Or, you may need a block for each record or each definition in the input data; since you can't know in advance how many there will be, you must allocate a new block for each record or definition as you read it.
When you use dynamic allocation, the allocation of a block of memory is an action that the program requests explicitly. You call a function or macro when you want to allocate space, and specify the size with an argument. If you want to free the space, you do so by calling another function or macro. You can do these things whenever you want, as often as you want.
The C language supports two kinds of memory allocation through the variables in C programs:
In GNU C, the length of the automatic storage can be an expression that varies. In other C implementations, it must be a constant.
Dynamic allocation is not supported by C variables; there is no storage class "dynamic", and there can never be a C variable whose value is stored in dynamically allocated space. The only way to refer to dynamically allocated space is through a pointer. Because it is less convenient, and because the actual process of dynamic allocation requires more computation time, programmers generally use dynamic allocation only when neither static nor automatic allocation will serve.
For example, if you want to allocate dynamically some space to hold a
struct foobar, you cannot declare a variable of type struct
foobar whose contents are the dynamically allocated space. But you can
declare a variable of pointer type struct foobar * and assign it the
address of the space. Then you can use the operators * and
-> on this pointer variable to refer to the contents of the space:
{
struct foobar *ptr
= (struct foobar *) malloc (sizeof (struct foobar));
ptr->name = x;
ptr->next = current_foobar;
current_foobar = ptr;
}
The most general dynamic allocation facility is malloc. It
allows you to allocate blocks of memory of any size at any time, make
them bigger or smaller at any time, and free the blocks individually at
any time (or never).
malloc.
malloc. xmalloc.
free to free a block you
got with malloc.
realloc to make a block
bigger or smaller.
calloc to allocate a
block and clear it.
memalign and valloc.
mallopt to adjust allocation
parameters.
malloc.
malloc and related functions.
To allocate a block of memory, call malloc. The prototype for
this function is in stdlib.h.
| void * malloc (size_t size) | Function |
| This function returns a pointer to a newly allocated block size bytes long, or a null pointer if the block could not be allocated. |
The contents of the block are undefined; you must initialize it yourself
(or use calloc instead; see Allocating Cleared Space).
Normally you would cast the value as a pointer to the kind of object
that you want to store in the block. Here we show an example of doing
so, and of initializing the space with zeros using the library function
memset (see Copying and Concatenation):
struct foo *ptr; ... ptr = (struct foo *) malloc (sizeof (struct foo)); if (ptr == 0) abort (); memset (ptr, 0, sizeof (struct foo));
You can store the result of malloc into any pointer variable
without a cast, because ISO C automatically converts the type
void * to another type of pointer when necessary. But the cast
is necessary in contexts other than assignment operators or if you might
want your code to run in traditional C.
Remember that when allocating space for a string, the argument to
malloc must be one plus the length of the string. This is
because a string is terminated with a null character that doesn't count
in the "length" of the string but does need space. For example:
char *ptr; ... ptr = (char *) malloc (length + 1);
See Representation of Strings, for more information about this.
mallocIf no more space is available, malloc returns a null pointer.
You should check the value of every call to malloc. It is
useful to write a subroutine that calls malloc and reports an
error if the value is a null pointer, returning only if the value is
nonzero. This function is conventionally called xmalloc. Here
it is:
void *
xmalloc (size_t size)
{
register void *value = malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
Here is a real example of using malloc (by way of xmalloc).
The function savestring will copy a sequence of characters into
a newly allocated null-terminated string:
char *
savestring (const char *ptr, size_t len)
{
register char *value = (char *) xmalloc (len + 1);
value[len] = '\0';
return (char *) memcpy (value, ptr, len);
}
The block that malloc gives you is guaranteed to be aligned so
that it can hold any type of data. In the GNU system, the address is
always a multiple of eight on most systems, and a multiple of 16 on
64-bit systems. Only rarely is any higher boundary (such as a page
boundary) necessary; for those cases, use memalign or
valloc (see Aligned Memory Blocks).
Note that the memory located after the end of the block is likely to be
in use for something else; perhaps a block already allocated by another
call to malloc. If you attempt to treat the block as longer than
you asked for it to be, you are liable to destroy the data that
malloc uses to keep track of its blocks, or you may destroy the
contents of another block. If you have already allocated a block and
discover you want it to be bigger, use realloc (see Changing Block Size).
mallocWhen you no longer need a block that you got with malloc, use the
function free to make the block available to be allocated again.
The prototype for this function is in stdlib.h.
| void free (void *ptr) | Function |
The free function deallocates the block of storage pointed at
by ptr.
|
| void cfree (void *ptr) | Function |
This function does the same thing as free. It's provided for
backward compatibility with SunOS; you should use free instead.
|
Freeing a block alters the contents of the block. Do not expect to find any data (such as a pointer to the next block in a chain of blocks) in the block after freeing it. Copy whatever you need out of the block before freeing it! Here is an example of the proper way to free all the blocks in a chain, and the strings that they point to:
struct chain
{
struct chain *next;
char *name;
}
void
free_chain (struct chain *chain)
{
while (chain != 0)
{
struct chain *next = chain->next;
free (chain->name);
free (chain);
chain = next;
}
}
Occasionally, free can actually return memory to the operating
system and make the process smaller. Usually, all it can do is allow a
later call to malloc to reuse the space. In the meantime, the
space remains in your program as part of a free-list used internally by
malloc.
There is no point in freeing blocks at the end of a program, because all of the program's space is given back to the system when the process terminates.
Often you do not know for certain how big a block you will ultimately need at the time you must begin to use the block. For example, the block might be a buffer that you use to hold a line being read from a file; no matter how long you make the buffer initially, you may encounter a line that is longer.
You can make the block longer by calling realloc. This function
is declared in stdlib.h.
| void * realloc (void *ptr, size_t newsize) | Function |
The realloc function changes the size of the block whose address is
ptr to be newsize.
Since the space after the end of the block may be in use, If you pass a null pointer for ptr, |
Like malloc, realloc may return a null pointer if no
memory space is available to make the block bigger. When this happens,
the original block is untouched; it has not been modified or relocated.
In most cases it makes no difference what happens to the original block
when realloc fails, because the application program cannot continue
when it is out of memory, and the only thing to do is to give a fatal error
message. Often it is convenient to write and use a subroutine,
conventionally called xrealloc, that takes care of the error message
as xmalloc does for malloc:
void *
xrealloc (void *ptr, size_t size)
{
register void *value = realloc (ptr, size);
if (value == 0)
fatal ("Virtual memory exhausted");
return value;
}
You can also use realloc to make a block smaller. The reason you
would do this is to avoid tying up a lot of memory space when only a little
is needed.
In several allocation implementations, making a block smaller sometimes
necessitates copying it, so it can fail if no other space is available.
If the new size you specify is the same as the old size, realloc
is guaranteed to change nothing and return the same address that you gave.
The function calloc allocates memory and clears it to zero. It
is declared in stdlib.h.
| void * calloc (size_t count, size_t eltsize) | Function |
This function allocates a block long enough to contain a vector of
count elements, each of size eltsize. Its contents are
cleared to zero before calloc returns.
|
You could define calloc as follows:
void *
calloc (size_t count, size_t eltsize)
{
size_t size = count * eltsize;
void *value = malloc (size);
if (value != 0)
memset (value, 0, size);
return value;
}
But in general, it is not guaranteed that calloc calls
malloc internally. Therefore, if an application provides its own
malloc/realloc/free outside the C library, it
should always define calloc, too.
mallocAs opposed to other versions, the malloc in GNU libc does not
round up block sizes to powers of two, neither for large nor for small
sizes. Neighboring chunks can be coalesced on a free no matter
what their size is. This makes the implementation suitable for all
kinds of allocation patterns without generally incurring high memory
waste through fragmentation.
Very large blocks (much larger than a page) are allocated with
mmap (anonymous or via /dev/zero) by this implementation.
This has the great advantage that these chunks are returned to the
system immediately when they are freed. Therefore, it cannot happen
that a large chunk becomes "locked" in between smaller ones and even
after calling free wastes memory. The size threshold for
mmap to be used can be adjusted with mallopt. The use of
mmap can also be disabled completely.
The address of a block returned by malloc or realloc in
the GNU system is always a multiple of eight (or sixteen on 64-bit
systems). If you need a block whose address is a multiple of a higher
power of two than that, use memalign or valloc. These
functions are declared in stdlib.h.
With the GNU library, you can use free to free the blocks that
memalign and valloc return. That does not work in BSD,
however--BSD does not provide any way to free such blocks.
| void * memalign (size_t boundary, size_t size) | Function |
The memalign function allocates a block of size bytes whose
address is a multiple of boundary. The boundary must be a
power of two! The function memalign works by allocating a
somewhat larger block, and then returning an address within the block
that is on the specified boundary.
|
| void * valloc (size_t size) | Function |
Using valloc is like using memalign and passing the page size
as the value of the second argument. It is implemented like this:
void *
valloc (size_t size)
{
return memalign (getpagesize (), size);
}
|
You can adjust some parameters for dynamic memory allocation with the
mallopt function. This function is the general SVID/XPG
interface, defined in malloc.h.
| int mallopt (int param, int value) | Function |
When calling mallopt, the param argument specifies the
parameter to be set, and value the new value to be set. Possible
choices for param, as defined in malloc.h, are:
|
You can ask malloc to check the consistency of dynamic storage by
using the mcheck function. This function is a GNU extension,
declared in mcheck.h.
| int mcheck (void (*abortfn) (enum mcheck_status status)) | Function |
Calling mcheck tells malloc to perform occasional
consistency checks. These will catch things such as writing
past the end of a block that was allocated with malloc.
The abortfn argument is the function to call when an inconsistency
is found. If you supply a null pointer, then It is too late to begin allocation checking once you have allocated
anything with The easiest way to arrange to call (gdb) break main Breakpoint 1, main (argc=2, argv=0xbffff964) at whatever.c:10 (gdb) command 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >call mcheck(0) >continue >end (gdb) ... This will however only work if no initialization function of any object
involved calls any of the |
| enum mcheck_status mprobe (void *pointer) | Function |
The mprobe function lets you explicitly check for inconsistencies
in a particular allocated block. You must have already called
mcheck at the beginning of the program, to do its occasional
checks; calling mprobe requests an additional consistency check
to be done at the time of the call.
The argument pointer must be a pointer returned by |
| enum mcheck_status | Data Type |
This enumerated type describes what kind of inconsistency was detected
in an allocated block, if any. Here are the possible values:
|
Another possibility to check for and guard against bugs in the use of
malloc, realloc and free is to set the environment
variable MALLOC_CHECK_. When MALLOC_CHECK_ is set, a
special (less efficient) implementation is used which is designed to be
tolerant against simple errors, such as double calls of free with
the same argument, or overruns of a single byte (off-by-one bugs). Not
all such errors can be protected against, however, and memory leaks can
result. If MALLOC_CHECK_ is set to 0, any detected heap
corruption is silently ignored; if set to 1, a diagnostic is
printed on stderr; if set to 2, abort is called
immediately. This can be useful because otherwise a crash may happen
much later, and the true cause for the problem is then very hard to
track down.
So, what's the difference between using MALLOC_CHECK_ and linking
with -lmcheck? MALLOC_CHECK_ is orthogonal with respect to
-lmcheck. -lmcheck has been added for backward
compatibility. Both MALLOC_CHECK_ and -lmcheck should
uncover the same bugs - but using MALLOC_CHECK_ you don't need to
recompile your application.
The GNU C library lets you modify the behavior of malloc,
realloc, and free by specifying appropriate hook
functions. You can use these hooks to help you debug programs that use
dynamic storage allocation, for example.
The hook variables are declared in malloc.h.
| __malloc_hook | Variable |
The value of this variable is a pointer to function that malloc
uses whenever it is called. You should define this function to look
like malloc; that is, like:
void *function (size_t size, void *caller) The value of caller is the return address found on the stack when
the |
| __realloc_hook | Variable |
The value of this variable is a pointer to function that realloc
uses whenever it is called. You should define this function to look
like realloc; that is, like:
void *function (void *ptr, size_t size, void *caller) The value of caller is the return address found on the stack when
the |
| __free_hook | Variable |
The value of this variable is a pointer to function that free
uses whenever it is called. You should define this function to look
like free; that is, like:
void function (void *ptr, void *caller) The value of caller is the return address found on the stack when
the |
| __memalign_hook | Variable |
The value of this variable is a pointer to function that memalign
uses whenever it is called. You should define this function to look
like memalign; that is, like:
void *function (size_t size, size_t alignment) |
You must make sure that the function you install as a hook for one of these functions does not call that function recursively without restoring the old value of the hook first! Otherwise, your program will get stuck in an infinite recursion. Before calling the function recursively, one should make sure to restore all the hooks to their previous value. When coming back from the recursive call, all the hooks should be resaved since a hook might modify itself.
Here is an example showing how to use __malloc_hook and
__free_hook properly. It installs a function that prints out
information every time malloc or free is called. We just
assume here that realloc and memalign are not used in our
program.
/* Global variables used to hold underlaying hook values. */
static void *(*old_malloc_hook) (size_t);
static void (*old_free_hook) (void*);
/* Prototypes for our hooks. */
static void *my_malloc_hook (size_t);
static void my_free_hook(void*);
static void *
my_malloc_hook (size_t size)
{
void *result;
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/* Call recursively */
result = malloc (size);
/* Save underlaying hooks */
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
/* printf might call malloc, so protect it too. */
printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
/* Restore our own hooks */
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
return result;
}
static void *
my_free_hook (void *ptr)
{
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/* Call recursively */
free (ptr);
/* Save underlaying hooks */
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
/* printf might call free, so protect it too. */
printf ("freed pointer %p\n", ptr);
/* Restore our own hooks */
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
}
main ()
{
...
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
...
}
The mcheck function (see Heap Consistency Checking) works by
installing such hooks.
mallocYou can get information about dynamic storage allocation by calling the
mallinfo function. This function and its associated data type
are declared in malloc.h; they are an extension of the standard
SVID/XPG version.
| struct mallinfo | Data Type |
This structure type is used to return information about the dynamic
storage allocator. It contains the following members:
|
| struct mallinfo mallinfo (void) | Function |
This function returns information about the current dynamic memory usage
in a structure of type struct mallinfo.
|
malloc-Related FunctionsHere is a summary of the functions that work with malloc:
void *malloc (size_t size)
void free (void *addr)
malloc. See Freeing after Malloc.
void *realloc (void *addr, size_t size)
malloc larger or smaller,
possibly by copying it to a new location. See Changing Block Size.
void *calloc (size_t count, size_t eltsize)
malloc, and set its contents to zero. See Allocating Cleared Space.
void *valloc (size_t size)
void *memalign (size_t size, size_t boundary)
int mallopt (int param, int value)
int mcheck (void (*abortfn) (void))
malloc to perform occasional consistency checks on
dynamically allocated memory, and to call abortfn when an
inconsistency is found. See Heap Consistency Checking.
void *(*__malloc_hook) (size_t size, void *caller)
malloc uses whenever it is called.
void *(*__realloc_hook) (void *ptr, size_t size, void *caller)
realloc uses whenever it is called.
void (*__free_hook) (void *ptr, void *caller)
free uses whenever it is called.
void (*__memalign_hook) (size_t size, size_t alignment)
memalign uses whenever it is called.
struct mallinfo mallinfo (void)
An complicated task when programming with languages which do not use garbage collected dynamic memory allocation is to find memory leaks. Long running programs must assure that dynamically allocated objects are freed at the end of their lifetime. If this does not happen the system runs out of memory, sooner or later.
The malloc implementation in the GNU C library provides some
simple means to detect such leaks and provide some information to find
the location. To do this the application must be started in a special
mode which is enabled by an environment variable. There are no speed
penalties if the program is compiled in preparation of the debugging if
the debug mode is not enabled.
| void mtrace (void) | Function |
When the mtrace function is called it looks for an environment
variable named MALLOC_TRACE. This variable is supposed to
contain a valid file name. The user must have write access. If the
file already exists it is truncated. If the environment variable is not
set or it does not name a valid file which can be opened for writing
nothing is done. The behaviour of malloc etc. is not changed.
For obvious reasons this also happens if the application is install SUID
or SGID.
If the named file is successfully opened This function is a GNU extension and generally not available on other
systems. The prototype can be found in |
| void muntrace (void) | Function |
The muntrace function can be called after mtrace was used
to enable tracing the malloc calls. If no (successful) call of
mtrace was made muntrace does nothing.
Otherwise it deinstalls the handlers for This function is a GNU extension and generally not available on other
systems. The prototype can be found in |
Even though the tracing functionality does not influence the runtime
behaviour of the program it is no wise idea to call mtrace in all
programs. Just imagine you debug a program using mtrace and all
other programs used in the debug sessions also trace their malloc
calls. The output file would be the same for all programs and so is
unusable. Therefore one should call mtrace only if compiled for
debugging. A program could therefore start like this:
#include <mcheck.h>
int
main (int argc, char *argv[])
{
#ifdef DEBUGGING
mtrace ();
#endif
...
}
This is all what is needed if you want to trace the calls during the
whole runtime of the program. Alternatively you can stop the tracing at
any time with a call to muntrace. It is even possible to restart
the tracing again with a new call to mtrace. But this can course
unreliable results since there are possibly calls of the functions which
are not called. Please note that not only the application uses the
traced functions, also libraries (including the C library itself) use
this function.
This last point is also why it is no good idea to call muntrace
before the program terminated. The libraries are informed about the
termination of the program only after the program returns from
main or calls exit and so cannot free the memory they use
before this time.
So the best thing one can do is to call mtrace as the very first
function in the program and never call muntrace. So the program
traces almost all uses of the malloc functions (except those
calls which are executed by constructors of the program or used
libraries).
You know the situation. The program is prepared for debugging and in all debugging sessions it runs well. But once it is started without debugging the error shows up. In our situation here: the memory leaks becomes visible only when we just turned off the debugging. If you foresee such situations you can still win. Simply use something equivalent to the following little program:
#include <mcheck.h>
#include <signal.h>
static void
enable (int sig)
{
mtrace ();
signal (SIGUSR1, enable);
}
static void
disable (int sig)
{
muntrace ();
signal (SIGUSR2, disable);
}
int
main (int argc, char *argv[])
{
...
signal (SIGUSR1, enable);
signal (SIGUSR2, disable);
...
}
I.e., the user can start the memory debugger any time s/he wants if the
program was started with MALLOC_TRACE set in the environment.
The output will of course not show the allocations which happened before
the first signal but if there is a memory leak this will show up
nevertheless.
If you take a look at the output it will look similar to this:
= Start [0x8048209] - 0x8064cc8 [0x8048209] - 0x8064ce0 [0x8048209] - 0x8064cf8 [0x80481eb] + 0x8064c48 0x14 [0x80481eb] + 0x8064c60 0x14 [0x80481eb] + 0x8064c78 0x14 [0x80481eb] + 0x8064c90 0x14 = End
What this all means is not really important since the trace file is not
meant to be read by a human. Therefore no attention is payed to good
readability. Instead there is a program which comes with the GNU C
library which interprets the traces and outputs a summary in on
user-friendly way. The program is called mtrace (it is in fact a
Perl script) and it takes one or two arguments. In any case the name of
the file with the trace output must be specified. If an optional argument
precedes the name of the trace file this must be the name of the program
which generated the trace.
drepper$ mtrace tst-mtrace log No memory leaks.
In this case the program tst-mtrace was run and it produced a
trace file log. The message printed by mtrace shows there
are no problems with the code: all allocated memory was freed
afterwards.
If we call mtrace on the example trace given above we would get
different output:
drepper$ mtrace errlog - 0x08064cc8 Free 2 was never alloc'd 0x8048209 - 0x08064ce0 Free 3 was never alloc'd 0x8048209 - 0x08064cf8 Free 4 was never alloc'd 0x8048209 Memory not freed: ----------------- Address Size Caller 0x08064c48 0x14 at 0x80481eb 0x08064c60 0x14 at 0x80481eb 0x08064c78 0x14 at 0x80481eb 0x08064c90 0x14 at 0x80481eb
We have called mtrace with only one argument and so the script
has no chance to find out what is meant with the addresses given in the
trace. We can do better:
drepper$ mtrace tst-mtrace errlog - 0x08064cc8 Free 2 was never alloc'd /home/drepper/tst-mtrace.c:39 - 0x08064ce0 Free 3 was never alloc'd /home/drepper/tst-mtrace.c:39 - 0x08064cf8 Free 4 was never alloc'd /home/drepper/tst-mtrace.c:39 Memory not freed: ----------------- Address Size Caller 0x08064c48 0x14 at /home/drepper/tst-mtrace.c:33 0x08064c60 0x14 at /home/drepper/tst-mtrace.c:33 0x08064c78 0x14 at /home/drepper/tst-mtrace.c:33 0x08064c90 0x14 at /home/drepper/tst-mtrace.c:33
Suddenly the output makes much more sense and the user can see immediately where the function calls causing the trouble can be found.
Interpreting this output is not complicated. There are at most two
different situations being detected. First, free was called for
pointers which were never returned by one of the allocation functions.
This is usually a very bad problem and how this looks like is shown in
the first three lines of the output. Situations like this are quite
rare and if they appear they show up very drastically: the program
normally crashes.
The other situation which is much harder to detect are memory leaks. As
you can see in the output the mtrace function collects all this
information and so can say that the program calls an allocation function
from line 33 in the source file /home/drepper/tst-mtrace.c four
times without freeing this memory before the program terminates.
Whether this is a real problem keeps to be investigated.
An obstack is a pool of memory containing a stack of objects. You can create any number of separate obstacks, and then allocate objects in specified obstacks. Within each obstack, the last object allocated must always be the first one freed, but distinct obstacks are independent of each other.
Aside from this one constraint of order of freeing, obstacks are totally general: an obstack can contain any number of objects of any size. They are implemented with macros, so allocation is usually very fast as long as the objects are usually small. And the only space overhead per object is the padding needed to start each object on a suitable boundary.
The utilities for manipulating obstacks are declared in the header
file obstack.h.
| struct obstack | Data Type |
An obstack is represented by a data structure of type struct
obstack. This structure has a small fixed size; it records the status
of the obstack and how to find the space in which objects are allocated.
It does not contain any of the objects themselves. You should not try
to access the contents of the structure directly; use only the functions
described in this chapter.
|
You can declare variables of type struct obstack and use them as
obstacks, or you can allocate obstacks dynamically like any other kind
of object. Dynamic allocation of obstacks allows your program to have a
variable number of different stacks. (You can even allocate an
obstack structure in another obstack, but this is rarely useful.)
All the functions that work with obstacks require you to specify which
obstack to use. You do this with a pointer of type struct obstack
*. In the following, we often say "an obstack" when strictly
speaking the object at hand is such a pointer.
The objects in the obstack are packed into large blocks called
chunks. The struct obstack structure points to a chain of
the chunks currently in use.
The obstack library obtains a new chunk whenever you allocate an object
that won't fit in the previous chunk. Since the obstack library manages
chunks automatically, you don't need to pay much attention to them, but
you do need to supply a function which the obstack library should use to
get a chunk. Usually you supply a function which uses malloc
directly or indirectly. You must also supply a function to free a chunk.
These matters are described in the following section.
Each source file in which you plan to use the obstack functions
must include the header file obstack.h, like this:
#include <obstack.h>
Also, if the source file uses the macro obstack_init, it must
declare or define two functions or macros that will be called by the
obstack library. One, obstack_chunk_alloc, is used to allocate
the chunks of memory into which objects are packed. The other,
obstack_chunk_free, is used to return chunks when the objects in
them are freed. These macros should appear before any use of obstacks
in the source file.
Usually these are defined to use malloc via the intermediary
xmalloc (see Unconstrained Allocation). This is done with
the following pair of macro definitions:
#define obstack_chunk_alloc xmalloc #define obstack_chunk_free free
Though the storage you get using obstacks really comes from malloc,
using obstacks is faster because malloc is called less often, for
larger blocks of memory. See Obstack Chunks, for full details.
At run time, before the program can use a struct obstack object
as an obstack, it must initialize the obstack by calling
obstack_init.
| int obstack_init (struct obstack *obstack-ptr) | Function |
Initialize obstack obstack-ptr for allocation of objects. This
function calls the obstack's obstack_chunk_alloc function. If
allocation of memory fails, the function pointed to by
obstack_alloc_failed_handler is called. The obstack_init
function always returns 1 (Compatibility notice: Former versions of
obstack returned 0 if allocation failed).
|
Here are two examples of how to allocate the space for an obstack and initialize it. First, an obstack that is a static variable:
static struct obstack myobstack; ... obstack_init (&myobstack);
Second, an obstack that is itself dynamically allocated:
struct obstack *myobstack_ptr = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init (myobstack_ptr);
| obstack_alloc_failed_handler | Variable |
The value of this variable is a pointer to a function that
obstack uses when obstack_chunk_alloc fails to allocate
memory. The default action is to print a message and abort.
You should supply a function that either calls exit
(see Program Termination) or longjmp (see Non-Local Exits) and doesn't return.
void my_obstack_alloc_failed (void) ... obstack_alloc_failed_handler = &my_obstack_alloc_failed; |
The most direct way to allocate an object in an obstack is with
obstack_alloc, which is invoked almost like malloc.
| void * obstack_alloc (struct obstack *obstack-ptr, int size) | Function |
This allocates an uninitialized block of size bytes in an obstack
and returns its address. Here obstack-ptr specifies which obstack
to allocate the block in; it is the address of the struct obstack
object which represents the obstack. Each obstack function or macro
requires you to specify an obstack-ptr as the first argument.
This function calls the obstack's |
For example, here is a function that allocates a copy of a string str
in a specific obstack, which is in the variable string_obstack:
struct obstack string_obstack;
char *
copystring (char *string)
{
size_t len = strlen (string) + 1;
char *s = (char *) obstack_alloc (&string_obstack, len);
memcpy (s, string, len);
return s;
}
To allocate a block with specified contents, use the function
obstack_copy, declared like this:
| void * obstack_copy (struct obstack *obstack-ptr, void *address, int size) | Function |
This allocates a block and initializes it by copying size
bytes of data starting at address. It calls
obstack_alloc_failed_handler if allocation of memory by
obstack_chunk_alloc failed.
|
| void * obstack_copy0 (struct obstack *obstack-ptr, void *address, int size) | Function |
Like obstack_copy, but appends an extra byte containing a null
character. This extra byte is not counted in the argument size.
|
The obstack_copy0 function is convenient for copying a sequence
of characters into an obstack as a null-terminated string. Here is an
example of its use:
char *
obstack_savestring (char *addr, int size)
{
return obstack_copy0 (&myobstack, addr, size);
}
Contrast this with the previous example of savestring using
malloc (see Basic Allocation).
To free an object allocated in an obstack, use the function
obstack_free. Since the obstack is a stack of objects, freeing
one object automatically frees all other objects allocated more recently
in the same obstack.
| void obstack_free (struct obstack *obstack-ptr, void *object) | Function |
| If object is a null pointer, everything allocated in the obstack is freed. Otherwise, object must be the address of an object allocated in the obstack. Then object is freed, along with everything allocated in obstack since object. |
Note that if object is a null pointer, the result is an
uninitialized obstack. To free all storage in an obstack but leave it
valid for further allocation, call obstack_free with the address
of the first object allocated on the obstack:
obstack_free (obstack_ptr, first_object_allocated_ptr);
Recall that the objects in an obstack are grouped into chunks. When all the objects in a chunk become free, the obstack library automatically frees the chunk (see Preparing for Obstacks). Then other obstacks, or non-obstack allocation, can reuse the space of the chunk.
The interfaces for using obstacks may be defined either as functions or as macros, depending on the compiler. The obstack facility works with all C compilers, including both ISO C and traditional C, but there are precautions you must take if you plan to use compilers other than GNU C.
If you are using an old-fashioned non-ISO C compiler, all the obstack "functions" are actually defined only as macros. You can call these macros like functions, but you cannot use them in any other way (for example, you cannot take their address).
Calling the macros requires a special precaution: namely, the first operand (the obstack pointer) may not contain any side effects, because it may be computed more than once. For example, if you write this:
obstack_alloc (get_obstack (), 4);
you will find that get_obstack may be called several times.
If you use *obstack_list_ptr++ as the obstack pointer argument,
you will get very strange results since the incrementation may occur
several times.
In ISO C, each function has both a macro definition and a function definition. The function definition is used if you take the address of the function without calling it. An ordinary call uses the macro definition by default, but you can request the function definition instead by writing the function name in parentheses, as shown here:
char *x; void *(*funcp) (); /* Use the macro. */ x = (char *) obstack_alloc (obptr, size); /* Call the function. */ x = (char *) (obstack_alloc) (obptr, size); /* Take the address of the function. */ funcp = obstack_alloc;
This is the same situation that exists in ISO C for the standard library functions. See Macro Definitions.
Warning: When you do use the macros, you must observe the precaution of avoiding side effects in the first operand, even in ISO C.
If you use the GNU C compiler, this precaution is not necessary, because various language extensions in GNU C permit defining the macros so as to compute each argument only once.
Because storage in obstack chunks is used sequentially, it is possible to build up an object step by step, adding one or more bytes at a time to the end of the object. With this technique, you do not need to know how much data you will put in the object until you come to the end of it. We call this the technique of growing objects. The special functions for adding data to the growing object are described in this section.
You don't need to do anything special when you start to grow an object.
Using one of the functions to add data to the object automatically
starts it. However, it is necessary to say explicitly when the object is
finished. This is done with the function obstack_finish.
The actual address of the object thus built up is not known until the object is finished. Until then, it always remains possible that you will add so much data that the object must be copied into a new chunk.
While the obstack is in use for a growing object, you cannot use it for ordinary allocation of another object. If you try to do so, the space already added to the growing object will become part of the other object.
| void obstack_blank (struct obstack *obstack-ptr, int size) | Function |
The most basic function for adding to a growing object is
obstack_blank, which adds space without initializing it.
|
| void obstack_grow (struct obstack *obstack-ptr, void *data, int size) | Function |
To add a block of initialized space, use obstack_grow, which is
the growing-object analogue of obstack_copy. It adds size
bytes of data to the growing object, copying the contents from
data.
|
| void obstack_grow0 (struct obstack *obstack-ptr, void *data, int size) | Function |
This is the growing-object analogue of obstack_copy0. It adds
size bytes copied from data, followed by an additional null
character.
|
| void obstack_1grow (struct obstack *obstack-ptr, char c) | Function |
To add one character at a time, use the function obstack_1grow.
It adds a single byte containing c to the growing object.
|
| void obstack_ptr_grow (struct obstack *obstack-ptr, void *data) | Function |
Adding the value of a pointer one can use the function
obstack_ptr_grow. It adds sizeof (void *) bytes
containing the value of data.
|
| void obstack_int_grow (struct obstack *obstack-ptr, int data) | Function |
A single value of type int can be added by using the
obstack_int_grow function. It adds sizeof (int) bytes to
the growing object and initializes them with the value of data.
|
| void * obstack_finish (struct obstack *obstack-ptr) | Function |
When you are finished growing the object, use the function
obstack_finish to close it off and return its final address.
Once you have finished the object, the obstack is available for ordinary allocation or for growing another object. This function can return a null pointer under the same conditions as
|
When you build an object by growing it, you will probably need to know
afterward how long it became. You need not keep track of this as you grow
the object, because you can find out the length from the obstack just
before finishing the object with the function obstack_object_size,
declared as follows:
| int obstack_object_size (struct obstack *obstack-ptr) | Function |
This function returns the current size of the growing object, in bytes.
Remember to call this function before finishing the object.
After it is finished, obstack_object_size will return zero.
|
If you have started growing an object and wish to cancel it, you should finish it and then free it, like this:
obstack_free (obstack_ptr, obstack_finish (obstack_ptr));
This has no effect if no object was growing.
You can use obstack_blank with a negative size argument to make
the current object smaller. Just don't try to shrink it beyond zero
length--there's no telling what will happen if you do that.
The usual functions for growing objects incur overhead for checking whether there is room for the new growth in the current chunk. If you are frequently constructing objects in small steps of growth, this overhead can be significant.
You can reduce the overhead by using special "fast growth" functions that grow the object without checking. In order to have a robust program, you must do the checking yourself. If you do this checking in the simplest way each time you are about to add data to the object, you have not saved anything, because that is what the ordinary growth functions do. But if you can arrange to check less often, or check more efficiently, then you make the program faster.
The function obstack_room returns the amount of room available
in the current chunk. It is declared as follows:
| int obstack_room (struct obstack *obstack-ptr) | Function |
| This returns the number of bytes that can be added safely to the current growing object (or to an object about to be started) in obstack obstack using the fast growth functions. |
While you know there is room, you can use these fast growth functions for adding data to a growing object:
| void obstack_1grow_fast (struct obstack *obstack-ptr, char c) | Function |
The function obstack_1grow_fast adds one byte containing the
character c to the growing object in obstack obstack-ptr.
|
| void obstack_ptr_grow_fast (struct obstack *obstack-ptr, void *data) | Function |
The function obstack_ptr_grow_fast adds sizeof (void *)
bytes containing the value of data to the growing object in
obstack obstack-ptr.
|
| void obstack_int_grow_fast (struct obstack *obstack-ptr, int data) | Function |
The function obstack_int_grow_fast adds sizeof (int) bytes
containing the value of data to the growing object in obstack
obstack-ptr.
|
| void obstack_blank_fast (struct obstack *obstack-ptr, int size) | Function |
The function obstack_blank_fast adds size bytes to the
growing object in obstack obstack-ptr without initializing them.
|
When you check for space using obstack_room and there is not
enough room for what you want to add, the fast growth functions
are not safe. In this case, simply use the corresponding ordinary
growth function instead. Very soon this will copy the object to a
new chunk; then there will be lots of room available again.
So, each time you use an ordinary growth function, check afterward for
sufficient space using obstack_room. Once the object is copied
to a new chunk, there will be plenty of space again, so the program will
start using the fast growth functions again.
Here is an example:
void
add_string (struct obstack *obstack, const char *ptr, int len)
{
while (len > 0)
{
int room = obstack_room (obstack);
if (room == 0)
{
/* Not enough room. Add one character slowly,
which may copy to a new chunk and make room. */
obstack_1grow (obstack, *ptr++);
len--;
}
else
{
if (room > len)
room = len;
/* Add fast as much as we have room for. */
len -= room;
while (room-- > 0)
obstack_1grow_fast (obstack, *ptr++);
}
}
}
Here are functions that provide information on the current status of allocation in an obstack. You can use them to learn about an object while still growing it.
| void * obstack_base (struct obstack *obstack-ptr) | Function |
|
This function returns the tentative address of the beginning of the
currently growing object in obstack-ptr. If you finish the object
immediately, it will have that address. If you make it larger first, it
may outgrow the current chunk--then its address will change!
If no object is growing, this value says where the next object you allocate will start (once again assuming it fits in the current chunk). |
| void * obstack_next_free (struct obstack *obstack-ptr) | Function |
This function returns the address of the first free byte in the current
chunk of obstack obstack-ptr. This is the end of the currently
growing object. If no object is growing, obstack_next_free
returns the same value as obstack_base.
|
| int obstack_object_size (struct obstack *obstack-ptr) | Function |
This function returns the size in bytes of the currently growing object.
This is equivalent to
obstack_next_free (obstack-ptr) - obstack_base (obstack-ptr) |
Each obstack has an alignment boundary; each object allocated in the obstack automatically starts on an address that is a multiple of the specified boundary. By default, this boundary is 4 bytes.
To access an obstack's alignment boundary, use the macro
obstack_alignment_mask, whose function prototype looks like
this:
| int obstack_alignment_mask (struct obstack *obstack-ptr) | Macro |
|
The value is a bit mask; a bit that is 1 indicates that the corresponding
bit in the address of an object should be 0. The mask value should be one
less than a power of 2; the effect is that all object addresses are
multiples of that power of 2. The default value of the mask is 3, so that
addresses are multiples of 4. A mask value of 0 means an object can start
on any multiple of 1 (that is, no alignment is required).
The expansion of the macro obstack_alignment_mask (obstack_ptr) = 0; has the effect of turning off alignment processing in the specified obstack. |
Note that a change in alignment mask does not take effect until
after the next time an object is allocated or finished in the
obstack. If you are not growing an object, you can make the new
alignment mask take effect immediately by calling obstack_finish.
This will finish a zero-length object and then do proper alignment for
the next object.
Obstacks work by allocating space for themselves in large chunks, and then parceling out space in the chunks to satisfy your requests. Chunks are normally 4096 bytes long unless you specify a different chunk size. The chunk size includes 8 bytes of overhead that are not actually used for storing objects. Regardless of the specified size, longer chunks will be allocated when necessary for long objects.
The obstack library allocates chunks by calling the function
obstack_chunk_alloc, which you must define. When a chunk is no
longer needed because you have freed all the objects in it, the obstack
library frees the chunk by calling obstack_chunk_free, which you
must also define.
These two must be defined (as macros) or declared (as functions) in each
source file that uses obstack_init (see Creating Obstacks).
Most often they are defined as macros like this:
#define obstack_chunk_alloc malloc #define obstack_chunk_free free
Note that these are simple macros (no arguments). Macro definitions with
arguments will not work! It is necessary that obstack_chunk_alloc
or obstack_chunk_free, alone, expand into a function name if it is
not itself a function name.
If you allocate chunks with malloc, the chunk size should be a
power of 2. The default chunk size, 4096, was chosen because it is long
enough to satisfy many typical requests on the obstack yet short enough
not to waste too much memory in the portion of the last chunk not yet used.
| int obstack_chunk_size (struct obstack *obstack-ptr) | Macro |
| This returns the chunk size of the given obstack. |
Since this macro expands to an lvalue, you can specify a new chunk size by assigning it a new value. Doing so does not affect the chunks already allocated, but will change the size of chunks allocated for that particular obstack in the future. It is unlikely to be useful to make the chunk size smaller, but making it larger might improve efficiency if you are allocating many objects whose size is comparable to the chunk size. Here is how to do so cleanly:
if (obstack_chunk_size (obstack_ptr) < new-chunk-size) obstack_chunk_size (obstack_ptr) = new-chunk-size;
Here is a summary of all the functions associated with obstacks. Each
takes the address of an obstack (struct obstack *) as its first
argument.
void obstack_init (struct obstack *obstack-ptr)
void *obstack_alloc (struct obstack *obstack-ptr, int size)
void *obstack_copy (struct obstack *obstack-ptr, void *address, int size)
void *obstack_copy0 (struct obstack *obstack-ptr, void *address, int size)
void obstack_free (struct obstack *obstack-ptr, void *object)
void obstack_blank (struct obstack *obstack-ptr, int size)
void obstack_grow (struct obstack *obstack-ptr, void *address, int size)
void obstack_grow0 (struct obstack *obstack-ptr, void *address, int size)
void obstack_1grow (struct obstack *obstack-ptr, char data-char)
void *obstack_finish (struct obstack *obstack-ptr)
int obstack_object_size (struct obstack *obstack-ptr)
void obstack_blank_fast (struct obstack *obstack-ptr, int size)
void obstack_1grow_fast (struct obstack *obstack-ptr, char data-char)
int obstack_room (struct obstack *obstack-ptr)
int obstack_alignment_mask (struct obstack *obstack-ptr)
int obstack_chunk_size (struct obstack *obstack-ptr)
void *obstack_base (struct obstack *obstack-ptr)
void *obstack_next_free (struct obstack *obstack-ptr)
The function alloca supports a kind of half-dynamic allocation in
which blocks are allocated dynamically but freed automatically.
Allocating a block with alloca is an explicit action; you can
allocate as many blocks as you wish, and compute the size at run time. But
all the blocks are freed when you exit the function that alloca was
called from, just as if they were automatic variables declared in that
function. There is no way to free the space explicitly.
The prototype for alloca is in stdlib.h. This function is
a BSD extension.
| void * alloca (size_t size); | Function |
The return value of alloca is the address of a block of size
bytes of storage, allocated in the stack frame of the calling function.
|
Do not use alloca inside the arguments of a function call--you
will get unpredictable results, because the stack space for the
alloca would appear on the stack in the middle of the space for
the function arguments. An example of what to avoid is foo (x,
alloca (4), y).
alloca.
alloca.
alloca.
alloca ExampleAs an example of use of alloca, here is a function that opens a file
name made from concatenating two argument strings, and returns a file
descriptor or minus one signifying failure:
int
open2 (char *str1, char *str2, int flags, int mode)
{
char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
stpcpy (stpcpy (name, str1), str2);
return open (name, flags, mode);
}
Here is how you would get the same results with malloc and
free:
int
open2 (char *str1, char *str2, int flags, int mode)
{
char *name = (char *) malloc (strlen (str1) + strlen (str2) + 1);
int desc;
if (name == 0)
fatal ("virtual memory exceeded");
stpcpy (stpcpy (name, str1), str2);
desc = open (name, flags, mode);
free (name);
return desc;
}
As you can see, it is simpler with alloca. But alloca has
other, more important advantages, and some disadvantages.
allocaHere are the reasons why alloca may be preferable to malloc:
alloca wastes very little space and is very fast. (It is
open-coded by the GNU C compiler.)
alloca does not have separate pools for different sizes of
block, space used for any size block can be reused for any other size.
alloca does not cause storage fragmentation.
longjmp (see Non-Local Exits)
automatically free the space allocated with alloca when they exit
through the function that called alloca. This is the most
important reason to use alloca.
To illustrate this, suppose you have a function
open_or_report_error which returns a descriptor, like
open, if it succeeds, but does not return to its caller if it
fails. If the file cannot be opened, it prints an error message and
jumps out to the command level of your program using longjmp.
Let's change open2 (see Alloca Example) to use this
subroutine:
int
open2 (char *str1, char *str2, int flags, int mode)
{
char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
stpcpy (stpcpy (name, str1), str2);
return open_or_report_error (name, flags, mode);
}
Because of the way alloca works, the storage it allocates is
freed even when an error occurs, with no special effort required.
By contrast, the previous definition of open2 (which uses
malloc and free) would develop a storage leak if it were
changed in this way. Even if you are willing to make more changes to
fix it, there is no easy way to do so.
allocaThese are the disadvantages of alloca in comparison with
malloc:
alloca, so it is less
portable. However, a slower emulation of alloca written in C
is available for use on systems with this deficiency.
In GNU C, you can replace most uses of alloca with an array of
variable size. Here is how open2 would look then:
int open2 (char *str1, char *str2, int flags, int mode)
{
char name[strlen (str1) + strlen (str2) + 1];
stpcpy (stpcpy (name, str1), str2);
return open (name, flags, mode);
}
But alloca is not always equivalent to a variable-sized array, for
several reasons:
alloca
remains until the end of the function.
alloca within a loop, allocating an
additional block on each iteration. This is impossible with
variable-sized arrays.
Note: If you mix use of alloca and variable-sized arrays
within one function, exiting a scope in which a variable-sized array was
declared frees all blocks allocated with alloca during the
execution of that scope.
Programs that work with characters and strings often need to classify a
character--is it alphabetic, is it a digit, is it whitespace, and so
on--and perform case conversion operations on characters. The
functions in the header file ctype.h are provided for this
purpose.
Since the choice of locale and character set can alter the
classifications of particular character codes, all of these functions
are affected by the current locale. (More precisely, they are affected
by the locale currently selected for character classification--the
LC_CTYPE category; see Locale Categories.)
The ISO C standard specifies two different sets of functions. The
one set works on char type characters, the other one on
wchar_t wide character (see Extended Char Intro).
This section explains the library functions for classifying characters.
For example, isalpha is the function to test for an alphabetic
character. It takes one argument, the character to test, and returns a
nonzero integer if the character is alphabetic, and zero otherwise. You
would use it like this:
if (isalpha (c))
printf ("The character `%c' is alphabetic.\n", c);
Each of the functions in this section tests for membership in a
particular class of characters; each has a name starting with is.
Each of them takes one argument, which is a character to test, and
returns an int which is treated as a boolean value. The
character argument is passed as an int, and it may be the
constant value EOF instead of a real character.
The attributes of any given character can vary between locales. See Locales, for more information on locales.
These functions are declared in the header file ctype.h.
| int islower (int c) | Function |
| Returns true if c is a lower-case letter. The letter need not be from the Latin alphabet, any alphabet representable is valid. |
| int isupper (int c) | Function |
| Returns true if c is an upper-case letter. The letter need not be from the Latin alphabet, any alphabet representable is valid. |
| int isalpha (int c) | Function |
Returns true if c is an alphabetic character (a letter). If
islower or isupper is true of a character, then
isalpha is also true.
In some locales, there may be additional characters for which
|
| int isdigit (int c) | Function |
Returns true if c is a decimal digit (0 through 9).
|
| int isalnum (int c) | Function |
Returns true if c is an alphanumeric character (a letter or
number); in other words, if either isalpha or isdigit is
true of a character, then isalnum is also true.
|
| int isxdigit (int c) | Function |
Returns true if c is a hexadecimal digit.
Hexadecimal digits include the normal decimal digits 0 through
9 and the letters A through F and
a through f.
|
| int ispunct (int c) | Function |
| Returns true if c is a punctuation character. This means any printing character that is not alphanumeric or a space character. |
| int isspace (int c) | Function |
Returns true if c is a whitespace character. In the standard
"C" locale, isspace returns true for only the standard
whitespace characters:
|
| int isblank (int c) | Function |
| Returns true if c is a blank character; that is, a space or a tab. This function is a GNU extension. |
| int isgraph (int c) | Function |
| Returns true if c is a graphic character; that is, a character that has a glyph associated with it. The whitespace characters are not considered graphic. |
| int isprint (int c) | Function |
Returns true if c is a printing character. Printing characters
include all the graphic characters, plus the space ( ) character.
|
| int iscntrl (int c) | Function |
| Returns true if c is a control character (that is, a character that is not a printing character). |
| int isascii (int c) | Function |
Returns true if c is a 7-bit unsigned char value that fits
into the US/UK ASCII character set. This function is a BSD extension
and is also an SVID extension.
|
This section explains the library functions for performing conversions
such as case mappings on characters. For example, toupper
converts any character to upper case if possible. If the character
can't be converted, toupper returns it unchanged.
These functions take one argument of type int, which is the
character to convert, and return the converted character as an
int. If the conversion is not applicable to the argument given,
the argument is returned unchanged.
Compatibility Note: In pre-ISO C dialects, instead of
returning the argument unchanged, these functions may fail when the
argument is not suitable for the conversion. Thus for portability, you
may need to write islower(c) ? toupper(c) : c rather than just
toupper(c).
These functions are declared in the header file ctype.h.
| int tolower (int c) | Function |
If c is an upper-case letter, tolower returns the corresponding
lower-case letter. If c is not an upper-case letter,
c is returned unchanged.
|
| int toupper (int c) | Function |
If c is a lower-case letter, toupper returns the corresponding
upper-case letter. Otherwise c is returned unchanged.
|
| int toascii (int c) | Function |
This function converts c to a 7-bit unsigned char value
that fits into the US/UK ASCII character set, by clearing the high-order
bits. This function is a BSD extension and is also an SVID extension.
|
| int _tolower (int c) | Function |
This is identical to tolower, and is provided for compatibility
with the SVID. See SVID.
|
| int _toupper (int c) | Function |
This is identical to toupper, and is provided for compatibility
with the SVID.
|
The second amendment to ISO C89 defines functions to classify wide
character. Although the original ISO C89 standard already defined
the type wchar_t but no functions operating on them were defined.
The general design of the classification functions for wide characters
is more general. It allows to extend the set of available
classification beyond the set which is always available. The POSIX
standard specifies a way how the extension can be done and this is
already implemented in the GNU C library implementation of the
localedef program.
The character class functions are normally implemented using bitsets. I.e., for the character in question the appropriate bitset is read from a table and a test is performed whether a certain bit is set in this bitset. Which bit is tested for is determined by the class.
For the wide character classification functions this is made visible.
There is a type representing the classification, a function to retrieve
this value for a specific class, and a function to test using the
classification value whether a given character is in this class. On top
of this the normal character classification functions as used for
char objects can be defined.
| wctype_t | Data type |
The wctype_t can hold a value which represents a character class.
The only defined way to generate such a value is by using the
wctype function.
This type is defined in |
| wctype_t wctype (const char *property) | Function |
The wctype returns a value representing a class of wide
characters which is identified by the string property. Beside
some standard properties each locale can define its own ones. In case
no property with the given name is known for the current locale for the
LC_CTYPE category the function returns zero.
The properties known in every locale are:
This function is declared in |
To test the membership of a character to one of the non-standard classes the ISO C standard defines a completely new function.
| int iswctype (wint_t wc, wctype_t desc) | Function |
This function returns a nonzero value if wc is in the character
class specified by desc. desc must previously be returned
by a successful call to wctype.
This function is declared in |
The make it easier to use the commonly used classification functions
they are defined in the C library. There is no need to use
wctype is the property string is one of the known character
classes. In some situations it is desirable to construct the property
string and then it gets important that wctype can also handle the
standard classes.
| int iswalnum (wint_t wc) | Function |
This function returns a nonzero value if wc is an alphanumeric
character (a letter or number); in other words, if either iswalpha
or iswdigit is true of a character, then iswalnum is also
true.
This function can be implemented using iswctype (wc, wctype ("alnum"))
It is declared in |
| int iswalpha (wint_t wc) | Function |
Returns true if wc is an alphabetic character (a letter). If
iswlower or iswupper is true of a character, then
iswalpha is also true.
In some locales, there may be additional characters for which
This function can be implemented using iswctype (wc, wctype ("alpha"))
It is declared in |
| int iswcntrl (wint_t wc) | Function |
|
Returns true if wc is a control character (that is, a character that
is not a printing character).
This function can be implemented using iswctype (wc, wctype ("cntrl"))
It is declared in |
| int iswdigit (wint_t wc) | Function |
Returns true if wc is a digit (e.g., 0 through 9).
Please note that this function does not only return a nonzero value for
decimal digits, but for all kinds of digits. A consequence is
that code like the following will not work unconditionally for
wide characters:
n = 0;
while (iswctype (*wc))
{
n *= 10;
n += *wc++ - L'0';
}
This function can be implemented using iswctype (wc, wctype ("digit"))
It is declared in |
| int iswgraph (wint_t wc) | Function |
|
Returns true if wc is a graphic character; that is, a character
that has a glyph associated with it. The whitespace characters are not
considered graphic.
This function can be implemented using iswctype (wc, wctype ("graph"))
It is declared in |
| int iswlower (wint_t wc) | Function |
|
Returns true if wc is a lower-case letter. The letter need not be
from the Latin alphabet, any alphabet representable is valid.
This function can be implemented using iswctype (wc, wctype ("lower"))
It is declared in |
| int iswprint (wint_t wc) | Function |
Returns true if wc is a printing character. Printing characters
include all the graphic characters, plus the space ( ) character.
This function can be implemented using iswctype (wc, wctype ("print"))
It is declared in |
| int iswpunct (wint_t wc) | Function |
|
Returns true if wc is a punctuation character.
This means any printing character that is not alphanumeric or a space
character.
This function can be implemented using iswctype (wc, wctype ("punct"))
It is declared in |
| int iswspace (wint_t wc) | Function |
Returns true if wc is a whitespace character. In the standard
"C" locale, iswspace returns true for only the standard
whitespace characters:
This function can be implemented using iswctype (wc, wctype ("space"))
It is declared in |
| int iswupper (wint_t wc) | Function |
|
Returns true if wc is an upper-case letter. The letter need not be
from the Latin alphabet, any alphabet representable is valid.
This function can be implemented using iswctype (wc, wctype ("upper"))
It is declared in |
| int iswxdigit (wint_t wc) | Function |
Returns true if wc is a hexadecimal digit.
Hexadecimal digits include the normal decimal digits 0 through
9 and the letters A through F and
a through f.
This function can be implemented using iswctype (wc, wctype ("xdigit"))
It is declared in |
The GNu C library provides also a function which is not defined in the ISO C standard but which is available as a version for single byte characters as well.
| int iswblank (wint_t wc) | Function |
Returns true if wc is a blank character; that is, a space or a tab.
This function is a GNU extension. It is declared in wchar.h.
|
The first note is probably nothing astonishing but still occasionally a
cause of problems. The iswXXX functions can be implemented
using macros and in fact, the GNU C library does this. They are still
available as real functions but when the wctype.h header is
included the macros will be used. This is nothing new compared to the
char type versions of these functions.
The second notes covers something which is new. It can be best illustrated by a (real-world) example. The first piece of code is an excerpt from the original code. It is truncated a bit but the intention should be clear.
int
is_in_class (int c, const char *class)
{
if (strcmp (class, "alnum") == 0)
return isalnum (c);
if (strcmp (class, "alpha") == 0)
return isalpha (c);
if (strcmp (class, "cntrl") == 0)
return iscntrl (c);
...
return 0;
}
Now with the wctype and iswctype one could avoid the
if cascades. But rewriting the code as follows is wrong:
int
is_in_class (int c, const char *class)
{
wctype_t desc = wctype (class);
return desc ? iswctype ((wint_t) c, desc) : 0;
}
The problem is that it is not guarateed that the wide character representation of a single-byte character can be found using casting. In fact, usually this fails miserably. The correct solution for this problem is to write the code as follows:
int
is_in_class (int c, const char *class)
{
wctype_t desc = wctype (class);
return desc ? iswctype (btowc (c), desc) : 0;
}
See Converting a Character, for more information on btowc.
Please note that this change probably does not improve the performance
of the program a lot since the wctype function still has to make
the string comparisons. But it gets really interesting if the
is_in_class function would be called more than once using the
same class name. In this case the variable desc could be computed
once and reused for all the calls. Therefore the above form of the
function is probably not the final one.
As for the classification functions the ISO C standard also
generalizes the mapping functions. Instead of only allowing the two
standard mappings the locale can contain others. Again, the
localedef program already supports generating such locale data
files.
| wctrans_t | Data Type |
This data type is defined as a scalar type which can hold a value
representing the locale-dependent character mapping. There is no way to
construct such a value beside using the return value of the
wctrans function.
This type is defined in |
| wctrans_t wctrans (const char *property) | Function |
The wctrans function has to be used to find out whether a named
mapping is defined in the current locale selected for the
LC_CTYPE category. If the returned value is non-zero it can
afterwards be used in calls to towctrans. If the return value is
zero no such mapping is known in the current locale.
Beside locale-specific mappings there are two mappings which are guaranteed to be available in every locale:
This function is declared in |
| wint_t towctrans (wint_t wc, wctrans_t desc) | Function |
The towctrans function maps the input character wc
according to the rules of the mapping for which desc is an
descriptor and returns the so found value. The desc value must be
obtained by a successful call to wctrans.
This function is declared in |
The ISO C standard also defines for the generally available mappings
convenient shortcuts so that it is not necessary to call wctrans
for them.
| wint_t towlower (wint_t wc) | Function |
If wc is an upper-case letter, towlower returns the corresponding
lower-case letter. If wc is not an upper-case letter,
wc is returned unchanged.
towctrans (wc, wctrans ("tolower"))
This function is declared in |
| wint_t towupper (wint_t wc) | Function |
If wc is a lower-case letter, towupper returns the corresponding
upper-case letter. Otherwise wc is returned unchanged.
towctrans (wc, wctrans ("toupper"))
This function is declared in |
The same warnings given in the last section for the use of the wide
character classification function applies here. It is not possible to
simply cast a char type value to a wint_t and use it as an
argument for towctrans calls.
Operations on strings (or arrays of characters) are an important part of
many programs. The GNU C library provides an extensive set of string
utility functions, including functions for copying, concatenating,
comparing, and searching strings. Many of these functions can also
operate on arbitrary regions of storage; for example, the memcpy
function can be used to copy the contents of any kind of array.
It's fairly common for beginning C programmers to "reinvent the wheel" by duplicating this functionality in their own code, but it pays to become familiar with the library functions and to make use of them, since this offers benefits in maintenance, efficiency, and portability.
For instance, you could easily compare one string to another in two
lines of C code, but if you use the built-in strcmp function,
you're less likely to make a mistake. And, since these library
functions are typically highly optimized, your program may run faster
too.
This section is a quick summary of string concepts for beginning C programmers. It describes how character strings are represented in C and some common pitfalls. If you are already familiar with this material, you can skip this section.
A string is an array of char objects. But string-valued
variables are usually declared to be pointers of type char *.
Such variables do not include space for the text of a string; that has
to be stored somewhere else--in an array variable, a string constant,
or dynamically allocated memory (see Memory Allocation). It's up to
you to store the address of the chosen memory space into the pointer
variable. Alternatively you can store a null pointer in the
pointer variable. The null pointer does not point anywhere, so
attempting to reference the string it points to gets an error.
By convention, a null character, '\0', marks the end of a
string. For example, in testing to see whether the char *
variable p points to a null character marking the end of a string,
you can write !*p or *p == '\0'.
A null character is quite different conceptually from a null pointer,
although both are represented by the integer 0.
String literals appear in C program source as strings of
characters between double-quote characters ("). In ISO C,
string literals can also be formed by string concatenation:
"a" "b" is the same as "ab". Modification of string
literals is not allowed by the GNU C compiler, because literals
are placed in read-only storage.
Character arrays that are declared const cannot be modified
either. It's generally good style to declare non-modifiable string
pointers to be of type const char *, since this often allows the
C compiler to detect accidental modifications as well as providing some
amount of documentation about what your program intends to do with the
string.
The amount of memory allocated for the character array may extend past the null character that normally marks the end of the string. In this document, the term allocated size is always used to refer to the total amount of memory allocated for the string, while the term length refers to the number of characters up to (but not including) the terminating null character.
A notorious source of program bugs is trying to put more characters in a string than fit in its allocated size. When writing code that extends strings or moves characters into a pre-allocated array, you should be very careful to keep track of the length of the text and make explicit checks for overflowing the array. Many of the library functions do not do this for you! Remember also that you need to allocate an extra byte to hold the null character that marks the end of the string.
This chapter describes both functions that work on arbitrary arrays or blocks of memory, and functions that are specific to null-terminated arrays of characters.
Functions that operate on arbitrary blocks of memory have names
beginning with mem (such as memcpy) and invariably take an
argument which specifies the size (in bytes) of the block of memory to
operate on. The array arguments and return values for these functions
have type void *, and as a matter of style, the elements of these
arrays are referred to as "bytes". You can pass any kind of pointer
to these functions, and the sizeof operator is useful in
computing the value for the size argument.
In contrast, functions that operate specifically on strings have names
beginning with str (such as strcpy) and look for a null
character to terminate the string instead of requiring an explicit size
argument to be passed. (Some of these functions accept a specified
maximum length, but they also check for premature termination with a
null character.) The array arguments and return values for these
functions have type char *, and the array elements are referred
to as "characters".
In many cases, there are both mem and str versions of a
function. The one that is more appropriate to use depends on the exact
situation. When your program is manipulating arbitrary arrays or blocks of
storage, then you should always use the mem functions. On the
other hand, when you are manipulating null-terminated strings it is
usually more convenient to use the str functions, unless you
already know the length of the string in advance.
You can get the length of a string using the strlen function.
This function is declared in the header file string.h.
| size_t strlen (const char *s) | Function |
The strlen function returns the length of the null-terminated
string s. (In other words, it returns the offset of the terminating
null character within the array.)
For example, strlen ("hello, world")
=> 12
When applied to a character array, the char string[32] = "hello, world";
sizeof (string)
=> 32
strlen (string)
=> 12
But beware, this will not work unless string is the character array itself, not a pointer to it. For example: char string[32] = "hello, world";
char *ptr = string;
sizeof (string)
=> 32
sizeof (ptr)
=> 4 /* (on a machine with 4 byte pointers) */
This is an easy mistake to make when you are working with functions that take string arguments; those arguments are always pointers, not arrays. |
| size_t strnlen (const char *s, size_t maxlen) | Function |
The strnlen function returns the length of the null-terminated
string s is this length is smaller than maxlen. Otherwise
it returns maxlen. Therefore this function is equivalent to
(strlen (s) < n ? strlen (s) : maxlen) but it
is more efficient.
char string[32] = "hello, world";
strnlen (string, 32)
=> 12
strnlen (string, 5)
=> 5
This function is a GNU extension. |
You can use the functions described in this section to copy the contents
of strings and arrays, or to append the contents of one string to
another. These functions are declared in the header file
string.h.
A helpful way to remember the ordering of the arguments to the functions in this section is that it corresponds to an assignment expression, with the destination array specified to the left of the source array. All of these functions return the address of the destination array.
Most of these functions do not work properly if the source and destination arrays overlap. For example, if the beginning of the destination array overlaps the end of the source array, the original contents of that part of the source array may get overwritten before it is copied. Even worse, in the case of the string functions, the null character marking the end of the string may be lost, and the copy function might get stuck in a loop trashing all the memory allocated to your program.
All functions that have problems copying between overlapping arrays are
explicitly identified in this manual. In addition to functions in this
section, there are a few others like sprintf (see Formatted Output Functions) and scanf (see Formatted Input Functions).
| void * memcpy (void *to, const void *from, size_t size) | Function |
The memcpy function copies size bytes from the object
beginning at from into the object beginning at to. The
behavior of this function is undefined if the two arrays to and
from overlap; use memmove instead if overlapping is possible.
The value returned by Here is an example of how you might use struct foo *oldarray, *newarray; int arraysize; ... memcpy (new, old, arraysize * sizeof (struct foo)); |
| void * mempcpy (void *to, const void *from, size_t size) | Function |
The mempcpy function is nearly identical to the memcpy
function. It copies size bytes from the object beginning at
from into the object pointed to by to. But instead of
returning the value of to it returns a pointer to the byte
following the last written byte in the object beginning at to.
I.e., the value is ((void *) ((char *) to + size)).
This function is useful in situations where a number of objects shall be copied to consecutive memory positions. void *
combine (void *o1, size_t s1, void *o2, size_t s2)
{
void *result = malloc (s1 + s2);
if (result != NULL)
mempcpy (mempcpy (result, o1, s1), o2, s2);
return result;
}
This function is a GNU extension. |
| void * memmove (void *to, const void *from, size_t size) | Function |
memmove copies the size bytes at from into the
size bytes at to, even if those two blocks of space
overlap. In the case of overlap, memmove is careful to copy the
original values of the bytes in the block at from, including those
bytes which also belong to the block at to.
|
| void * memccpy (void *to, const void *from, int c, size_t size) | Function |
| This function copies no more than size bytes from from to to, stopping if a byte matching c is found. The return value is a pointer into to one byte past where c was copied, or a null pointer if no byte matching c appeared in the first size bytes of from. |
| void * memset (void *block, int c, size_t size) | Function |
This function copies the value of c (converted to an
unsigned char) into each of the first size bytes of the
object beginning at block. It returns the value of block.
|
| char * strcpy (char *to, const char *from) | Function |
This copies characters from the string from (up to and including
the terminating null character) into the string to. Like
memcpy, this function has undefined results if the strings
overlap. The return value is the value of to.
|
| char * strncpy (char *to, const char *from, size_t size) | Function |
This function is similar to strcpy but always copies exactly
size characters into to.
If the length of from is more than size, then If the length of from is less than size, then The behavior of Using |
| char * strdup (const char *s) | Function |
This function copies the null-terminated string s into a newly
allocated string. The string is allocated using malloc; see
Unconstrained Allocation. If malloc cannot allocate space
for the new string, strdup returns a null pointer. Otherwise it
returns a pointer to the new string.
|
| char * strndup (const char *s, size_t size) | Function |
This function is similar to strdup but always copies at most
size characters into the newly allocated string.
If the length of s is more than size, then This function is different to
|
| char * stpcpy (char *to, const char *from) | Function |
This function is like strcpy, except that it returns a pointer to
the end of the string to (that is, the address of the terminating
null character) rather than the beginning.
For example, this program uses
#include <string.h>
#include <stdio.h>
int
main (void)
{
char buffer[10];
char *to = buffer;
to = stpcpy (to, "foo");
to = stpcpy (to, "bar");
puts (buffer);
return 0;
}
This function is not part of the ISO or POSIX standards, and is not customary on Unix systems, but we did not invent it either. Perhaps it comes from MS-DOG. Its behavior is undefined if the strings overlap. |
| char * stpncpy (char *to, const char *from, size_t size) | Function |
This function is similar to stpcpy but copies always exactly
size characters into to.
If the length of from is more then size, then If the length of from is less than size, then This function is not part of ISO or POSIX but was found useful while developing the GNU C Library itself. Its behaviour is undefined if the strings overlap. |
| char * strdupa (const char *s) | Macro |
This function is similar to strdup but allocates the new string
using alloca instead of malloc (see Variable Size Automatic). This means of course the returned string has the same
limitations as any block of memory allocated using alloca.
For obvious reasons
#include <paths.h>
#include <string.h>
#include <stdio.h>
const char path[] = _PATH_STDPATH;
int
main (void)
{
char *wr_path = strdupa (path);
char *cp = strtok (wr_path, ":");
while (cp != NULL)
{
puts (cp);
cp = strtok (NULL, ":");
}
return 0;
}
Please note that calling This function is only available if GNU CC is used. |
| char * strndupa (const char *s, size_t size) | Macro |
This function is similar to strndup but like strdupa it
allocates the new string using alloca
see Variable Size Automatic. The same advantages and limitations
of strdupa are valid for strndupa, too.
This function is implemented only as a macro, just like
|
| char * strcat (char *to, const char *from) | Function |
The strcat function is similar to strcpy, except that the
characters from from are concatenated or appended to the end of
to, instead of overwriting it. That is, the first character from
from overwrites the null character marking the end of to.
An equivalent definition for char *
strcat (char *to, const char *from)
{
strcpy (to + strlen (to), from);
return to;
}
This function has undefined results if the strings overlap. |
Programmers using the strcat function (or the following
strncat function for that matter) can easily be recognize as
lazy. In almost all situations the lengths of the participating strings
are known. Or at least, one could know them if one keeps track of the
results of the various function calls. But then it is very inefficient
to use strcat. A lot of time is wasted finding the end of the
destination string so that the actual copying can start. This is a
common example:
/* This function concatenates arbitrarily many strings. The last parameter must beNULL. */ char * concat (const char *str, ...) { va_list ap, ap2; size_t total = 1; const char *s; char *result; va_start (ap, str); /* Actuallyva_copy, but this is the name more gcc versions understand. */ __va_copy (ap2, ap); /* Determine how much space we need. */ for (s = str; s != NULL; s = va_arg (ap, const char *)) total += strlen (s); va_end (ap); result = (char *) malloc (total); if (result != NULL) { result[0] = '\0'; /* Copy the strings. */ for (s = str; s != NULL; s = va_arg (ap2, const char *)) strcat (result, s); } va_end (ap2); return result; }
This looks quite simple, especially the second loop where the strings are actually copied. But these innocent lines hide a major performance penalty. Just imagine that ten strings of 100 bytes each have to be concatenated. For the second string we search the already stored 100 bytes for the end of the string so that we can append the next string. For all strings in total the comparisons necessary to find the end of the intermediate results sums up to 5500! If we combine the copying with the search for the allocation we can write this function more efficient:
char *
concat (const char *str, ...)
{
va_list ap;
size_t allocated = 100;
char *result = (char *) malloc (allocated);
char *wp;
if (allocated != NULL)
{
char *newp;
va_start (ap, atr);
wp = result;
for (s = str; s != NULL; s = va_arg (ap, const char *))
{
size_t len = strlen (s);
/* Resize the allocated memory if necessary. */
if (wp + len + 1 > result + allocated)
{
allocated = (allocated + len) * 2;
newp = (char *) realloc (result, allocated);
if (newp == NULL)
{
free (result);
return NULL;
}
wp = newp + (wp - result);
result = newp;
}
wp = mempcpy (wp, s, len);
}
/* Terminate the result string. */
*wp++ = '\0';
/* Resize memory to the optimal size. */
newp = realloc (result, wp - result);
if (newp != NULL)
result = newp;
va_end (ap);
}
return result;
}
With a bit more knowledge about the input strings one could fine-tune
the memory allocation. The difference we are pointing to here is that
we don't use strcat anymore. We always keep track of the length
of the current intermediate result so we can safe us the search for the
end of the string and use mempcpy. Please note that we also
don't use stpcpy which might seem more natural since we handle
with strings. But this is not necessary since we already know the
length of the string and therefore can use the faster memory copying
function.
Whenever a programmer feels the need to use strcat she or he
should think twice and look through the program whether the code cannot
be rewritten to take advantage of already calculated results. Again: it
is almost always unnecessary to use strcat.
| char * strncat (char *to, const char *from, size_t size) | Function |
This function is like strcat except that not more than size
characters from from are appended to the end of to. A
single null character is also always appended to to, so the total
allocated size of to must be at least size + 1 bytes
longer than its initial length.
The char *
strncat (char *to, const char *from, size_t size)
{
strncpy (to + strlen (to), from, size);
return to;
}
The behavior of |
Here is an example showing the use of strncpy and strncat.
Notice how, in the call to strncat, the size parameter
is computed to avoid overflowing the character array buffer.
#include <string.h>
#include <stdio.h>
#define SIZE 10
static char buffer[SIZE];
main ()
{
strncpy (buffer, "hello", SIZE);
puts (buffer);
strncat (buffer, ", world", SIZE - strlen (buffer) - 1);
puts (buffer);
}
The output produced by this program looks like:
hello hello, wo
| void bcopy (const void *from, void *to, size_t size) | Function |
This is a partially obsolete alternative for memmove, derived from
BSD. Note that it is not quite equivalent to memmove, because the
arguments are not in the same order and there is no return value.
|
| void bzero (void *block, size_t size) | Function |
This is a partially obsolete alternative for memset, derived from
BSD. Note that it is not as general as memset, because the only
value it can store is zero.
|
You can use the functions in this section to perform comparisons on the contents of strings and arrays. As well as checking for equality, these functions can also be used as the ordering functions for sorting operations. See Searching and Sorting, for an example of this.
Unlike most comparison operations in C, the string comparison functions return a nonzero value if the strings are not equivalent rather than if they are. The sign of the value indicates the relative ordering of the first characters in the strings that are not equivalent: a negative value indicates that the first string is "less" than the second, while a positive value indicates that the first string is "greater".
The most common use of these functions is to check only for equality.
This is canonically done with an expression like ! strcmp (s1, s2).
All of these functions are declared in the header file string.h.
| int memcmp (const void *a1, const void *a2, size_t size) | Function |
The function memcmp compares the size bytes of memory
beginning at a1 against the size bytes of memory beginning
at a2. The value returned has the same sign as the difference
between the first differing pair of bytes (interpreted as unsigned
char objects, then promoted to int).
If the contents of the two blocks are equal, |
On arbitrary arrays, the memcmp function is mostly useful for
testing equality. It usually isn't meaningful to do byte-wise ordering
comparisons on arrays of things other than bytes. For example, a
byte-wise comparison on the bytes that make up floating-point numbers
isn't likely to tell you anything about the relationship between the
values of the floating-point numbers.
You should also be careful about using memcmp to compare objects
that can contain "holes", such as the padding inserted into structure
objects to enforce alignment requirements, extra space at the end of
unions, and extra characters at the ends of strings whose length is less
than their allocated size. The contents of these "holes" are
indeterminate and may cause strange behavior when performing byte-wise
comparisons. For more predictable results, perform an explicit
component-wise comparison.
For example, given a structure type definition like:
struct foo
{
unsigned char tag;
union
{
double f;
long i;
char *p;
} value;
};
you are better off writing a specialized comparison function to compare
struct foo objects instead of comparing them with memcmp.
| int strcmp (const char *s1, const char *s2) | Function |
The strcmp function compares the string s1 against
s2, returning a value that has the same sign as the difference
between the first differing pair of characters (interpreted as
unsigned char objects, then promoted to int).
If the two strings are equal, A consequence of the ordering used by |
| int strcasecmp (const char *s1, const char *s2) | Function |
This function is like strcmp, except that differences in case are
ignored. How uppercase and lowercase characters are related is
determined by the currently selected locale. In the standard "C"
locale the characters Ä and ä do not match but in a locale which
regards these characters as parts of the alphabet they do match.
|
| int strncasecmp (const char *s1, const char *s2, size_t n) | Function |
This function is like strncmp, except that differences in case
are ignored. Like strcasecmp, it is locale dependent how
uppercase and lowercase characters are related.
|
| int strncmp (const char *s1, const char *s2, size_t size) | Function |
This function is the similar to strcmp, except that no more than
size characters are compared. In other words, if the two strings are
the same in their first size characters, the return value is zero.
|
Here are some examples showing the use of strcmp and strncmp.
These examples assume the use of the ASCII character set. (If some
other character set--say, EBCDIC--is used instead, then the glyphs
are associated with different numeric codes, and the return values
and ordering may differ.)
strcmp ("hello", "hello")
=> 0 /* These two strings are the same. */
strcmp ("hello", "Hello")
=> 32 /* Comparisons are case-sensitive. */
strcmp ("hello", "world")
=> -15 /* The character 'h' comes before 'w'. */
strcmp ("hello", "hello, world")
=> -44 /* Comparing a null character against a comma. */
strncmp ("hello", "hello, world", 5)
=> 0 /* The initial 5 characters are the same. */
strncmp ("hello, world", "hello, stupid world!!!", 5)
=> 0 /* The initial 5 characters are the same. */
| int strverscmp (const char *s1, const char *s2) | Function |
The strverscmp function compares the string s1 against
s2, considering them as holding indices/version numbers. Return
value follows the same conventions as found in the strverscmp
function. In fact, if s1 and s2 contain no digits,
strverscmp behaves like strcmp.
Basically, we compare strings normally (character by character), until we find a digit in each string - then we enter a special comparison mode, where each sequence of digits is taken as a whole. If we reach the end of these two parts without noticing a difference, we return to the standard comparison mode. There are two types of numeric parts: "integral" and "fractional" (those begin with a '0'). The types of the numeric parts affect the way we sort them:
strverscmp ("no digit", "no digit")
=> 0 /* same behaviour as strcmp. */
strverscmp ("item#99", "item#100")
=> <0 /* same prefix, but 99 < 100. */
strverscmp ("alpha1", "alpha001")
=> >0 /* fractional part inferior to integral one. */
strverscmp ("part1_f012", "part1_f01")
=> >0 /* two fractional parts. */
strverscmp ("foo.009", "foo.0")
=> <0 /* idem, but with leading zeroes only. */
This function is especially useful when dealing with filename sorting, because filenames frequently hold indices/version numbers.
|
| int bcmp (const void *a1, const void *a2, size_t size) | Function |
This is an obsolete alias for memcmp, derived from BSD.
|
In some locales, the conventions for lexicographic ordering differ from
the strict numeric ordering of character codes. For example, in Spanish
most glyphs with diacritical marks such as accents are not considered
distinct letters for the purposes of collation. On the other hand, the
two-character sequence ll is treated as a single letter that is
collated immediately after l.
You can use the functions strcoll and strxfrm (declared in
the header file string.h) to compare strings using a collation
ordering appropriate for the current locale. The locale used by these
functions in particular can be specified by setting the locale for the
LC_COLLATE category; see Locales.
In the standard C locale, the collation sequence for strcoll is
the same as that for strcmp.
Effectively, the way these functions work is by applying a mapping to transform the characters in a string to a byte sequence that represents the string's position in the collating sequence of the current locale. Comparing two such byte sequences in a simple fashion is equivalent to comparing the strings with the locale's collating sequence.
The function strcoll performs this translation implicitly, in
order to do one comparison. By contrast, strxfrm performs the
mapping explicitly. If you are making multiple comparisons using the
same string or set of strings, it is likely to be more efficient to use
strxfrm to transform all the strings just once, and subsequently
compare the transformed strings with strcmp.
| int strcoll (const char *s1, const char *s2) | Function |
The strcoll function is similar to strcmp but uses the
collating sequence of the current locale for collation (the
LC_COLLATE locale).
|
Here is an example of sorting an array of strings, using strcoll
to compare them. The actual sort algorithm is not written here; it
comes from qsort (see Array Sort Function). The job of the
code shown here is to say how to compare the strings while sorting them.
(Later on in this section, we will show a way to do this more
efficiently using strxfrm.)
/* This is the comparison function used withqsort. */ int compare_elements (char **p1, char **p2) { return strcoll (*p1, *p2); } /* This is the entry point--the function to sort strings using the locale's collating sequence. */ void sort_strings (char **array, int nstrings) { /* Sorttemp_arrayby comparing the strings. */ qsort (array, nstrings, sizeof (char *), compare_elements); }
| size_t strxfrm (char *to, const char *from, size_t size) | Function |
The function strxfrm transforms string using the collation
transformation determined by the locale currently selected for
collation, and stores the transformed string in the array to. Up
to size characters (including a terminating null character) are
stored.
The behavior is undefined if the strings to and from overlap; see Copying and Concatenation. The return value is the length of the entire transformed string. This
value is not affected by the value of size, but if it is greater
or equal than size, it means that the transformed string did not
entirely fit in the array to. In this case, only as much of the
string as actually fits was stored. To get the whole transformed
string, call The transformed string may be longer than the original string, and it may also be shorter. If size is zero, no characters are stored in to. In this
case, |
Here is an example of how you can use strxfrm when
you plan to do many comparisons. It does the same thing as the previous
example, but much faster, because it has to transform each string only
once, no matter how many times it is compared with other strings. Even
the time needed to allocate and free storage is much less than the time
we save, when there are many strings.
struct sorter { char *input; char *transformed; };
/* This is the comparison function used with qsort
to sort an array of struct sorter. */
int
compare_elements (struct sorter *p1, struct sorter *p2)
{
return strcmp (p1->transformed, p2->transformed);
}
/* This is the entry point--the function to sort
strings using the locale's collating sequence. */
void
sort_strings_fast (char **array, int nstrings)
{
struct sorter temp_array[nstrings];
int i;
/* Set up temp_array. Each element contains
one input string and its transformed string. */
for (i = 0; i < nstrings; i++)
{
size_t length = strlen (array[i]) * 2;
char *transformed;
size_t transformed_length;
temp_array[i].input = array[i];
/* First try a buffer perhaps big enough. */
transformed = (char *) xmalloc (length);
/* Transform array[i]. */
transformed_length = strxfrm (transformed, array[i], length);
/* If the buffer was not large enough, resize it
and try again. */
if (transformed_length >= length)
{
/* Allocate the needed space. +1 for terminating
NUL character. */
transformed = (char *) xrealloc (transformed,
transformed_length + 1);
/* The return value is not interesting because we know
how long the transformed string is. */
(void) strxfrm (transformed, array[i],
transformed_length + 1);
}
temp_array[i].transformed = transformed;
}
/* Sort temp_array by comparing transformed strings. */
qsort (temp_array, sizeof (struct sorter),
nstrings, compare_elements);
/* Put the elements back in the permanent array
in their sorted order. */
for (i = 0; i < nstrings; i++)
array[i] = temp_array[i].input;
/* Free the strings we allocated. */
for (i = 0; i < nstrings; i++)
free (temp_array[i].transformed);
}
Compatibility Note: The string collation functions are a new feature of ISO C 89. Older C dialects have no equivalent feature.
This section describes library functions which perform various kinds
of searching operations on strings and arrays. These functions are
declared in the header file string.h.
| void * memchr (const void *block, int c, size_t size) | Function |
This function finds the first occurrence of the byte c (converted
to an unsigned char) in the initial size bytes of the
object beginning at block. The return value is a pointer to the
located byte, or a null pointer if no match was found.
|
| char * strchr (const char *string, int c) | Function |
The strchr function finds the first occurrence of the character
c (converted to a char) in the null-terminated string
beginning at string. The return value is a pointer to the located
character, or a null pointer if no match was found.
For example, strchr ("hello, world", 'l')
=> "llo, world"
strchr ("hello, world", '?')
=> NULL
The terminating null character is considered to be part of the string, so you can use this function get a pointer to the end of a string by specifying a null character as the value of the c argument. |
| char * index (const char *string, int c) | Function |
index is another name for strchr; they are exactly the same.
New code should always use strchr since this name is defined in
ISO C while index is a BSD invention which never was available
on System V derived systems.
|
One useful, but unusual, use of the strchr or index
function is when one wants to have a pointer pointing to the NUL byte
terminating a string. This is often written in this way:
s += strlen (s);
This is almost optimal but the addition operation duplicated a bit of
the work already done in the strlen function. A better solution
is this:
s = strchr (s, '\0');
There is no restriction on the second parameter of strchr so it
could very well also be the NUL character. Those readers thinking very
hard about this might now point out that the strchr function is
more expensive than the strlen function since we have two abort
criteria. This is right. But when using the GNU C library is used this
strchr call gets optimized in a special way so that this version
actually is faster.
| char * strrchr (const char *string, int c) | Function |
The function strrchr is like strchr, except that it searches
backwards from the end of the string string (instead of forwards
from the front).
For example, strrchr ("hello, world", 'l')
=> "ld"
|
| char * rindex (const char *string, int c) | Function |
rindex is another name for strrchr; they are exactly the same.
New code should always use strrchr since this name is defined in
ISO C while rindex is a BSD invention which never was available
on System V derived systems.
|
| char * strstr (const char *haystack, const char *needle) | Function |
This is like strchr, except that it searches haystack for a
substring needle rather than just a single character. It
returns a pointer into the string haystack that is the first
character of the substring, or a null pointer if no match was found. If
needle is an empty string, the function returns haystack.
For example, strstr ("hello, world", "l")
=> "llo, world"
strstr ("hello, world", "wo")
=> "world"
|
| void * memmem (const void *haystack, size_t haystack-len, const void *needle, size_t needle-len) |
Function |
This is like strstr, but needle and haystack are byte
arrays rather than null-terminated strings. needle-len is the
length of needle and haystack-len is the length of
haystack.
This function is a GNU extension. |
| size_t strspn (const char *string, const char *skipset) | Function |
The strspn ("string span") function returns the length of the
initial substring of string that consists entirely of characters that
are members of the set specified by the string skipset. The order
of the characters in skipset is not important.
For example, strspn ("hello, world", "abcdefghijklmnopqrstuvwxyz")
=> 5
|
| size_t strcspn (const char *string, const char *stopset) | Function |
The strcspn ("string complement span") function returns the length
of the initial substring of string that consists entirely of characters
that are not members of the set specified by the string stopset.
(In other words, it returns the offset of the first character in string
that is a member of the set stopset.)
For example, strcspn ("hello, world", " \t\n,.;!?")
=> 5
|
| char * strpbrk (const char *string, const char *stopset) | Function |
The strpbrk ("string pointer break") function is related to
strcspn, except that it returns a pointer to the first character
in string that is a member of the set stopset instead of the
length of the initial substring. It returns a null pointer if no such
character from stopset is found.
For example, strpbrk ("hello, world", " \t\n,.;!?")
=> ", world"
|
It's fairly common for programs to have a need to do some simple kinds
of lexical analysis and parsing, such as splitting a command string up
into tokens. You can do this with the strtok function, declared
in the header file string.h.
| char * strtok (char *newstring, const char *delimiters) | Function |
A string can be split into tokens by making a series of calls to the
function strtok.
The string to be split up is passed as the newstring argument on
the first call only. The The delimiters argument is a string that specifies a set of delimiters that may surround the token being extracted. All the initial characters that are members of this set are discarded. The first character that is not a member of this set of delimiters marks the beginning of the next token. The end of the token is found by looking for the next character that is a member of the delimiter set. This character in the original string newstring is overwritten by a null character, and the pointer to the beginning of the token in newstring is returned. On the next call to If the end of the string newstring is reached, or if the remainder of
string consists only of delimiter characters, |
Warning: Since strtok alters the string it is parsing,
you should always copy the string to a temporary buffer before parsing
it with strtok. If you allow strtok to modify a string
that came from another part of your program, you are asking for trouble;
that string might be used for other purposes after strtok has
modified it, and it would not have the expected value.
The string that you are operating on might even be a constant. Then
when strtok tries to modify it, your program will get a fatal
signal for writing in read-only memory. See Program Error Signals.
This is a special case of a general principle: if a part of a program does not have as its purpose the modification of a certain data structure, then it is error-prone to modify the data structure temporarily.
The function strtok is not reentrant. See Nonreentrancy, for
a discussion of where and why reentrancy is important.
Here is a simple example showing the use of strtok.
#include <string.h> #include <stddef.h> ... const char string[] = "words separated by spaces -- and, punctuation!"; const char delimiters[] = " .,;:!-"; char *token, *cp; ... cp = strdupa (string); /* Make writable copy. */ token = strtok (cp, delimiters); /* token => "words" */ token = strtok (NULL, delimiters); /* token => "separated" */ token = strtok (NULL, delimiters); /* token => "by" */ token = strtok (NULL, delimiters); /* token => "spaces" */ token = strtok (NULL, delimiters); /* token => "and" */ token = strtok (NULL, delimiters); /* token => "punctuation" */ token = strtok (NULL, delimiters); /* token => NULL */
The GNU C library contains two more functions for tokenizing a string which overcome the limitation of non-reentrancy.
| char * strtok_r (char *newstring, const char *delimiters, char **save_ptr) | Function |
Just like strtok, this function splits the string into several
tokens which can be accessed by successive calls to strtok_r.
The difference is that the information about the next token is stored in
the space pointed to by the third argument, save_ptr, which is a
pointer to a string pointer. Calling strtok_r with a null
pointer for newstring and leaving save_ptr between the calls
unchanged does the job without hindering reentrancy.
This function is defined in POSIX-1 and can be found on many systems which support multi-threading. |
| char * strsep (char **string_ptr, const char *delimiter) | Function |
This function is just strtok_r with the newstring argument
replaced by the save_ptr argument. The initialization of the
moving pointer has to be done by the user. Successive calls to
strsep move the pointer along the tokens separated by
delimiter, returning the address of the next token and updating
string_ptr to point to the beginning of the next token.
If the input string contains more than one character from
delimiter in a row This function was introduced in 4.3BSD and therefore is widely available. |
Here is how the above example looks like when strsep is used.
#include <string.h> #include <stddef.h> ... const char string[] = "words separated by spaces -- and, punctuation!"; const char delimiters[] = " .,;:!-"; char *running; char *token; ... running = strdupa (string); token = strsep (&running, delimiters); /* token => "words" */ token = strsep (&running, delimiters); /* token => "separated" */ token = strsep (&running, delimiters); /* token => "by" */ token = strsep (&running, delimiters); /* token => "spaces" */ token = strsep (&running, delimiters); /* token => "" */ token = strsep (&running, delimiters); /* token => "" */ token = strsep (&running, delimiters); /* token => "" */ token = strsep (&running, delimiters); /* token => "and" */ token = strsep (&running, delimiters); /* token => "" */ token = strsep (&running, delimiters); /* token => "punctuation" */ token = strsep (&running, delimiters); /* token => "" */ token = strsep (&running, delimiters); /* token => NULL */
To store or transfer binary data in environments which only support text one has to encode the binary data by mapping the input bytes to characters in the range allowed for storing or transfering. SVID systems (and nowadays XPG compliant systems) provide minimal support for this task.
| char * l64a (long int n) | Function |
|
This function encodes a 32-bit input value using characters from the
basic character set. It returns a pointer to a 6 character buffer which
contains an encoded version of n. To encode a series of bytes the
user must copy the returned string to a destination buffer. It returns
the empty string if n is zero, which is somewhat bizarre but
mandated by the standard. Warning: Since a static buffer is used this function should not be used in multi-threaded programs. There is no thread-safe alternative to this function in the C library. Compatibility Note: The XPG standard states that the return value of l64a is undefined if n is negative. In the GNU
implementation, l64a treats its argument as unsigned, so it will
return a sensible encoding for any nonzero n; however, portable
programs should not rely on this.
To encode a large buffer char *
encode (const void *buf, size_t len)
{
/* We know in advance how long the buffer has to be. */
unsigned char *in = (unsigned char *) buf;
char *out = malloc (6 + ((len + 3) / 4) * 6 + 1);
char *cp = out;
/* Encode the length. */
/* Using `htonl' is necessary so that the data can be
decoded even on machines with different byte order. */
cp = mempcpy (cp, l64a (htonl (len)), 6);
while (len > 3)
{
unsigned long int n = *in++;
n = (n << 8) | *in++;
n = (n << 8) | *in++;
n = (n << 8) | *in++;
len -= 4;
if (n)
cp = mempcpy (cp, l64a (htonl (n)), 6);
else
/* `l64a' returns the empty string for n==0, so we
must generate its encoding ("......") by hand. */
cp = stpcpy (cp, "......");
}
if (len > 0)
{
unsigned long int n = *in++;
if (--len > 0)
{
n = (n << 8) | *in++;
if (--len > 0)
n = (n << 8) | *in;
}
memcpy (cp, l64a (htonl (n)), 6);
cp += 6;
}
*cp = '\0';
return out;
}
It is strange that the library does not provide the complete functionality needed but so be it. |
To decode data produced with l64a the following function should be
used.
| long int a64l (const char *string) | Function |
The parameter string should contain a string which was produced by
a call to l64a. The function processes at least 6 characters of
this string, and decodes the characters it finds according to the table
below. It stops decoding when it finds a character not in the table,
rather like atoi; if you have a buffer which has been broken into
lines, you must be careful to skip over the end-of-line characters.
The decoded number is returned as a |
The l64a and a64l functions use a base 64 encoding, in
which each character of an encoded string represents six bits of an
input word. These symbols are used for the base 64 digits:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
| |
| 0 | . | / | 0 | 1
| 2 | 3 | 4 | 5
|
| 8 | 6 | 7 | 8 | 9
| A | B | C | D
|
| 16 | E | F | G | H
| I | J | K | L
|
| 24 | M | N | O | P
| Q | R | S | T
|
| 32 | U | V | W | X
| Y | Z | a | b
|
| 40 | c | d | e | f
| g | h | i | j
|
| 48 | k | l | m | n
| o | p | q | r
|
| 56 | s | t | u | v
| w | x | y | z
|
This encoding scheme is not standard. There are some other encoding methods which are much more widely used (UU encoding, MIME encoding). Generally, it is better to use one of these encodings.
argz vectors are vectors of strings in a contiguous block of
memory, each element separated from its neighbors by null-characters
('\0').
Envz vectors are an extension of argz vectors where each element is a
name-value pair, separated by a '=' character (as in a Unix
environment).
Each argz vector is represented by a pointer to the first element, of
type char *, and a size, of type size_t, both of which can
be initialized to 0 to represent an empty argz vector. All argz
functions accept either a pointer and a size argument, or pointers to
them, if they will be modified.
The argz functions use malloc/realloc to allocate/grow
argz vectors, and so any argz vector creating using these functions may
be freed by using free; conversely, any argz function that may
grow a string expects that string to have been allocated using
malloc (those argz functions that only examine their arguments or
modify them in place will work on any sort of memory).
See Unconstrained Allocation.
All argz functions that do memory allocation have a return type of
error_t, and return 0 for success, and ENOMEM if an
allocation error occurs.
These functions are declared in the standard include file argz.h.
| error_t argz_create (char *const argv[], char **argz, size_t *argz_len) | Function |
The argz_create function converts the Unix-style argument vector
argv (a vector of pointers to normal C strings, terminated by
(char *)0; see Program Arguments) into an argz vector with
the same elements, which is returned in argz and argz_len.
|
| error_t argz_create_sep (const char *string, int sep, char **argz, size_t *argz_len) | Function |
The argz_create_sep function converts the null-terminated string
string into an argz vector (returned in argz and
argz_len) by splitting it into elements at every occurrence of the
character sep.
|
| size_t argz_count (const char *argz, size_t arg_len) | Function |
| Returns the number of elements in the argz vector argz and argz_len. |
| void argz_extract (char *argz, size_t argz_len, char **argv) | Function |
The argz_extract function converts the argz vector argz and
argz_len into a Unix-style argument vector stored in argv,
by putting pointers to every element in argz into successive
positions in argv, followed by a terminator of 0.
Argv must be pre-allocated with enough space to hold all the
elements in argz plus the terminating (char *)0
((argz_count (argz, argz_len) + 1) * sizeof (char *)
bytes should be enough). Note that the string pointers stored into
argv point into argz--they are not copies--and so
argz must be copied if it will be changed while argv is
still active. This function is useful for passing the elements in
argz to an exec function (see Executing a File).
|
| void argz_stringify (char *argz, size_t len, int sep) | Function |
The argz_stringify converts argz into a normal string with
the elements separated by the character sep, by replacing each
'\0' inside argz (except the last one, which terminates the
string) with sep. This is handy for printing argz in a
readable manner.
|
| error_t argz_add (char **argz, size_t *argz_len, const char *str) | Function |
The argz_add function adds the string str to the end of the
argz vector *argz, and updates *argz and
*argz_len accordingly.
|
| error_t argz_add_sep (char **argz, size_t *argz_len, const char *str, int delim) | Function |
The argz_add_sep function is similar to argz_add, but
str is split into separate elements in the result at occurrences of
the character delim. This is useful, for instance, for
adding the components of a Unix search path to an argz vector, by using
a value of ':' for delim.
|
| error_t argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len) | Function |
The argz_append function appends buf_len bytes starting at
buf to the argz vector *argz, reallocating
*argz to accommodate it, and adding buf_len to
*argz_len.
|
| error_t argz_delete (char **argz, size_t *argz_len, char *entry) | Function |
If entry points to the beginning of one of the elements in the
argz vector *argz, the argz_delete function will
remove this entry and reallocate *argz, modifying
*argz and *argz_len accordingly. Note that as
destructive argz functions usually reallocate their argz argument,
pointers into argz vectors such as entry will then become invalid.
|
| error_t argz_insert (char **argz, size_t *argz_len, char *before, const char *entry) | Function |
The argz_insert function inserts the string entry into the
argz vector *argz at a point just before the existing
element pointed to by before, reallocating *argz and
updating *argz and *argz_len. If before
is 0, entry is added to the end instead (as if by
argz_add). Since the first element is in fact the same as
*argz, passing in *argz as the value of
before will result in entry being inserted at the beginning.
|
| char * argz_next (char *argz, size_t argz_len, const char *entry) | Function |
The argz_next function provides a convenient way of iterating
over the elements in the argz vector argz. It returns a pointer
to the next element in argz after the element entry, or
0 if there are no elements following entry. If entry
is 0, the first element of argz is returned.
This behavior suggests two styles of iteration: char *entry = 0;
while ((entry = argz_next (argz, argz_len, entry)))
action;
(the double parentheses are necessary to make some C compilers shut up
about what they consider a questionable char *entry;
for (entry = argz;
entry;
entry = argz_next (argz, argz_len, entry))
action;
Note that the latter depends on argz having a value of |
| error_t argz_replace (char **argz, size_t *argz_len, const char *str, const char *with, unsigned *replace_count) | Function |
Replace any occurrences of the string str in argz with
with, reallocating argz as necessary. If
replace_count is non-zero, *replace_count will be
incremented by number of replacements performed.
|
Envz vectors are just argz vectors with additional constraints on the form of each element; as such, argz functions can also be used on them, where it makes sense.
Each element in an envz vector is a name-value pair, separated by a '='
character; if multiple '=' characters are present in an element, those
after the first are considered part of the value, and treated like all other
non-'\0' characters.
If no '=' characters are present in an element, that element is
considered the name of a "null" entry, as distinct from an entry with an
empty value: envz_get will return 0 if given the name of null
entry, whereas an entry with an empty value would result in a value of
""; envz_entry will still find such entries, however. Null
entries can be removed with envz_strip function.
As with argz functions, envz functions that may allocate memory (and thus
fail) have a return type of error_t, and return either 0 or
ENOMEM.
These functions are declared in the standard include file envz.h.
| char * envz_entry (const char *envz, size_t envz_len, const char *name) | Function |
The envz_entry function finds the entry in envz with the name
name, and returns a pointer to the whole entry--that is, the argz
element which begins with name followed by a '=' character. If
there is no entry with that name, 0 is returned.
|
| char * envz_get (const char *envz, size_t envz_len, const char *name) | Function |
The envz_get function finds the entry in envz with the name
name (like envz_entry), and returns a pointer to the value
portion of that entry (following the '='). If there is no entry with
that name (or only a null entry), 0 is returned.
|
| error_t envz_add (char **envz, size_t *envz_len, const char *name, const char *value) | Function |
The envz_add function adds an entry to *envz
(updating *envz and *envz_len) with the name
name, and value value. If an entry with the same name
already exists in envz, it is removed first. If value is
0, then the new entry will the special null type of entry
(mentioned above).
|
| error_t envz_merge (char **envz, size_t *envz_len, const char *envz2, size_t envz2_len, int override) | Function |
The envz_merge function adds each entry in envz2 to envz,
as if with envz_add, updating *envz and
*envz_len. If override is true, then values in envz2
will supersede those with the same name in envz, otherwise not.
Null entries are treated just like other entries in this respect, so a null entry in envz can prevent an entry of the same name in envz2 from being added to envz, if override is false. |
| void envz_strip (char **envz, size_t *envz_len) | Function |
The envz_strip function removes any null entries from envz,
updating *envz and *envz_len.
|
Character sets used in the early days of computing had only six, seven, or eight bits for each character: there was never a case where more than eight bits (one byte) were used to represent a single character. The limitations of this approach became more apparent as more people grappled with non-Roman character sets, where not all the characters that make up a language's character set can be represented by 2^8 choices. This chapter shows the functionality which was added to the C library to correctly support multiple character sets.
A variety of solutions to overcome the differences between character sets with a 1:1 relation between bytes and characters and character sets with ratios of 2:1 or 4:1 exist. The remainder of this section gives a few examples to help understand the design decisions made while developing the functionality of the C library.
A distinction we have to make right away is between internal and external representation. Internal representation means the representation used by a program while keeping the text in memory. External representations are used when text is stored or transmitted through whatever communication channel. Examples of external representations include files lying in a directory that are going to be read and parsed.
Traditionally there was no difference between the two representations. It was equally comfortable and useful to use the same one-byte representation internally and externally. This changes with more and larger character sets.
One of the problems to overcome with the internal representation is handling text which is externally encoded using different character sets. Assume a program which reads two texts and compares them using some metric. The comparison can be usefully done only if the texts are internally kept in a common format.
For such a common format (= character set) eight bits are certainly no longer enough. So the smallest entity will have to grow: wide characters will now be used. Instead of one byte, two or four will be used instead. (Three are not good to address in memory and more than four bytes seem not to be necessary).
As shown in some other part of this manual, there exists a completely new family of functions which can handle texts of this kind in memory. The most commonly used character set for such internal wide character representations are Unicode and ISO 10646. The former is a subset of the latter and used when wide characters are chosen to by 2 bytes (= 16 bits) wide. The standard names of the encodings used in these cases are UCS2 (= 16 bits) and UCS4 (= 32 bits).
To represent wide characters the char type is not suitable. For
this reason the ISO C standard introduces a new type which is
designed to keep one character of a wide character string. To maintain
the similarity there is also a type corresponding to int for
those functions which take a single wide character.
| wchar_t | Data type |
This data type is used as the base type for wide character strings.
I.e., arrays of objects of this type are the equivalent of char[]
for multibyte character strings. The type is defined in stddef.h.
The ISO C89 standard, where this type was introduced, does not say
anything specific about the representation. It only requires that this
type is capable to store all elements of the basic character set.
Therefore it would be legitimate to define But for GNU systems this type is always 32 bits wide. It is therefore
capable to represent all UCS4 value therefore covering all of ISO 10646. Some Unix systems define |
| wint_t | Data type |
wint_t is a data type used for parameters and variables which
contain a single wide character. As the name already suggests it is the
equivalent to int when using the normal char strings. The
types wchar_t and wint_t have often the same
representation if their size if 32 bits wide but if wchar_t is
defined as char the type wint_t must be defined as
int due to the parameter promotion.
This type is defined in |
As there are for the char data type there also exist macros
specifying the minimum and maximum value representable in an object of
type wchar_t.
| wint_t WCHAR_MIN | Macro |
The macro WCHAR_MIN evaluates to the minimum value representable
by an object of type wint_t.
This macro got introduced in the second amendment to ISO C89. |
| wint_t WCHAR_MAX | Macro |
The macro WCHAR_MIN evaluates to the maximum value representable
by an object of type wint_t.
This macro got introduced in the second amendment to ISO C89. |
Another special wide character value is the equivalent to EOF.
| wint_t WEOF | Macro |
The macro WEOF evaluates to a constant expression of type
wint_t whose value is different from any member of the extended
character set.
{
int c;
...
while ((c = getc (fp)) < 0)
...
}
has to be rewritten to explicitly use {
wint_t c;
...
while ((c = wgetc (fp)) != WEOF)
...
}
This macro was introduced in the second amendment to ISO C89 and is
defined in |
These internal representations present problems when it comes to storing and transmittal, since a single wide character consists of more than one byte they are effected by byte-ordering. I.e., machines with different endianesses would see different value accessing the same data. This also applies for communication protocols which are all byte-based and therefore the sender has to decide about splitting the wide character in bytes. A last (but not least important) point is that wide characters often require more storage space than an customized byte oriented character set.
For all the above reasons, an external encoding which is different
from the internal encoding is often used if the latter is UCS2 or UCS4.
The external encoding is byte-based and can be chosen appropriately for
the environment and for the texts to be handled. There exist a variety
of different character sets which can be used for this external
encoding. Information which will not be exhaustively presented
here-instead, a description of the major groups will suffice. All of
the ASCII-based character sets [_bkoz_: do you mean Roman character
sets? If not, what do you mean here?] fulfill one requirement: they are
"filesystem safe". This means that the character '/' is used in
the encoding only to represent itself. Things are a bit
different for character sets like EBCDIC (Extended Binary Coded Decimal
Interchange Code, a character set family used by IBM) but if the
operation system does not understand EBCDIC directly the parameters to
system calls have to be converted first anyhow.
In most uses of ISO 2022 the defined character sets do not allow state changes which cover more than the next character. This has the big advantage that whenever one can identify the beginning of the byte sequence of a character one can interpret a text correctly. Examples of character sets using this policy are the various EUC character sets (used by Sun's operations systems, EUC-JP, EUC-KR, EUC-TW, and EUC-CN) or SJIS (Shift JIS, a Japanese encoding).
But there are also character sets using a state which is valid for more than one character and has to be changed by another byte sequence. Examples for this are ISO-2022-JP, ISO-2022-KR, and ISO-2022-CN.
0xc2 0x61 (non-spacing
acute accent, following by lower-case `a') to get the "small a with
acute" character. To get the acute accent character on its on one has
to write 0xc2 0x20 (the non-spacing acute followed by a space).
This type of characters sets is quite frequently used in embedded systems such as video text.
There were a few other attempts to encode ISO 10646 such as UTF-7 but UTF-8 is today the only encoding which should be used. In fact, UTF-8 will hopefully soon be the only external which has to be supported. It proves to be universally usable and the only disadvantage is that it favor Roman languages very much by making the byte string representation of other scripts (Cyrillic, Greek, Asian scripts) longer than necessary if using a specific character set for these scripts. Methods like the Unicode compression scheme can alleviate these problems.
The question remaining is: how to select the character set or encoding to use. The answer: you cannot decide about it yourself, it is decided by the developers of the system or the majority of the users. Since the goal is interoperability one has to use whatever the other people one works with use. If there are no constraints the selection is based on the requirements the expected circle of users will have. I.e., if a project is expected to only be used in, say, Russia it is fine to use KOI8-R or a similar character set. But if at the same time people from, say, Greece are participating one should use a character set which allows all people to collaborate.
The most widely useful solution seems to be: go with the most general character set, namely ISO 10646. Use UTF-8 as the external encoding and problems about users not being able to use their own language adequately are a thing of the past.
One final comment about the choice of the wide character representation
is necessary at this point. We have said above that the natural choice
is using Unicode or ISO 10646. This is not specified in any
standard, though. The ISO C standard does not specify anything
specific about the wchar_t type. There might be systems where
the developers decided differently. Therefore one should as much as
possible avoid making assumption about the wide character representation
although GNU systems will always work as described above. If the
programmer uses only the functions provided by the C library to handle
wide character strings there should not be any compatibility problems
with other systems.
A Unix C library contains three different sets of functions in two families to handle character set conversion. The one function family is specified in the ISO C standard and therefore is portable even beyond the Unix world.
The most commonly known set of functions, coming from the ISO C89 standard, is unfortunately the least useful one. In fact, these functions should be avoided whenever possible, especially when developing libraries (as opposed to applications).
The second family of functions got introduced in the early Unix standards (XPG2) and is still part of the latest and greatest Unix standard: Unix 98. It is also the most powerful and useful set of functions. But we will start with the functions defined in the second amendment to ISO C89.
The ISO C standard defines functions to convert strings from a multibyte representation to wide character strings. There are a number of peculiarities:
LC_CTYPE category of the current locale is used; see
Locale Categories.
Despite these limitations the ISO C functions can very well be used
in many contexts. In graphical user interfaces, for instance, it is not
uncommon to have functions which require text to be displayed in a wide
character string if it is not simple ASCII. The text itself might come
from a file with translations and the user should decide about the
current locale which determines the translation and therefore also the
external encoding used. In such a situation (and many others) the
functions described here are perfect. If more freedom while performing
the conversion is necessary take a look at the iconv functions
(see Generic Charset Conversion).
We already said above that the currently selected locale for the
LC_CTYPE category decides about the conversion which is performed
by the functions we are about to describe. Each locale uses its own
character set (given as an argument to localedef) and this is the
one assumed as the external multibyte encoding. The wide character
character set always is UCS4, at least on GNU systems.
A characteristic of each multibyte character set is the maximum number of bytes which can be necessary to represent one character. This information is quite important when writing code which uses the conversion functions. In the examples below we will see some examples. The ISO C standard defines two macros which provide this information.
| int MB_LEN_MAX | Macro |
This macro specifies the maximum number of bytes in the multibyte
sequence for a single character in any of the supported locales. It is
a compile-time constant and it is defined in limits.h.
|
| int MB_CUR_MAX | Macro |
MB_CUR_MAX expands into a positive integer expression that is the
maximum number of bytes in a multibyte character in the current locale.
The value is never greater than MB_LEN_MAX. Unlike
MB_LEN_MAX this macro need not be a compile-time constant and in
fact, in the GNU C library it is not.
|
Two different macros are necessary since strictly ISO C89 compilers do not allow variable length array definitions but still it is desirable to avoid dynamic allocation. This incomplete piece of code shows the problem:
{
char buf[MB_LEN_MAX];
ssize_t len = 0;
while (! feof (fp))
{
fread (&buf[len], 1, MB_CUR_MAX - len, fp);
/* ... process buf */
len -= used;
}
}
The code in the inner loop is expected to have always enough bytes in
the array buf to convert one multibyte character. The array
buf has to be sized statically since many compilers do not allow a
variable size. The fread call makes sure that always
MB_CUR_MAX bytes are available in buf. Note that it isn't
a problem if MB_CUR_MAX is not a compile-time constant.
In the introduction of this chapter it was said that certain character sets use a stateful encoding. I.e., the encoded values depend in some way on the previous bytes in the text.
Since the conversion functions allow converting a text in more than one step we must have a way to pass this information from one call of the functions to another.
| mbstate_t | Data type |
A variable of type mbstate_t can contain all the information
about the shift state needed from one call to a conversion
function to another.
This type is defined in |
To use objects of this type the programmer has to define such objects (normally as local variables on the stack) and pass a pointer to the object to the conversion functions. This way the conversion function can update the object if the current multibyte character set is stateful.
There is no specific function or initializer to put the state object in any specific state. The rules are that the object should always represent the initial state before the first use and this is achieved by clearing the whole variable with code such as follows:
{
mbstate_t state;
memset (&state, '\0', sizeof (state));
/* from now on state can be used. */
...
}
When using the conversion functions to generate output it is often necessary to test whether the current state corresponds to the initial state. This is necessary, for example, to decide whether or not to emit escape sequences to set the state to the initial state at certain sequence points. Communication protocols often require this.
| int mbsinit (const mbstate_t *ps) | Function |
|
This function determines whether the state object pointed to by ps
is in the initial state or not. If ps is a null pointer or the
object is in the initial state the return value is nonzero. Otherwise
it is zero.
This function was introduced in the second amendment to ISO C89 and
is declared in |
Code using this function often looks similar to this:
{
mbstate_t state;
memset (&state, '\0', sizeof (state));
/* Use state. */
...
if (! mbsinit (&state))
{
/* Emit code to return to initial state. */
const char empty[] = "";
const char **srcp = ∅
wcsrtombs (outbuf, &srcp, outbuflen, &state);
}
...
}
The code to emit the escape sequence to get back to the initial state is
interesting. The wcsrtombs function can be used to determine the
necessary output code (see Converting Strings). Please note that on
GNU systems it is not necessary to perform this extra action for the
conversion from multibyte text to wide character text since the wide
character encoding is not stateful. But there is nothing mentioned in
any standard which prohibits making wchar_t using a stateful
encoding.
The most fundamental of the conversion functions are those dealing with single characters. Please note that this does not always mean single bytes. But since there is very often a subset of the multibyte character set which consists of single byte sequences there are functions to help with converting bytes. One very important and often applicable scenario is where ASCII is a subpart of the multibyte character set. I.e., all ASCII characters stand for itself and all other characters have at least a first byte which is beyond the range 0 to 127.
| wint_t btowc (int c) | Function |
The btowc function ("byte to wide character") converts a valid
single byte character c in the initial shift state into the wide
character equivalent using the conversion rules from the currently
selected locale of the LC_CTYPE category.
If Please note the restriction of c being tested for validity only in
the initial shift state. There is no This function was introduced in the second amendment of ISO C89 and
is declared in |
Despite the limitation that the single byte value always is interpreted in the initial state this function is actually useful most of the time. Most characters are either entirely single-byte character sets or they are extension to ASCII. But then it is possible to write code like this (not that this specific example is very useful):
wchar_t *
itow (unsigned long int val)
{
static wchar_t buf[30];
wchar_t *wcp = &buf[29];
*wcp = L'\0';
while (val != 0)
{
*--wcp = btowc ('0' + val % 10);
val /= 10;
}
if (wcp == &buf[29])
*--wcp = L'0';
return wcp;
}
Why is it necessary to use such a complicated implementation and not
simply cast '0' + val % 10 to a wide character? The answer is
that there is no guarantee that one can perform this kind of arithmetic
on the character of the character set used for wchar_t
representation. In other situations the bytes are not constant at
compile time and so the compiler cannot do the work. In situations like
this it is necessary btowc.
There also is a function for the conversion in the other direction.
| int wctob (wint_t c) | Function |
The wctob function ("wide character to byte") takes as the
parameter a valid wide character. If the multibyte representation for
this character in the initial state is exactly one byte long the return
value of this function is this character. Otherwise the return value is
EOF.
This function was introduced in the second amendment of ISO C89 and
is declared in |
There are more general functions to convert single character from multibyte representation to wide characters and vice versa. These functions pose no limit on the length of the multibyte representation and they also do not require it to be in the initial state.
| size_t mbrtowc (wchar_t *restrict pwc, const char *restrict s, size_t n, mbstate_t *restrict ps) | Function |
The mbrtowc function ("multibyte restartable to wide
character") converts the next multibyte character in the string pointed
to by s into a wide character and stores it in the wide character
string pointed to by pwc. The conversion is performed according
to the locale currently selected for the LC_CTYPE category. If
the conversion for the character set used in the locale requires a state
the multibyte string is interpreted in the state represented by the
object pointed to by ps. If ps is a null pointer an static,
internal state variable used only by the mbrtowc variable is
used.
If the next multibyte character corresponds to the NUL wide character
the return value of the function is 0 and the state object is
afterwards in the initial state. If the next n or fewer bytes
form a correct multibyte character the return value is the number of
bytes starting from s which form the multibyte character. The
conversion state is updated according to the bytes consumed in the
conversion. In both cases the wide character (either the If the first n bytes of the multibyte string possibly form a valid
multibyte character but there are more than n bytes needed to
complete it the return value of the function is If the first This function was introduced in the second amendment to ISO C89 and
is declared in |
Using this function is straight forward. A function which copies a multibyte string into a wide character string while at the same time converting all lowercase character into uppercase could look like this (this is not the final version, just an example; it has no error checking, and leaks sometimes memory):
wchar_t *
mbstouwcs (const char *s)
{
size_t len = strlen (s);
wchar_t *result = malloc ((len + 1) * sizeof (wchar_t));
wchar_t *wcp = result;
wchar_t tmp[1];
mbstate_t state;
memset (&state, '\0', sizeof (state));
size_t nbytes;
while ((nbytes = mbrtowc (tmp, s, len, &state)) > 0)
{
if (nbytes >= (size_t) -2)
/* Invalid input string. */
return NULL;
*result++ = towupper (tmp[0]);
len -= nbytes;
s += nbytes;
}
return result;
}
The use of mbrtowc should be clear. A single wide character is
stored in tmp[0] and the number of consumed bytes is stored
in the variable nbytes. In case the the conversion was successful
the uppercase variant of the wide character is stored in the
result array and the pointer to the input string and the number of
available bytes is adjusted.
The only non-obvious thing about the function might be the way memory is allocated for the result. The above code uses the fact that there can never be more wide characters in the converted results than there are bytes in the multibyte input string. This method yields to a pessimistic guess about the size of the result and if many wide character strings have to be constructed this way or the strings are long, the extra memory required allocated because the input string contains multibyte characters might be significant. It would be possible to resize the allocated memory block to the correct size before returning it. A better solution might be to allocate just the right amount of space for the result right away. Unfortunately there is no function to compute the length of the wide character string directly from the multibyte string. But there is a function which does part of the work.
| size_t mbrlen (const char *restrict s, size_t n, mbstate_t *ps) | Function |
The mbrlen function ("multibyte restartable length") computes
the number of at most n bytes starting at s which form the
next valid and complete multibyte character.
If the next multibyte character corresponds to the NUL wide character the return value is 0. If the next n bytes form a valid multibyte character the number of bytes belonging to this multibyte character byte sequence is returned. If the the first n bytes possibly form a valid multibyte
character but it is incomplete the return value is The multibyte sequence is interpreted in the state represented by the
object pointer to by ps. If ps is a null pointer an state
object local to This function was introduced in the second amendment to ISO C89 and
is declared in |
The tentative reader now will of course note that mbrlen can be
implemented as
mbrtowc (NULL, s, n, ps != NULL ? ps : &internal)
This is true and in fact is mentioned in the official specification.
Now, how can this function be used to determine the length of the wide
character string created from a multibyte character string? It is not
directly usable but we can define a function mbslen using it:
size_t
mbslen (const char *s)
{
mbstate_t state;
size_t result = 0;
size_t nbytes;
memset (&state, '\0', sizeof (state));
while ((nbytes = mbrlen (s, MB_LEN_MAX, &state)) > 0)
{
if (nbytes >= (size_t) -2)
/* Something is wrong. */
return (size_t) -1;
s += nbytes;
++result;
}
return result;
}
This function simply calls mbrlen for each multibyte character
in the string and counts the number of function calls. Please note that
we here use MB_LEN_MAX as the size argument in the mbrlen
call. This is OK since a) this value is larger then the length of the
longest multibyte character sequence and b) because we know that the
string s ends with a NUL byte which cannot be part of any other
multibyte character sequence but the one representing the NUL wide
character. Therefore the mbrlen function will never read invalid
memory.
Now that this function is available (just to make this clear, this function is not part of the GNU C library) we can compute the number of wide character required to store the converted multibyte character string s using
wcs_bytes = (mbslen (s) + 1) * sizeof (wchar_t);
Please note that the mbslen function is quite inefficient. The
implementation of mbstouwcs implemented using mbslen would
have to perform the conversion of the multibyte character input string
twice and this conversion might be quite expensive. So it is necessary
to think about the consequences of using the easier but imprecise method
before doing the work twice.
| size_t wcrtomb (char *restrict s, wchar_t wc, mbstate_t *restrict ps) | Function |
The wcrtomb function ("wide character restartable to
multibyte") converts a single wide character into a multibyte string
corresponding to that wide character.
If s is a null pointer the function resets the the state stored in
the objects pointer to by ps (or the internal wcrtombs (temp_buf, L'\0', ps) since if s is a null pointer If wc is the NUL wide character Otherwise a byte sequence (possibly including shift sequences) is
written into the string s. This of only happens if wc is a
valid wide character, i.e., it has a multibyte representation in the
character set selected by locale of the If no error occurred the function returns the number of bytes stored in the string s. This includes all byte representing shift sequences. One word about the interface of the function: there is no parameter
specifying the length of the array s. Instead the function
assumes that there are at least This function was introduced in the second amendment to ISO C and is
declared in |
Using this function is as easy as using mbrtowc. The following
example appends a wide character string to a multibyte character string.
Again, the code is not really useful (and correct), it is simply here to
demonstrate the use and some problems.
char *
mbscatwc (char *s, size_t len, const wchar_t *ws)
{
mbstate_t state;
/* Find the end of the existing string. */
char *wp = strchr (s, '\0');
len -= wp - s;
memset (&state, '\0', sizeof (state));
do
{
size_t nbytes;
if (len < MB_CUR_LEN)
{
/* We cannot guarantee that the next
character fits into the buffer, so
return an error. */
errno = E2BIG;
return NULL;
}
nbytes = wcrtomb (wp, *ws, &state);
if (nbytes == (size_t) -1)
/* Error in the conversion. */
return NULL;
len -= nbytes;
wp += nbytes;
}
while (*ws++ != L'\0');
return s;
}
First the function has to find the end of the string currently in the
array s. The strchr call does this very efficiently since a
requirement for multibyte character representations is that the NUL byte
never is used except to represent itself (and in this context, the end
of the string).
After initializing the state object the loop is entered where the first
task is to make sure there is enough room in the array s. We
abort if there are not at least MB_CUR_LEN bytes available. This
is not always optimal but we have no other choice. We might have less
than MB_CUR_LEN bytes available but the next multibyte character
might also be only one byte long. At the time the wcrtomb call
returns it is too late to decide whether the buffer was large enough or
not. If this solution is really unsuitable there is a very slow but
more accurate solution.
...
if (len < MB_CUR_LEN)
{
mbstate_t temp_state;
memcpy (&temp_state, &state, sizeof (state));
if (wcrtomb (NULL, *ws, &temp_state) > len)
{
/* We cannot guarantee that the next
character fits into the buffer, so
return an error. */
errno = E2BIG;
return NULL;
}
}
...
Here we do perform the conversion which might overflow the buffer so
that we are afterwards in the position to make an exact decision about
the buffer size. Please note the NULL argument for the
destination buffer in the new wcrtomb call; since we are not
interested in the converted text at this point this is a nice way to
express this. The most unusual thing about this piece of code certainly
is the duplication of the conversion state object. But think about
this: if a change of the state is necessary to emit the next multibyte
character we want to have the same shift state change performed in the
real conversion. Therefore we have to preserve the initial shift state
information.
There are certainly many more and even better solutions to this problem. This example is only meant for educational purposes.
The functions described in the previous section only convert a single character at a time. Most operations to be performed in real-world programs include strings and therefore the ISO C standard also defines conversions on entire strings. However, the defined set of functions is quite limited, thus the GNU C library contains a few extensions which can help in some important situations.
| size_t mbsrtowcs (wchar_t *restrict dst, const char **restrict src, size_t len, mbstate_t *restrict ps) | Function |
The mbsrtowcs function ("multibyte string restartable to wide
character string") converts an NUL terminated multibyte character
string at *src into an equivalent wide character string,
including the NUL wide character at the end. The conversion is started
using the state information from the object pointed to by ps or
from an internal object of mbsrtowcs if ps is a null
pointer. Before returning the state object to match the state after the
last converted character. The state is the initial state if the
terminating NUL byte is reached and converted.
If dst is not a null pointer the result is stored in the array pointed to by dst, otherwise the conversion result is not available since it is stored in an internal buffer. If len wide characters are stored in the array dst before reaching the end of the input string the conversion stops and len is returned. If dst is a null pointer len is never checked. Another reason for a premature return from the function call is if the
input string contains an invalid multibyte sequence. In this case the
global variable In all other cases the function returns the number of wide characters
converted during this call. If dst is not null This function was introduced in the second amendment to ISO C and is
declared in |
The definition of this function has one limitation which has to be
understood. The requirement that dst has to be a NUL terminated
string provides problems if one wants to convert buffers with text. A
buffer is normally no collection of NUL terminated strings but instead a
continuous collection of lines, separated by newline characters. Now
assume a function to convert one line from a buffer is needed. Since
the line is not NUL terminated the source pointer cannot directly point
into the unmodified text buffer. This means, either one inserts the NUL
byte at the appropriate place for the time of the mbsrtowcs
function call (which is not doable for a read-only buffer or in a
multi-threaded application) or one copies the line in an extra buffer
where it can be terminated by a NUL byte. Note that it is not in
general possible to limit the number of characters to convert by setting
the parameter len to any specific value. Since it is not known
how many bytes each multibyte character sequence is in length one always
could do only a guess.
There is still a problem with the method of NUL-terminating a line right after the newline character which could lead to very strange results. As said in the description of the mbsrtowcs function above the conversion state is guaranteed to be in the initial shift state after processing the NUL byte at the end of the input string. But this NUL byte is not really part of the text. I.e., the conversion state after the newline in the original text could be something different than the initial shift state and therefore the first character of the next line is encoded using this state. But the state in question is never accessible to the user since the conversion stops after the NUL byte (which resets the state). Most stateful character sets in use today require that the shift state after a newline is the initial state-but this is not a strict guarantee. Therefore simply NUL terminating a piece of a running text is not always an adequate solution and therefore never should be used in generally used code.
The generic conversion interface (see Generic Charset Conversion)
does not have this limitation (it simply works on buffers, not
strings), and the GNU C library contains a set of functions which take
additional parameters specifying the maximal number of bytes which are
consumed from the input string. This way the problem of
mbsrtowcs's example above could be solved by determining the line
length and passing this length to the function.
| size_t wcsrtombs (char *restrict dst, const wchar_t **restrict src, size_t len, mbstate_t *restrict ps) | Function |
The wcsrtombs function ("wide character string restartable to
multibyte string") converts the NUL terminated wide character string at
*src into an equivalent multibyte character string and
stores the result in the array pointed to by dst. The NUL wide
character is also converted. The conversion starts in the state
described in the object pointed to by ps or by a state object
locally to wcsrtombs in case ps is a null pointer. If
dst is a null pointer the conversion is performed as usual but the
result is not available. If all characters of the input string were
successfully converted and if dst is not a null pointer the
pointer pointed to by src gets assigned a null pointer.
If one of the wide characters in the input string has no valid multibyte
character equivalent the conversion stops early, sets the global
variable Another reason for a premature stop is if dst is not a null pointer and the next converted character would require more than len bytes in total to the array dst. In this case (and if dest is not a null pointer) the pointer pointed to by src is assigned a value pointing to the wide character right after the last one successfully converted. Except in the case of an encoding error the return value of the function is the number of bytes in all the multibyte character sequences stored in dst. Before returning the state in the object pointed to by ps (or the internal object in case ps is a null pointer) is updated to reflect the state after the last conversion. The state is the initial shift state in case the terminating NUL wide character was converted. This function was introduced in the second amendment to ISO C and is
declared in |
The restriction mentions above for the mbsrtowcs function applies
also here. There is no possibility to directly control the number of
input characters. One has to place the NUL wide character at the
correct place or control the consumed input indirectly via the available
output array size (the len parameter).
| size_t mbsnrtowcs (wchar_t *restrict dst, const char **restrict src, size_t nmc, size_t len, mbstate_t *restrict ps) | Function |
The mbsnrtowcs function is very similar to the mbsrtowcs
function. All the parameters are the same except for nmc which is
new. The return value is the same as for mbsrtowcs.
This new parameter specifies how many bytes at most can be used from the
multibyte character string. I.e., the multibyte character string
This function is a GNU extensions. It is meant to work around the problems mentioned above. Now it is possible to convert buffer with multibyte character text piece for piece without having to care about inserting NUL bytes and the effect of NUL bytes on the conversion state. |
A function to convert a multibyte string into a wide character string and display it could be written like this (this is not a really useful example):
void
showmbs (const char *src, FILE *fp)
{
mbstate_t state;
int cnt = 0;
memset (&state, '\0', sizeof (state));
while (1)
{
wchar_t linebuf[100];
const char *endp = strchr (src, '\n');
size_t n;
/* Exit if there is no more line. */
if (endp == NULL)
break;
n = mbsnrtowcs (linebuf, &src, endp - src, 99, &state);
linebuf[n] = L'\0';
fprintf (fp, "line %d: \"%S\"\n", linebuf);
}
}
There is no problem with the state after a call to mbsnrtowcs.
Since we don't insert characters in the strings which were not in there
right from the beginning and we use state only for the conversion
of the given buffer there is no problem with altering the state.
| size_t wcsnrtombs (char *restrict dst, const wchar_t **restrict src, size_t nwc, size_t len, mbstate_t *restrict ps) | Function |
The wcsnrtombs function implements the conversion from wide
character strings to multibyte character strings. It is similar to
wcsrtombs but it takes, just like mbsnrtowcs, an extra
parameter which specifies the length of the input string.
No more than nwc wide characters from the input string
This function is a GNU extension and just like |
The example programs given in the last sections are only brief and do
not contain all the error checking etc. Presented here is a complete
and documented example. It features the mbrtowc function but it
should be easy to derive versions using the other functions.
int
file_mbsrtowcs (int input, int output)
{
/* Note the use of MB_LEN_MAX.
MB_CUR_MAX cannot portably be used here. */
char buffer[BUFSIZ + MB_LEN_MAX];
mbstate_t state;
int filled = 0;
int eof = 0;
/* Initialize the state. */
memset (&state, '\0', sizeof (state));
while (!eof)
{
ssize_t nread;
ssize_t nwrite;
char *inp = buffer;
wchar_t outbuf[BUFSIZ];
wchar_t *outp = outbuf;
/* Fill up the buffer from the input file. */
nread = read (input, buffer + filled, BUFSIZ);
if (nread < 0)
{
perror ("read");
return 0;
}
/* If we reach end of file, make a note to read no more. */
if (nread == 0)
eof = 1;
/* filled is now the number of bytes in buffer. */
filled += nread;
/* Convert those bytes to wide characters-as many as we can. */
while (1)
{
size_t thislen = mbrtowc (outp, inp, filled, &state);
/* Stop converting at invalid character;
this can mean we have read just the first part
of a valid character. */
if (thislen == (size_t) -1)
break;
/* We want to handle embedded NUL bytes
but the return value is 0. Correct this. */
if (thislen == 0)
thislen = 1;
/* Advance past this character. */
inp += thislen;
filled -= thislen;
++outp;
}
/* Write the wide characters we just made. */
nwrite = write (output, outbuf,
(outp - outbuf) * sizeof (wchar_t));
if (nwrite < 0)
{
perror ("write");
return 0;
}
/* See if we have a real invalid character. */
if ((eof && filled > 0) || filled >= MB_CUR_MAX)
{
error (0, 0, "invalid multibyte character");
return 0;
}
/* If any characters must be carried forward,
put them at the beginning of buffer. */
if (filled > 0)
memmove (inp, buffer, filled);
}
return 1;
}
The functions described in the last chapter are defined in the second amendment to ISO C89. But the original ISO C89 standard also contained functions for character set conversion. The reason that they are not described in the first place is that they are almost entirely useless.
The problem is that all the functions for conversion defined in ISO C89 use a local state. This implies that multiple conversions at the same time (not only when using threads) cannot be done, and that you cannot first convert single characters and then strings since you cannot tell the conversion functions which state to use.
These functions are therefore usable only in a very limited set of situations. One must complete converting the entire string before starting a new one and each string/text must be converted with the same function (there is no problem with the library itself; it is guaranteed that no library function changes the state of any of these functions). For the above reasons it is highly requested that the functions from the last section are used in place of non-reentrant conversion functions.
| int mbtowc (wchar_t *restrict result, const char *restrict string, size_t size) | Function |
The mbtowc ("multibyte to wide character") function when called
with non-null string converts the first multibyte character
beginning at string to its corresponding wide character code. It
stores the result in *result.
For a valid multibyte character, For an invalid byte sequence, If the multibyte character code uses shift characters, then
|
| int wctomb (char *string, wchar_t wchar) | Function |
The wctomb ("wide character to multibyte") function converts
the wide character code wchar to its corresponding multibyte
character sequence, and stores the result in bytes starting at
string. At most MB_CUR_MAX characters are stored.
Given a valid code, If wchar is an invalid wide character code, If the multibyte character code uses shift characters, then
Calling this function with a wchar argument of zero when
string is not null has the side-effect of reinitializing the
stored shift state as well as storing the multibyte character
|
Similar to mbrlen there is also a non-reentrant function which
computes the length of a multibyte character. It can be defined in
terms of mbtowc.
| int mblen (const char *string, size_t size) | Function |
The mblen function with a non-null string argument returns
the number of bytes that make up the multibyte character beginning at
string, never examining more than size bytes. (The idea is
to supply for size the number of bytes of data you have in hand.)
The return value of For a valid multibyte character, If the multibyte character code uses shift characters, then The function |
For convenience reasons the ISO C89 standard defines also functions to convert entire strings instead of single characters. These functions suffer from the same problems as their reentrant counterparts from the second amendment to ISO C89; see Converting Strings.
| size_t mbstowcs (wchar_t *wstring, const char *string, size_t size) | Function |
The mbstowcs ("multibyte string to wide character string")
function converts the null-terminated string of multibyte characters
string to an array of wide character codes, storing not more than
size wide characters into the array beginning at wstring.
The terminating null character counts towards the size, so if size
is less than the actual number of wide characters resulting from
string, no terminating null character is stored.
The conversion of characters from string begins in the initial shift state. If an invalid multibyte character sequence is found, this function returns a value of -1. Otherwise, it returns the number of wide characters stored in the array wstring. This number does not include the terminating null character, which is present if the number is less than size. Here is an example showing how to convert a string of multibyte characters, allocating enough space for the result. wchar_t *
mbstowcs_alloc (const char *string)
{
size_t size = strlen (string) + 1;
wchar_t *buf = xmalloc (size * sizeof (wchar_t));
size = mbstowcs (buf, string, size);
if (size == (size_t) -1)
return NULL;
buf = xrealloc (buf, (size + 1) * sizeof (wchar_t));
return buf;
}
|
| size_t wcstombs (char *string, const wchar_t *wstring, size_t size) | Function |
The wcstombs ("wide character string to multibyte string")
function converts the null-terminated wide character array wstring
into a string containing multibyte characters, storing not more than
size bytes starting at string, followed by a terminating
null character if there is room. The conversion of characters begins in
the initial shift state.
The terminating null character counts towards the size, so if size is less than or equal to the number of bytes needed in wstring, no terminating null character is stored. If a code that does not correspond to a valid multibyte character is found, this function returns a value of -1. Otherwise, the return value is the number of bytes stored in the array string. This number does not include the terminating null character, which is present if the number is less than size. |
In some multibyte character codes, the meaning of any particular byte sequence is not fixed; it depends on what other sequences have come earlier in the same string. Typically there are just a few sequences that can change the meaning of other sequences; these few are called shift sequences and we say that they set the shift state for other sequences that follow.
To illustrate shift state and shift sequences, suppose we decide that
the sequence 0200 (just one byte) enters Japanese mode, in which
pairs of bytes in the range from 0240 to 0377 are single
characters, while 0201 enters Latin-1 mode, in which single bytes
in the range from 0240 to 0377 are characters, and
interpreted according to the ISO Latin-1 character set. This is a
multibyte code which has two alternative shift states ("Japanese mode"
and "Latin-1 mode"), and two shift sequences that specify particular
shift states.
When the multibyte character code in use has shift states, then
mblen, mbtowc and wctomb must maintain and update
the current shift state as they scan the string. To make this work
properly, you must follow these rules:
mblen (NULL,
0). This initializes the shift state to its standard initial value.
Here is an example of using mblen following these rules:
void
scan_string (char *s)
{
int length = strlen (s);
/* Initialize shift state. */
mblen (NULL, 0);
while (1)
{
int thischar = mblen (s, length);
/* Deal with end of string and invalid characters. */
if (thischar == 0)
break;
if (thischar == -1)
{
error ("invalid multibyte character");
break;
}
/* Advance past this character. */
s += thischar;
length -= thischar;
}
}
The functions mblen, mbtowc and wctomb are not
reentrant when using a multibyte code that uses a shift state. However,
no other library functions call these functions, so you don't have to
worry that the shift state will be changed mysteriously.
The conversion functions mentioned so far in this chapter all had in
common that they operate on character sets which are not directly
specified by the functions. The multibyte encoding used is specified by
the currently selected locale for the LC_CTYPE category. The
wide character set is fixed by the implementation (in the case of GNU C
library it always is UCS4 encoded ISO 10646.
This has of course several problems when it comes to general character conversion:
LC_CTYPE category,
one has to change the LC_CTYPE locale using setlocale.
This introduces major problems for the rest of the programs since
several more functions (e.g., the character classification functions,
see Classification of Characters) use the LC_CTYPE category.
LC_CTYPE selection is global and shared by all
threads.
wchar_t representation there is at least a two-step
process necessary to convert a text using the functions above. One
would have to select the source character set as the multibyte encoding,
convert the text into a wchar_t text, select the destination
character set as the multibyte encoding and convert the wide character
text to the multibyte (= destination) character set.
Even if this is possible (which is not guaranteed) it is a very tiring work. Plus it suffers from the other two raised points even more due to the steady changing of the locale.
The XPG2 standard defines a completely new set of functions which has none of these limitations. They are not at all coupled to the selected locales and they but no constraints on the character sets selected for source and destination. Only the set of available conversions is limiting them. The standard does not specify that any conversion at all must be available. It is a measure of the quality of the implementation.
In the following text first the interface to iconv, the
conversion function, will be described. Comparisons with other
implementations will show what pitfalls lie on the way of portable
applications. At last, the implementation is described as far as
interesting to the advanced user who wants to extend the conversion
capabilities.
iconv example.
iconv
Implementations.
iconv Implementation in the GNU C
library.
This set of functions follows the traditional cycle of using a resource: open-use-close. The interface consists of three functions, each of which implement one step.
Before the interfaces are described it is necessary to introduce a
datatype. Just like other open-use-close interface the functions
introduced here work using a handles and the iconv.h header
defines a special type for the handles used.
| iconv_t | Data Type |
This data type is an abstract type defined in iconv.h. The user
must not assume anything about the definition of this type, it must be
completely opaque.
Objects of this type can get assigned handles for the conversions using
the |
The first step is the function to create a handle.
| iconv_t iconv_open (const char *tocode, const char *fromcode) | Function |
The iconv_open function has to be used before starting a
conversion. The two parameters this function takes determine the
source and destination character set for the conversion and if the
implementation has the possibility to perform such a conversion the
function returns a handle.
If the wanted conversion is not available the function returns
It is not possible to use the same descriptor in different threads to perform independent conversions. Within the data structures associated with the descriptor there is information about the conversion state. This must not be messed up by using it in different conversions. An The GNU C library implementation of This function got introduced early in the X/Open Portability Guide,
version 2. It is supported by all commercial Unices as it is
required for the Unix branding. However, the quality and completeness
of the implementation varies widely. The function is declared in
|
The iconv implementation can associate large data structure with
the handle returned by iconv_open. Therefore it is crucial to
free all the resources once all conversions are carried out and the
conversion is not needed anymore.
| int iconv_close (iconv_t cd) | Function |
The iconv_close function frees all resources associated with the
handle cd which must have been returned by a successful call to
the iconv_open function.
If the function call was successful the return value is 0.
Otherwise it is -1 and
This function was introduced together with the rest of the |
The standard defines only one actual conversion function. This has therefore the most general interface: it allows conversion from one buffer to another. Conversion from a file to a buffer, vice versa, or even file to file can be implemented on top of it.
| size_t iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) | Function |
The iconv function converts the text in the input buffer
according to the rules associated with the descriptor cd and
stores the result in the output buffer. It is possible to call the
function for the same text several times in a row since for stateful
character sets the necessary state information is kept in the data
structures associated with the descriptor.
The input buffer is specified by The output buffer is specified in a similar way. If inbuf is a null pointer the The conversion stops for three reasons. The first is that all characters from the input buffer are converted. This actually can mean two things: really all bytes from the input buffer are consumed or there are some bytes at the end of the buffer which possibly can form a complete character but the input is incomplete. The second reason for a stop is when the output buffer is full. And the third reason is that the input contains invalid characters. In all these cases the buffer pointers after the last successful conversion, for input and output buffer, are stored in inbuf and outbuf and the available room in each buffer is stored in inbytesleft and outbytesleft. Since the character sets selected in the If all input from the input buffer is successfully converted and stored
in the output buffer the function returns the number of non-reversible
conversions performed. In all other cases the return value is
This function was introduced in the XPG2 standard and is declared in the
|
The definition of the iconv function is quite good overall. It
provides quite flexible functionality. The only problems lie in the
boundary cases which are incomplete byte sequences at the end of the
input buffer and invalid input. A third problem, which is not really
a design problem, is the way conversions are selected. The standard
does not say anything about the legitimate names, a minimal set of
available conversions. We will see how this negatively impacts other
implementations, as is demonstrated below.
iconv exampleThe example below features a solution for a common problem. Given that
one knows the internal encoding used by the system for wchar_t
strings one often is in the position to read text from a file and store
it in wide character buffers. One can do this using mbsrtowcs
but then we run into the problems discussed above.
int
file2wcs (int fd, const char *charset, wchar_t *outbuf, size_t avail)
{
char inbuf[BUFSIZ];
size_t insize = 0;
char *wrptr = (char *) outbuf;
int result = 0;
iconv_t cd;
cd = iconv_open ("UCS4", charset);
if (cd == (iconv_t) -1)
{
/* Something went wrong. */
if (errno == EINVAL)
error (0, 0, "conversion from `%s' to `UCS4' no available",
charset);
else
perror ("iconv_open");
/* Terminate the output string. */
*outbuf = L'\0';
return -1;
}
while (avail > 0)
{
size_t nread;
size_t nconv;
char *inptr = inbuf;
/* Read more input. */
nread = read (fd, inbuf + insize, sizeof (inbuf) - insize);
if (nread == 0)
{
/* When we come here the file is completely read.
This still could mean there are some unused
characters in the inbuf. Put them back. */
if (lseek (fd, -insize, SEEK_CUR) == -1)
result = -1;
break;
}
insize += nread;
/* Do the conversion. */
nconv = iconv (cd, &inptr, &insize, &wrptr, &avail);
if (nconv == (size_t) -1)
{
/* Not everything went right. It might only be
an unfinished byte sequence at the end of the
buffer. Or it is a real problem. */
if (errno == EINVAL)
/* This is harmless. Simply move the unused
bytes to the beginning of the buffer so that
they can be used in the next round. */
memmove (inbuf, inptr, insize);
else
{
/* It is a real problem. Maybe we ran out of
space in the output buffer or we have invalid
input. In any case back the file pointer to
the position of the last processed byte. */
lseek (fd, -insize, SEEK_CUR);
result = -1;
break;
}
}
}
/* Terminate the output string. */
*((wchar_t *) wrptr) = L'\0';
if (iconv_close (cd) != 0)
perror ("iconv_close");
return (wchar_t *) wrptr - outbuf;
}
This example shows the most important aspects of using the iconv
functions. It shows how successive calls to iconv can be used to
convert large amounts of text. The user does not have to care about
stateful encodings as the functions take care of everything.
An interesting point is the case where iconv return an error and
errno is set to EINVAL. This is not really an error in
the transformation. It can happen whenever the input character set
contains byte sequences of more than one byte for some character and
texts are not processed in one piece. In this case there is a chance
that a multibyte sequence is cut. The caller than can simply read the
remainder of the takes and feed the offending bytes together with new
character from the input to iconv and continue the work. The
internal state kept in the descriptor is not unspecified after
such an event as it is the case with the conversion functions from the
ISO C standard.
The example also shows the problem of using wide character strings with
iconv. As explained in the description of the iconv
function above the function always takes a pointer to a char
array and the available space is measured in bytes. In the example the
output buffer is a wide character buffer. Therefore we use a local
variable wrptr of type char * which is used in the
iconv calls.
This looks rather innocent but can lead to problems on platforms which
have tight restriction on alignment. Therefore the caller of
iconv has to make sure that the pointers passed are suitable for
access of characters from the appropriate character set. Since in the
above case the input parameter to the function is a wchar_t
pointer this is the case (unless the user violates alignment when
computing the parameter). But in other situations, especially when
writing generic functions where one does not know what type of character
set one uses and therefore treats text as a sequence of bytes, it might
become tricky.
iconv ImplementationsThis is not really the place to discuss the iconv implementation
of other systems but it is necessary to know a bit about them to write
portable programs. The above mentioned problems with the specification
of the iconv functions can lead to portability issues.
The first thing to notice is that due to the large number of character sets in use it is certainly not practical to encode the conversions directly in the C library. Therefore the conversion information must come from files outside the C library. This is usually done in one or both of the following ways:
This solution is problematic as it requires a great deal of effort to apply to all character sets (potentially an infinite set). The differences in the structure of the different character sets is so large that many different variants of the table processing functions must be developed. On top of this the generic nature of these functions make them slower than specifically implemented functions.
This solution provides much more flexibility. The C library itself contains only very little code and therefore reduces the general memory footprint. Also, with a documented interface between the C library and the loadable modules it is possible for third parties to extend the set of available conversion modules. A drawback of this solution is that dynamic loading must be available.
Some implementations in commercial Unices implement a mixture of these these possibilities, the majority only the second solution. Using loadable modules moves the code out of the library itself and keeps the door open for extensions and improvements. But this design is also limiting on some platforms since not many platforms support dynamic loading in statically linked programs. On platforms without his capability it is therefore not possible to use this interface in statically linked programs. The GNU C library has on ELF platforms no problems with dynamic loading in in these situations and therefore this point is mood. The danger is that one gets acquainted with this and forgets about the restrictions on other systems.
A second thing to know about other iconv implementations is that
the number of available conversions is often very limited. Some
implementations provide in the standard release (not special
international or developer releases) at most 100 to 200 conversion
possibilities. This does not mean 200 different character sets are
supported. E.g., conversions from one character set to a set of, say,
10 others counts as 10 conversion. Together with the other direction
this makes already 20. One can imagine the thin coverage these platform
provide. Some Unix vendors even provide only a handful of conversions
which renders them useless for almost all uses.
This directly leads to a third and probably the most problematic point.
The way the iconv conversion functions are implemented on all
known Unix system and the availability of the conversion functions from
character set A to B and the conversion from
B to C does not imply that the
conversion from A to C is available.
This might not seem unreasonable and problematic at first but it is a quite big problem as one will notice shortly after hitting it. To show the problem we assume to write a program which has to convert from A to C. A call like
cd = iconv_open ("C", "A");
does fail according to the assumption above. But what does the program do now? The conversion is really necessary and therefore simply giving up is no possibility.
This is a nuisance. The iconv function should take care of this.
But how should the program proceed from here on? If it would try to
convert to character set B first the two iconv_open
calls
cd1 = iconv_open ("B", "A");
and
cd2 = iconv_open ("C", "B");
will succeed but how to find B?
Unfortunately, the answer is: there is no general solution. On some systems guessing might help. On those systems most character sets can convert to and from UTF8 encoded ISO 10646 or Unicode text. Beside this only some very system-specific methods can help. Since the conversion functions come from loadable modules and these modules must be stored somewhere in the filesystem, one could try to find them and determine from the available file which conversions are available and whether there is an indirect route from A to C.
This shows one of the design errors of iconv mentioned above. It
should at least be possible to determine the list of available
conversion programmatically so that if iconv_open says there is
no such conversion, one could make sure this also is true for indirect
routes.
iconv Implementation in the GNU C libraryAfter reading about the problems of iconv implementations in the
last section it is certainly good to note that the implementation in
the GNU C library has none of the problems mentioned above. What
follows is a step-by-step analysis of the points raised above. The
evaluation is based on the current state of the development (as of
January 1999). The development of the iconv functions is not
complete, but basic functionality has solidified.
The GNU C library's iconv implementation uses shared loadable
modules to implement the conversions. A very small number of
conversions are built into the library itself but these are only rather
trivial conversions.
All the benefits of loadable modules are available in the GNU C library
implementation. This is especially appealing since the interface is
well documented (see below) and it therefore is easy to write new
conversion modules. The drawback of using loadable objects is not a
problem in the GNU C library, at least on ELF systems. Since the
library is able to load shared objects even in statically linked
binaries this means that static linking needs not to be forbidden in
case one wants to use iconv.
The second mentioned problem is the number of supported conversions. Currently, the GNU C library supports more than 150 character sets. The way the implementation is designed the number of supported conversions is greater than 22350 (150 times 149). If any conversion from or to a character set is missing it can easily be added.
Particularly impressive as it may be, this high number is due to the
fact that the GNU C library implementation of iconv does not have
the third problem mentioned above. I.e., whenever there is a conversion
from a character set A to B and from
B to C it is always possible to convert from
A to C directly. If the iconv_open
returns an error and sets errno to EINVAL this really
means there is no known way, directly or indirectly, to perform the
wanted conversion.
This is achieved by providing for each character set a conversion from and to UCS4 encoded ISO 10646. Using ISO 10646 as an intermediate representation it is possible to triangulate, i.e., converting with an intermediate representation.
There is no inherent requirement to provide a conversion to ISO 10646 for a new character set and it is also possible to provide other conversions where neither source nor destination character set is ISO 10646. The currently existing set of conversions is simply meant to cover all conversions which might be of interest.
All currently available conversions use the triangulation method above, making conversion run unnecessarily slow. If, e.g., somebody often needs the conversion from ISO-2022-JP to EUC-JP, a quicker solution would involve direct conversion between the two character sets, skipping the input to ISO 10646 first. The two character sets of interest are much more similar to each other than to ISO 10646.
In such a situation one can easy write a new conversion and provide it
as a better alternative. The GNU C library iconv implementation
would automatically use the module implementing the conversion if it is
specified to be more efficient.
gconv-modules filesAll information about the available conversions comes from a file named
gconv-modules which can be found in any of the directories along
the GCONV_PATH. The gconv-modules files are line-oriented
text files, where each of the lines has one of the following formats:
alias define an alias name for a character
set. There are two more words expected on the line. The first one
defines the alias name and the second defines the original name of the
character set. The effect is that it is possible to use the alias name
in the fromset or toset parameters of iconv_open and
achieve the same result as when using the real character set name.
This is quite important as a character set has often many different
names. There is normally always an official name but this need not
correspond to the most popular name. Beside this many character sets
have special names which are somehow constructed. E.g., all character
sets specified by the ISO have an alias of the form
ISO-IR-nnn where nnn is the registration number.
This allows programs which know about the registration number to
construct character set names and use them in iconv_open calls.
More on the available names and aliases follows below.
module introduce an available conversion
module. These lines must contain three or four more words.
The first word specifies the source character set, the second word the
destination character set of conversion implemented in this module. The
third word is the name of the loadable module. The filename is
constructed by appending the usual shared object suffix (normally
.so) and this file is then supposed to be found in the same
directory the gconv-modules file is in. The last word on the
line, which is optional, is a numeric value representing the cost of the
conversion. If this word is missing a cost of 1 is assumed. The
numeric value itself does not matter that much; what counts are the
relative values of the sums of costs for all possible conversion paths.
Below is a more precise description of the use of the cost value.
Returning to the example above where one has written a module to directly
convert from ISO-2022-JP to EUC-JP and back. All what has to be done is
to put the new module, be its name ISO2022JP-EUCJP.so, in a directory
and add a file gconv-modules with the following content in the
same directory:
module ISO-2022-JP// EUC-JP// ISO2022JP-EUCJP 1 module EUC-JP// ISO-2022-JP// ISO2022JP-EUCJP 1
To see why this is sufficient, it is necessary to understand how the
conversion used by iconv (and described in the descriptor) is
selected. The approach to this problem is quite simple.
At the first call of the iconv_open function the program reads
all available gconv-modules files and builds up two tables: one
containing all the known aliases and another which contains the
information about the conversions and which shared object implements
them.
iconvThe set of available conversions form a directed graph with weighted
edges. The weights on the edges are the costs specified in the
gconv-modules files. The iconv_open function uses an
algorithm suitable for search for the best path in such a graph and so
constructs a list of conversions which must be performed in succession
to get the transformation from the source to the destination character
set.
Explaining why the above gconv-modules files allows the
iconv implementation to resolve the specific ISO-2022-JP to
EUC-JP conversion module instead of the conversion coming with the
library itself is straightforward. Since the latter conversion takes two
steps (from ISO-2022-JP to ISO 10646 and then from ISO 10646 to
EUC-JP) the cost is 1+1 = 2. But the above gconv-modules
file specifies that the new conversion modules can perform this
conversion with only the cost of 1.
A mysterious piece about the gconv-modules file above (and also
the file coming with the GNU C library) are the names of the character
sets specified in the module lines. Why do almost all the names
end in //? And this is not all: the names can actually be
regular expressions. At this point of time this mystery should not be
revealed, unless you have the relevant spell-casting materials: ashes
from an original DOS 6.2 boot disk burnt in effigy, a crucifix
blessed by St. Emacs, assorted herbal roots from Central America, sand
from Cebu, etc. Sorry! The part of the implementation where
this is used is not yet finished. For now please simply follow the
existing examples. It'll become clearer once it is. -drepper
A last remark about the gconv-modules is about the names not
ending with //. There often is a character set named
INTERNAL mentioned. From the discussion above and the chosen
name it should have become clear that this is the name for the
representation used in the intermediate step of the triangulation. We
have said that this is UCS4 but actually it is not quite right. The
UCS4 specification also includes the specification of the byte ordering
used. Since a UCS4 value consists of four bytes a stored value is
effected by byte ordering. The internal representation is not
the same as UCS4 in case the byte ordering of the processor (or at least
the running process) is not the same as the one required for UCS4. This
is done for performance reasons as one does not want to perform
unnecessary byte-swapping operations if one is not interested in actually
seeing the result in UCS4. To avoid trouble with endianess the internal
representation consistently is named INTERNAL even on big-endian
systems where the representations are identical.
iconv module data structuresSo far this section described how modules are located and considered to be used. What remains to be described is the interface of the modules so that one can write new ones. This section describes the interface as it is in use in January 1999. The interface will change in future a bit but hopefully only in an upward compatible way.
The definitions necessary to write new modules are publicly available
in the non-standard header gconv.h. The following text will
therefore describe the definitions from this header file. But first it
is necessary to get an overview.
From the perspective of the user of iconv the interface is quite
simple: the iconv_open function returns a handle which can be
used in calls to iconv and finally the handle is freed with a call
to iconv_close. The problem is: the handle has to be able to
represent the possibly long sequences of conversion steps and also the
state of each conversion since the handle is all which is passed to the
iconv function. Therefore the data structures are really the
elements to understanding the implementation.
We need two different kinds of data structures. The first describes the
conversion and the second describes the state etc. There are really two
type definitions like this in gconv.h.
| struct gconv_step | Data type |
This data structure describes one conversion a module can perform. For
each function in a loaded module with conversion functions there is
exactly one object of this type. This object is shared by all users of
the conversion. I.e., this object does not contain any information
corresponding to an actual conversion. It only describes the conversion
itself.
|
| struct gconv_step_data | Data type |
This is the data structure which contains the information specific to
each use of the conversion functions.
|
iconv module interfacesWith the knowledge about the data structures we now can describe the conversion functions itself. To understand the interface a bit of knowledge about the functionality in the C library which loads the objects with the conversions is necessary.
It is often the case that one conversion is used more than once. I.e.,
there are several iconv_open calls for the same set of character
sets during one program run. The mbsrtowcs et.al. functions in
the GNU C library also use the iconv functionality which
increases the number of uses of the same functions even more.
For this reason the modules do not get loaded exclusively for one
conversion. Instead a module once loaded can be used by arbitrarily many
iconv or mbsrtowcs calls at the same time. The splitting
of the information between conversion function specific information and
conversion data makes this possible. The last section showed the two
data structures used to do this.
This is of course also reflected in the interface and semantics of the functions the modules must provide. There are three functions which must have the following names:
gconv_init
gconv_init function initializes the conversion function
specific data structure. This very same object is shared by all
conversion which use this conversion and therefore no state information
about the conversion itself must be stored in here. If a module
implements more than one conversion the gconv_init function will be
called multiple times.
gconv_end
gconv_end function is responsible to free all resources
allocated by the gconv_init function. If there is nothing to do
this function can be missing. Special care must be taken if the module
implements more than one conversion and the gconv_init function
does not allocate the same resources for all conversions.
gconv
gconv_init and the conversion data, specific to
this use of the conversion functions.
There are three data types defined for the three module interface function and these define the interface.
| int (*gconv_init_fct) (struct gconv_step *) | Data type |
|
This specifies the interface of the initialization function of the
module. It is called exactly once for each conversion the module
implements.
As explained int the description of the
If the initialization function needs to communication some information
to the conversion function this can happen using the #define MIN_NEEDED_FROM 1
#define MAX_NEEDED_FROM 4
#define MIN_NEEDED_TO 4
#define MAX_NEEDED_TO 4
int
gconv_init (struct gconv_step *step)
{
/* Determine which direction. */
struct iso2022jp_data *new_data;
enum direction dir = illegal_dir;
enum variant var = illegal_var;
int result;
if (__strcasecmp (step->from_name, "ISO-2022-JP//") == 0)
{
dir = from_iso2022jp;
var = iso2022jp;
}
else if (__strcasecmp (step->to_name, "ISO-2022-JP//") == 0)
{
dir = to_iso2022jp;
var = iso2022jp;
}
else if (__strcasecmp (step->from_name, "ISO-2022-JP-2//") == 0)
{
dir = from_iso2022jp;
var = iso2022jp2;
}
else if (__strcasecmp (step->to_name, "ISO-2022-JP-2//") == 0)
{
dir = to_iso2022jp;
var = iso2022jp2;
}
result = GCONV_NOCONV;
if (dir != illegal_dir)
{
new_data = (struct iso2022jp_data *)
malloc (sizeof (struct iso2022jp_data));
result = GCONV_NOMEM;
if (new_data != NULL)
{
new_data->dir = dir;
new_data->var = var;
step->data = new_data;
if (dir == from_iso2022jp)
{
step->min_needed_from = MIN_NEEDED_FROM;
step->max_needed_from = MAX_NEEDED_FROM;
step->min_needed_to = MIN_NEEDED_TO;
step->max_needed_to = MAX_NEEDED_TO;
}
else
{
step->min_needed_from = MIN_NEEDED_TO;
step->max_needed_from = MAX_NEEDED_TO;
step->min_needed_to = MIN_NEEDED_FROM;
step->max_needed_to = MAX_NEEDED_FROM + 2;
}
/* Yes, this is a stateful encoding. */
step->stateful = 1;
result = GCONV_OK;
}
}
return result;
}
The function first checks which conversion is wanted. The module from which this function is taken implements four different conversion and which one is selected can be determined by comparing the names. The comparison should always be done without paying attention to the case. Then a data structure is allocated which contains the necessary
information about which conversion is selected. The data structure
One interesting thing is the initialization of the The possible return values of the initialization function are:
|
The functions called before the module is unloaded is significantly easier. It often has nothing at all to do in which case it can be left out completely.
| void (*gconv_end_fct) (struct gconv_step *) | Data type |
The task of this function is it to free all resources allocated in the
initialization function. Therefore only the data element of the
object pointed to by the argument is of interest. Continuing the
example from the initialization function, the finalization function
looks like this:
void
gconv_end (struct gconv_step *data)
{
free (data->data);
}
|
The most important function is the conversion function itself. It can get quite complicated for complex character sets. But since this is not of interest here we will only describe a possible skeleton for the conversion function.
| int (*gconv_fct) (struct gconv_step *, struct gconv_step_data *, const char **, const char *, size_t *, int) | Data type |
The conversion function can be called for two basic reason: to convert
text or to reset the state. From the description of the iconv
function it can be seen why the flushing mode is necessary. What mode
is selected is determined by the sixth argument, an integer. If it is
nonzero it means that flushing is selected.
Common to both mode is where the output buffer can be found. The
information about this buffer is stored in the conversion step data. A
pointer to this is passed as the second argument to this function. The
description of the What has to be done for flushing depends on the source character set.
If it is not stateful nothing has to be done. Otherwise the function
has to emit a byte sequence to bring the state object in the initial
state. Once this all happened the other conversion modules in the chain
of conversions have to get the same chance. Whether another step
follows can be determined from the The more interesting mode is when actually text has to be converted. The first step in this case is to convert as much text as possible from the input buffer and store the result in the output buffer. The start of the input buffer is determined by the third argument which is a pointer to a pointer variable referencing the beginning of the buffer. The fourth argument is a pointer to the byte right after the last byte in the buffer. The conversion has to be performed according to the current state if the
character set is stateful. The state is stored in an object pointed to
by the What now happens depends on whether this step is the last one or not.
If it is the last step the only thing which has to be done is to update
the In case the step is not the last one the later conversion functions have to get a chance to do their work. Therefore the appropriate conversion function has to be called. The information about the functions is stored in the conversion data structures, passed as the first parameter. This information and the step data are stored in arrays so the next element in both cases can be found by simple pointer arithmetic: int
gconv (struct gconv_step *step, struct gconv_step_data *data,
const char **inbuf, const char *inbufend, size_t *written,
int do_flush)
{
struct gconv_step *next_step = step + 1;
struct gconv_step_data *next_data = data + 1;
...
The next_step->fct (next_step, next_data, &outerr, outbuf, written, 0) But this is not yet all. Once the function call returns the conversion
function might have some more to do. If the return value of the
function is A requirement for the conversion function is that the input buffer pointer (the third argument) always points to the last character which was put in the converted form in the output buffer. This is trivial true after the conversion performed in the current step. But if the conversion functions deeper down the stream stop prematurely not all characters from the output buffer are consumed and therefore the input buffer pointers must be backed of to the right position. This is easy to do if the input and output character sets have a fixed width for all characters. In this situation we can compute how many characters are left in the output buffer and therefore can correct the input buffer pointer appropriate with a similar computation. Things are getting tricky if either character set has character represented with variable length byte sequences and it gets even more complicated if the conversion has to take care of the state. In these cases the conversion has to be performed once again, from the known state before the initial conversion. I.e., if necessary the state of the conversion has to be reset and the conversion loop has to be executed again. The difference now is that it is known how much input must be created and the conversion can stop before converting the first unused character. Once this is done the input buffer pointers must be updated again and the function can return. One final thing should be mentioned. If it is necessary for the
conversion to know whether it is the first invocation (in case a prolog
has to be emitted) the conversion function should just before returning
to the caller increment the The return value must be one of the following values:
The following example provides a framework for a conversion function. In case a new conversion has to be written the holes in this implementation have to be filled and that is it. int
gconv (struct gconv_step *step, struct gconv_step_data *data,
const char **inbuf, const char *inbufend, size_t *written,
int do_flush)
{
struct gconv_step *next_step = step + 1;
struct gconv_step_data *next_data = data + 1;
gconv_fct fct = next_step->fct;
int status;
/* If the function is called with no input this means we have
to reset to the initial state. The possibly partly
converted input is dropped. */
if (do_flush)
{
status = GCONV_OK;
/* Possible emit a byte sequence which put the state object
into the initial state. */
/* Call the steps down the chain if there are any but only
if we successfully emitted the escape sequence. */
if (status == GCONV_OK && ! data->is_last)
status = fct (next_step, next_data, NULL, NULL,
written, 1);
}
else
{
/* We preserve the initial values of the pointer variables. */
const char *inptr = *inbuf;
char *outbuf = data->outbuf;
char *outend = data->outbufend;
char *outptr;
do
{
/* Remember the start value for this round. */
inptr = *inbuf;
/* The outbuf buffer is empty. */
outptr = outbuf;
/* For stateful encodings the state must be safe here. */
/* Run the conversion loop.
|
This information should be sufficient to write new modules. Anybody doing so should also take a look at the available source code in the GNU C library sources. It contains many examples of working and optimized modules.
Different countries and cultures have varying conventions for how to communicate. These conventions range from very simple ones, such as the format for representing dates and times, to very complex ones, such as the language spoken.
Internationalization of software means programming it to be able to adapt to the user's favorite conventions. In ISO C, internationalization works by means of locales. Each locale specifies a collection of conventions, one convention for each purpose. The user chooses a set of conventions by specifying a locale (via environment variables).
All programs inherit the chosen locale as part of their environment. Provided the programs are written to obey the choice of locale, they will follow the conventions preferred by the user.
Each locale specifies conventions for several purposes, including the following:
Some aspects of adapting to the specified locale are handled
automatically by the library subroutines. For example, all your program
needs to do in order to use the collating sequence of the chosen locale
is to use strcoll or strxfrm to compare strings.
Other aspects of locales are beyond the comprehension of the library. For example, the library can't automatically translate your program's output messages into other languages. The only way you can support output in the user's favorite language is to program this more or less by hand. The C library provides functions to handle translations for multiple languages easily.
This chapter discusses the mechanism by which you can modify the current locale. The effects of the current locale on specific library functions are discussed in more detail in the descriptions of those functions.
The simplest way for the user to choose a locale is to set the
environment variable LANG. This specifies a single locale to use
for all purposes. For example, a user could specify a hypothetical
locale named espana-castellano to use the standard conventions of
most of Spain.
The set of locales supported depends on the operating system you are
using, and so do their names. We can't make any promises about what
locales will exist, except for one standard locale called C or
POSIX. Later we will describe how to construct locales XXX.
A user also has the option of specifying different locales for different purposes--in effect, choosing a mixture of multiple locales.
For example, the user might specify the locale espana-castellano
for most purposes, but specify the locale usa-english for
currency formatting. This might make sense if the user is a
Spanish-speaking American, working in Spanish, but representing monetary
amounts in US dollars.
Note that both locales espana-castellano and usa-english,
like all locales, would include conventions for all of the purposes to
which locales apply. However, the user can choose to use each locale
for a particular subset of those purposes.
The purposes that locales serve are grouped into categories, so
that a user or a program can choose the locale for each category
independently. Here is a table of categories; each name is both an
environment variable that a user can set, and a macro name that you can
use as an argument to setlocale.
LC_COLLATE
strcoll
and strxfrm); see Collation Functions.
LC_CTYPE
LC_MONETARY
LC_NUMERIC
LC_TIME
LC_MESSAGES
LC_ALL
setlocale to set a single locale for all purposes. Setting
this environment variable overwrites all selections by the other
LC_* variables or LANG.
LANG
When developing the message translation functions it was felt that the
functionality provided by the variables above is not sufficient. E.g., it
should be possible to specify more than one locale name. For an example
take a Swedish user who better speaks German than English, the programs
messages by default are written in English. Then it should be possible
to specify that the first choice for the language is Swedish, the second
choice is German, and if this also fails English is used. This is
possible with the variable LANGUAGE. For further description of
this GNU extension see Using gettextized software.
A C program inherits its locale environment variables when it starts up.
This happens automatically. However, these variables do not
automatically control the locale used by the library functions, because
ISO C says that all programs start by default in the standard C
locale. To use the locales specified by the environment, you must call
setlocale. Call it as follows:
setlocale (LC_ALL, "");
to select a locale based on the user choice of the appropriate environment variables.
You can also use setlocale to specify a particular locale, for
general use or for a specific category.
The symbols in this section are defined in the header file locale.h.
| char * setlocale (int category, const char *locale) | Function |
The function setlocale sets the current locale for
category category to locale.
If category is You can also use this function to find out the current locale by passing
a null pointer as the locale argument. In this case,
The string returned by You should not modify the string returned by When you read the current locale for category To ensure to be able to use the string encoding the currently selected locale at a later time one has to make a copy of the string. It is not guaranteed that the return value stays valid all the time. When the locale argument is not a null pointer, the string returned
by If you specify an empty string for locale, this means to read the appropriate environment variable and use its value to select the locale for category. If a nonempty string is given for locale the locale with this name is used, if this is possible. If you specify an invalid locale name, |
Here is an example showing how you might use setlocale to
temporarily switch to a new locale.
#include <stddef.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
void
with_other_locale (char *new_locale,
void (*subroutine) (int),
int argument)
{
char *old_locale, *saved_locale;
/* Get the name of the current locale. */
old_locale = setlocale (LC_ALL, NULL);
/* Copy the name so it won't be clobbered by setlocale. */
saved_locale = strdup (old_locale);
if (saved_locale == NULL)
fatal ("Out of memory");
/* Now change the locale and do some stuff with it. */
setlocale (LC_ALL, new_locale);
(*subroutine) (argument);
/* Restore the original locale. */
setlocale (LC_ALL, saved_locale);
free (saved_locale);
}
Portability Note: Some ISO C systems may define additional
locale categories and future versions of the library will do so. For
portability, assume that any symbol beginning with LC_ might be
defined in locale.h.
The only locale names you can count on finding on all operating systems are these three standard ones:
"C"
"POSIX"
""
Defining and installing named locales is normally a responsibility of the system administrator at your site (or the person who installed the GNU C library). It is also possible for the user to create private locales. All this will be discussed later when describing the tool to do so XXX.
If your program needs to use something other than the C locale,
it will be more portable if you use whatever locale the user specifies
with the environment, rather than trying to specify some non-standard
locale explicitly by name. Remember, different machines might have
different sets of locales installed.
There are several ways to access the locale information. The simplest way is to let the C library itself do the work. Several of the functions in this library access implicitly the locale data and use what information is available in the currently selected locale. This is how the locale model is meant to work normally.
As an example take the strftime function which is meant to nicely
format date and time information (see Formatting Date and Time).
Part of the standard information contained in the LC_TIME
category are, e.g., the names of the months. Instead of requiring the
programmer to take care of providing the translations the
strftime function does this all by itself. When using %A
in the format string this will be replaced by the appropriate weekday
name of the locale currently selected for LC_TIME. This is the
easy part and wherever possible functions do things automatically as in
this case.
But there are quite often situations when there is simply no functions
to perform the task or it is simply not possible to do the work
automatically. For these cases it is necessary to access the
information in the locale directly. To do this the C library provides
two functions: localeconv and nl_langinfo. The former is
part of ISO C and therefore portable, but has a brain-damaged
interface. The second is part of the Unix interface and is portable in
as far as the system follows the Unix standards.
localeconv.
nl_langinfo.
localeconv: It is portable but ...Together with the setlocale function the ISO C people
invented localeconv function. It is a masterpiece of misdesign.
It is expensive to use, it is not extendable, and is not generally
usable as it provides access only to the LC_MONETARY and
LC_NUMERIC related information. If it is applicable for a
certain situation it should nevertheless be used since it is very
portable. In general it is better to use the function strfmon
which can be used to format monetary amounts correctly according to the
selected locale by implicitly using this information.
| struct lconv * localeconv (void) | Function |
The localeconv function returns a pointer to a structure whose
components contain information about how numeric and monetary values
should be formatted in the current locale.
You should not modify the structure or its contents. The structure might
be overwritten by subsequent calls to |
| struct lconv | Data Type |
This is the data type of the value returned by localeconv. Its
elements are described in the following subsections.
|
If a member of the structure struct lconv has type char,
and the value is CHAR_MAX, it means that the current locale has
no value for that parameter.
$).
These are the standard members of struct lconv; there may be
others.
char *decimal_point
char *mon_decimal_point
C locale, the
value of decimal_point is ".", and the value of
mon_decimal_point is "".
char *thousands_sep
char *mon_thousands_sep
C locale, both members have a value of
"" (the empty string).
char *grouping
char *mon_grouping
grouping applies to non-monetary quantities
and mon_grouping applies to monetary quantities. Use either
thousands_sep or mon_thousands_sep to separate the digit
groups.
Each string is made up of decimal numbers separated by semicolons. Successive numbers (from left to right) give the sizes of successive groups (from right to left, starting at the decimal point). The last number in the string is used over and over for all the remaining groups.
If the last integer is -1, it means that there is no more
grouping--or, put another way, any remaining digits form one large
group without separators.
For example, if grouping is "4;3;2", the correct grouping
for the number 123456787654321 is 12, 34,
56, 78, 765, 4321. This uses a group of 4
digits at the end, preceded by a group of 3 digits, preceded by groups
of 2 digits (as many as needed). With a separator of ,, the
number would be printed as 12,34,56,78,765,4321.
A value of "3" indicates repeated groups of three digits, as
normally used in the U.S.
In the standard C locale, both grouping and
mon_grouping have a value of "". This value specifies no
grouping at all.
char int_frac_digits
char frac_digits
In the standard C locale, both of these members have the value
CHAR_MAX, meaning "unspecified". The ISO standard doesn't say
what to do when you find this the value; we recommend printing no
fractional digits. (This locale also specifies the empty string for
mon_decimal_point, so printing any fractional digits would be
confusing!)
These members of the struct lconv structure specify how to print
the symbol to identify a monetary value--the international analog of
$ for US dollars.
Each country has two standard currency symbols. The local currency symbol is used commonly within the country, while the international currency symbol is used internationally to refer to that country's currency when it is necessary to indicate the country unambiguously.
For example, many countries use the dollar as their monetary unit, and when dealing with international currencies it's important to specify that one is dealing with (say) Canadian dollars instead of U.S. dollars or Australian dollars. But when the context is known to be Canada, there is no need to make this explicit--dollar amounts are implicitly assumed to be in Canadian dollars.
char *currency_symbol
In the standard C locale, this member has a value of ""
(the empty string), meaning "unspecified". The ISO standard doesn't
say what to do when you find this value; we recommend you simply print
the empty string as you would print any other string found in the
appropriate member.
char *int_curr_symbol
The value of int_curr_symbol should normally consist of a
three-letter abbreviation determined by the international standard
ISO 4217 Codes for the Representation of Currency and Funds,
followed by a one-character separator (often a space).
In the standard C locale, this member has a value of ""
(the empty string), meaning "unspecified". We recommend you simply
print the empty string as you would print any other string found in the
appropriate member.
char p_cs_precedes
char n_cs_precedes
1 if the currency_symbol string should
precede the value of a monetary amount, or 0 if the string should
follow the value. The p_cs_precedes member applies to positive
amounts (or zero), and the n_cs_precedes member applies to
negative amounts.
In the standard C locale, both of these members have a value of
CHAR_MAX, meaning "unspecified". The ISO standard doesn't say
what to do when you find this value, but we recommend printing the
currency symbol before the amount. That's right for most countries.
In other words, treat all nonzero values alike in these members.
The POSIX standard says that these two members apply to the
int_curr_symbol as well as the currency_symbol. The ISO
C standard seems to imply that they should apply only to the
currency_symbol--so the int_curr_symbol should always
precede the amount.
We can only guess which of these (if either) matches the usual
conventions for printing international currency symbols. Our guess is
that they should always precede the amount. If we find out a reliable
answer, we will put it here.
char p_sep_by_space
char n_sep_by_space
1 if a space should appear between the
currency_symbol string and the amount, or 0 if no space
should appear. The p_sep_by_space member applies to positive
amounts (or zero), and the n_sep_by_space member applies to
negative amounts.
In the standard C locale, both of these members have a value of
CHAR_MAX, meaning "unspecified". The ISO standard doesn't say
what you should do when you find this value; we suggest you treat it as
one (print a space). In other words, treat all nonzero values alike in
these members.
These members apply only to currency_symbol. When you use
int_curr_symbol, you never print an additional space, because
int_curr_symbol itself contains the appropriate separator.
The POSIX standard says that these two members apply to the
int_curr_symbol as well as the currency_symbol. But an
example in the ISO C standard clearly implies that they should apply
only to the currency_symbol--that the int_curr_symbol
contains any appropriate separator, so you should never print an
additional space.
Based on what we know now, we recommend you ignore these members when printing international currency symbols, and print no extra space.
These members of the struct lconv structure specify how to print
the sign (if any) in a monetary value.
char *positive_sign
char *negative_sign
In the standard C locale, both of these members have a value of
"" (the empty string), meaning "unspecified".
The ISO standard doesn't say what to do when you find this value; we
recommend printing positive_sign as you find it, even if it is
empty. For a negative value, print negative_sign as you find it
unless both it and positive_sign are empty, in which case print
- instead. (Failing to indicate the sign at all seems rather
unreasonable.)
char p_sign_posn
char n_sign_posn
positive_sign or negative_sign.) The possible values are
as follows:
0
1
2
3
4
CHAR_MAX
C locale.
The ISO standard doesn't say what you should do when the value is
CHAR_MAX. We recommend you print the sign after the currency
symbol.
It is not clear whether you should let these members apply to the international currency format or not. POSIX says you should, but intuition plus the examples in the ISO C standard suggest you should not. We hope that someone who knows well the conventions for formatting monetary quantities will tell us what we should recommend.
When writing the X/Open Portability Guide the authors realized that the
localeconv function is not enough to provide reasonable access to
the locale information. The information which was meant to be available
in the locale (as later specified in the POSIX.1 standard) requires more
possibilities to access it. Therefore the nl_langinfo function
was introduced.
| char * nl_langinfo (nl_item item) | Function |
The nl_langinfo function can be used to access individual
elements of the locale categories. I.e., unlike the localeconv
function which always returns all the information nl_langinfo
lets the caller select what information is necessary. This is very
fast and it is no problem to call this function multiple times.
The second advantage is that not only the numeric and monetary
formatting information is available. Also the information of the
The type
The file Please note that the return value for any valid argument can be used for
in all situations (with the possible exception of the am/pm time format
related values). If the user has not selected any locale for the
appropriate category If the argument item is not valid a pointer to an empty string is returned. |
An example for the use of nl_langinfo is a function which has to
print a given date and time in the locale specific way. At first one
might think the since strftime internally uses the locale
information writing something like the following is enough:
size_t
i18n_time_n_data (char *s, size_t len, const struct tm *tp)
{
return strftime (s, len, "%X %D", tp);
}
The format contains no weekday or month names and therefore is
internationally usable. Wrong! The output produced is something like
"hh:mm:ss MM/DD/YY". This format is only recognizable in the
USA. Other countries use different formats. Therefore the function
should be rewritten like this:
size_t
i18n_time_n_data (char *s, size_t len, const struct tm *tp)
{
return strftime (s, len, nl_langinfo (D_T_FMT), tp);
}
Now the date and time format which is explicitly selected for the locale in place when the program runs is used. If the user selects the locale correctly there should never be a misunderstanding over the time and date format.
We have seen that the structure returned by localeconv as well as
the values given to nl_langinfo allow to retrieve the various
pieces of locale specific information to format numbers and monetary
amounts. But we have also seen that the rules underlying this
information are quite complex.
Therefore the X/Open standards introduce a function which uses this information from the locale and so makes it is for the user to format numbers according to these rules.
| ssize_t strfmon (char *s, size_t maxsize, const char *format, ...) | Function |
The strfmon function is similar to the strftime function
in that it takes a description of a buffer (with size), a format string
and values to write into a buffer a textual representation of the values
according to the format string. As for strftime the function
also returns the number of bytes written into the buffer.
There are two difference:
The next part of a specification is an, again optional, specification of
the field width. The width is given by digits following the flags. If
no width is specified it is assumed to be 0. The width value is
used after it is determined how much space the printed result needs. If
it does not require fewer characters than specified by the width value
nothing happens. Otherwise the output is extended to use as many
characters as the width says by filling with spaces. At which side
depends on whether the So far the format looks familiar as it is similar to The next field is introduced by a As a GNU extension the Finally as the last component of the format there must come a format specifying. There are three specifiers defined:
As it is done for The return value of the function is the number of characters stored in
s, including the terminating NUL byte. If the number of
characters stored would exceed maxsize the function returns
-1 and the content of the buffer s is unspecified. In this
case |
A few examples should make it clear how to use this function. It is
assumed that all the following pieces of code are executed in a program
which uses the locale valid for the USA (en_US). The simplest
form of the format is this:
strfmon (buf, 100, "@%n@%n@%n@", 123.45, -567.89, 12345.678);
The output produced is
"@$123.45@-$567.89@$12,345.68@"
We can notice several things here. First, the width for all formats is
different. We have not specified a width in the format string and so
this is no wonder. Second, the third number is printed using thousands
separators. The thousands separator for the en_US locale is a
comma. Beside this the number is rounded. The .678 are rounded
to .68 since the format does not specify a precision and the
default value in the locale is 2. A last thing is that the
national currency symbol is printed since %n was used, not
i. The next example shows how we can align the output.
strfmon (buf, 100, "@%=*11n@%=*11n@%=*11n@", 123.45, -567.89, 12345.678);
The output this time is:
"@ $123.45@ -$567.89@ $12,345.68@"
Two things stand out. First, all fields have the same width (eleven characters) since this is the width given in the format and since no number required more characters to be printed. The second important point is that the fill character is not used. This is correct since the white space was not used to fill the space specified by the right precision, but instead it is used to fill to the given width. The difference becomes obvious if we now add a right width specification.
strfmon (buf, 100, "@%=*11#5n@%=*11#5n@%=*11#5n@",
123.45, -567.89, 12345.678);
The output is
"@ $***123.45@-$***567.89@ $12,456.68@"
Here we can see that all the currency symbols are now aligned and the space between the currency sign and the number is filled with the selected fill character. Please note that although the right precision is selected to be 5 and 123.45 has three characters right of the radix character, the space is filled with three asterisks. This is correct since as explained above, the right precision does not count the characters used for the thousands separators in. One last example should explain the remaining functionality.
strfmon (buf, 100, "@%=0(16#5.3i@%=0(16#5.3i@%=0(16#5.3i@",
123.45, -567.89, 12345.678);
This rather complex format string produces the following output:
"@ USD 000123,450 @(USD 000567.890)@ USD 12,345.678 @"
The most noticeable change is the use of the alternative style to
represent negative numbers. In financial circles it is often done using
parentheses and this is what the ( flag selected. The fill character
is now 0. Please note that this 0 character is not
regarded as a numeric zero and therefore the first and second number are
not printed using a thousands separator. Since we use in the format the
specifier i instead of n now the international form of the
currency symbol is used. This is a four letter string, in this case
"USD ". The last point is that since the left precision is
selected to be three the first and second number are printed with an
extra zero at the end and the third number is printed unrounded.
The program's interface with the human should be designed in a way to ease the human the task. One of the possibilities is to use messages in whatever language the user prefers.
Printing messages in different languages can be implemented in different ways. One could add all the different languages in the source code and add among the variants every time a message has to be printed. This is certainly no good solution since extending the set of languages is difficult (the code must be changed) and the code itself can become really big with dozens of message sets.
A better solution is to keep the message sets for each language are kept in separate files which are loaded at runtime depending on the language selection of the user.
The GNU C Library provides two different sets of functions to support
message translation. The problem is that neither of the interfaces is
officially defined by the POSIX standard. The catgets family of
functions is defined in the X/Open standard but this is derived from
industry decisions and therefore not necessarily based on reasonable
decisions.
As mentioned above the message catalog handling provides easy extendibility by using external data files which contain the message translations. I.e., these files contain for each of the messages used in the program a translation for the appropriate language. So the tasks of the message handling functions are
The two approaches mainly differ in the implementation of this last step. The design decisions made for this influences the whole rest.
catgets family of functions.
gettext family of functions.
The catgets functions are based on the simple scheme:
Associate every message to translate in the source code with a unique identifier. To retrieve a message from a catalog file solely the identifier is used.
This means for the author of the program that s/he will have to make sure the meaning of the identifier in the program code and in the message catalogs are always the same.
Before a message can be translated the catalog file must be located. The user of the program must be able to guide the responsible function to find whatever catalog the user wants. This is separated from what the programmer had in mind.
All the types, constants and functions for the catgets functions
are defined/declared in the nl_types.h header file.
catgets function family.
catgets interface.
catgets function family
| nl_catd catopen (const char *cat_name, int flag) | Function |
The catgets function tries to locate the message data file names
cat_name and loads it when found. The return value is of an
opaque type and can be used in calls to the other functions to refer to
this loaded catalog.
The return value is Locating the catalog file must happen in a way which lets the user of the program influence the decision. It is up to the user to decide about the language to use and sometimes it is useful to use alternate catalog files. All this can be specified by the user by setting some environment variables. The first problem is to find out where all the message catalogs are stored. Every program could have its own place to keep all the different files but usually the catalog files are grouped by languages and the catalogs for all programs are kept in the same place. To tell the /usr/share/locale/%L/%N:/usr/share/locale/%L/LC_MESSAGES/%N First one can see that more than one directory can be specified (with
the usual syntax of separating them by colons). The next things to
observe are the format string,
Using prefix/share/locale/%L/%N:prefix/share/locale/%L/LC_MESSAGES/%N where prefix is given to The remaining problem is to decide which must be used. The value
decides about the substitution of the format elements mentioned above.
First of all the user can specify a path in the message catalog name
(i.e., the name contains a slash character). In this situation the
Otherwise the values of environment variables from the standard
environment are examined (see Standard Environment). Which
variables are examined is decided by the flag parameter of
If flag is zero only the In any case the environment variable should have a value of the form
The return value of the function is in any case a valid string. Either it is a translation from a message catalog or it is the same as the string parameter. So a piece of code to decide whether a translation actually happened must look like this: {
char *trans = catgets (desc, set, msg, input_string);
if (trans == input_string)
{
/* Something went wrong. */
}
}
When an error occurred the global variable errno is set to
While it sometimes can be useful to test for errors programs normally will avoid any test. If the translation is not available it is no big problem if the original, untranslated message is printed. Either the user understands this as well or s/he will look for the reason why the messages are not translated. |
Please note that the currently selected locale does not depend on a call
to the setlocale function. It is not necessary that the locale
data files for this locale exist and calling setlocale succeeds.
The catopen function directly reads the values of the environment
variables.
| char * catgets (nl_catd catalog_desc, int set, int message, const char *string) | Function |
The function catgets has to be used to access the massage catalog
previously opened using the catopen function. The
catalog_desc parameter must be a value previously returned by
catopen.
The next two parameters, set and message, reflect the internal organization of the message catalog files. This will be explained in detail below. For now it is interesting to know that a catalog can consists of several set and the messages in each thread are individually numbered using numbers. Neither the set number nor the message number must be consecutive. They can be arbitrarily chosen. But each message (unless equal to another one) must have its own unique pair of set and message number. Since it is not guaranteed that the message catalog for the language selected by the user exists the last parameter string helps to handle this case gracefully. If no matching string can be found string is returned. This means for the programmer that
|
It is somewhat uncomfortable to write a program using the catgets
functions if no supporting functionality is available. Since each
set/message number tuple must be unique, the programmer must keep lists
of the messages at the same time the code is written. And the work
between several people working on the same project must be coordinated.
We will see some how these problems can be relaxed a bit (see Common Usage).
| int catclose (nl_catd catalog_desc) | Function |
The catclose function can be used to free the resources
associated with a message catalog which previously was opened by a call
to catopen. If the resources can be successfully freed the
function returns 0. Otherwise it return -1 and the
global variable errno is set. Errors can occur if the catalog
descriptor catalog_desc is not valid in which case errno is
set to EBADF.
|
The only reasonable way the translate all the messages of a function and
store the result in a message catalog file which can be read by the
catopen function is to write all the message text to the
translator and let her/him translate them all. I.e., we must have a
file with entries which associate the set/message tuple with a specific
translation. This file format is specified in the X/Open standard and
is as follows:
$
followed by a whitespace character are comment and are also ignored.
$set followed by a whitespace character an additional argument
is required to follow. This argument can either be:
How to use the symbolic names is explained in section Common Usage.
It is an error if a symbol name appears more than once. All following messages are placed in a set with this number.
$delset followed by a whitespace character an additional argument
is required to follow. This argument can either be:
In both cases all messages in the specified set will be removed. They
will not appear in the output. But if this set is later again selected
with a $set command again messages could be added and these
messages will appear in the output.
$quote, the quoting character used for this input file is
changed to the first non-whitespace character following the
$quote. If no non-whitespace character is present before the
line ends quoting is disable.
By default no quoting character is used. In this mode strings are
terminated with the first unescaped line break. If there is a
$quote sequence present newline need not be escaped. Instead a
string is terminated with the first unescaped appearance of the quote
character.
A common usage of this feature would be to set the quote character to
". Then any appearance of the " in the strings must
be escaped using the backslash (i.e., \" must be written).
If the start of the line is a number the message number is obvious. It is an error if the same message number already appeared for this set.
If the leading token was an identifier the message number gets
automatically assigned. The value is the current maximum messages
number for this set plus one. It is an error if the identifier was
already used for a message in this set. It is ok to reuse the
identifier for a message in another thread. How to use the symbolic
identifiers will be explained below (see Common Usage). There is
one limitation with the identifier: it must not be Set. The
reason will be explained below.
Please note that you must use a quoting character if a message contains leading whitespace. Since one cannot guarantee this never happens it is probably a good idea to always use quoting.
The text of the messages can contain escape characters. The usual bunch
of characters known from the ISO C language are recognized
(\n, \t, \v, \b, \r, \f,
\\, and \nnn, where nnn is the octal coding of
a character code).
Important: The handling of identifiers instead of numbers for the set and messages is a GNU extension. Systems strictly following the X/Open specification do not have this feature. An example for a message catalog file is this:
$ This is a leading comment. $quote " $set SetOne 1 Message with ID 1. two " Message with ID \"two\", which gets the value 2 assigned" $set SetTwo $ Since the last set got the number 1 assigned this set has number 2. 4000 "The numbers can be arbitrary, they need not start at one."
This small example shows various aspects:
$ followed by
a whitespace.
". Otherwise the quotes in the
message definition would have to be left away and in this case the
message with the identifier two would loose its leading whitespace.
While this file format is pretty easy it is not the best possible for
use in a running program. The catopen function would have to
parser the file and handle syntactic errors gracefully. This is not so
easy and the whole process is pretty slow. Therefore the catgets
functions expect the data in another more compact and ready-to-use file
format. There is a special program gencat which is explained in
detail in the next section.
Files in this other format are not human readable. To be easy to use by programs it is a binary file. But the format is byte order independent so translation files can be shared by systems of arbitrary architecture (as long as they use the GNU C Library).
Details about the binary file format are not important to know since
these files are always created by the gencat program. The
sources of the GNU C Library also provide the sources for the
gencat program and so the interested reader can look through
these source files to learn about the file format.
The gencat program is specified in the X/Open standard and the
GNU implementation follows this specification and so allows to process
all correctly formed input files. Additionally some extension are
implemented which help to work in a more reasonable way with the
catgets functions.
The gencat program can be invoked in two ways:
`gencat [Option]... [Output-File [Input-File]...]`
This is the interface defined in the X/Open standard. If no Input-File parameter is given input will be read from standard input. Multiple input files will be read as if they are concatenated. If Output-File is also missing, the output will be written to standard output. To provide the interface one is used from other programs a second interface is provided.
`gencat [Option]... -o Output-File [Input-File]...`
The option -o is used to specify the output file and all file
arguments are used as input files.
Beside this one can use - or /dev/stdin for
Input-File to denote the standard input. Corresponding one can
use - and /dev/stdout for Output-File to denote
standard output. Using - as a file name is allowed in X/Open
while using the device names is a GNU extension.
The gencat program works by concatenating all input files and
then merge the resulting collection of message sets with a
possibly existing output file. This is done by removing all messages
with set/message number tuples matching any of the generated messages
from the output file and then adding all the new messages. To
regenerate a catalog file while ignoring the old contents therefore
requires to remove the output file if it exists. If the output is
written to standard output no merging takes place.
The following table shows the options understood by the gencat
program. The X/Open standard does not specify any option for the
program so all of these are GNU extensions.
-V
--version
-h
--help
--new
-H
--header=name
#defines to associate a name with a
number.
Please note that the generated file only contains the symbols from the input files. If the output is merged with the previous content of the output file the possibly existing symbols from the file(s) which generated the old output files are not in the generated header file.
catgets interfaceThe catgets functions can be used in two different ways. By
following slavishly the X/Open specs and not relying on the extension
and by using the GNU extensions. We will take a look at the former
method first to understand the benefits of extensions.
Since the X/Open format of the message catalog files does not allow symbol names we have to work with numbers all the time. When we start writing a program we have to replace all appearances of translatable strings with something like
catgets (catdesc, set, msg, "string")
catgets is retrieved from a call to catopen which is
normally done once at the program start. The "string" is the
string we want to translate. The problems start with the set and
message numbers.
In a bigger program several programmers usually work at the same time on the program and so coordinating the number allocation is crucial. Though no two different strings must be indexed by the same tuple of numbers it is highly desirable to reuse the numbers for equal strings with equal translations (please note that there might be strings which are equal in one language but have different translations due to difference contexts).
The allocation process can be relaxed a bit by different set numbers for
different parts of the program. So the number of developers who have to
coordinate the allocation can be reduced. But still lists must be keep
track of the allocation and errors can easily happen. These errors
cannot be discovered by the compiler or the catgets functions.
Only the user of the program might see wrong messages printed. In the
worst cases the messages are so irritating that they cannot be
recognized as wrong. Think about the translations for "true" and
"false" being exchanged. This could result in a disaster.
The problems mentioned in the last section derive from the fact that:
By constantly using symbolic names and by providing a method which maps the string content to a symbolic name (however this will happen) one can prevent both problems above. The cost of this is that the programmer has to write a complete message catalog file while s/he is writing the program itself.
This is necessary since the symbolic names must be mapped to numbers
before the program sources can be compiled. In the last section it was
described how to generate a header containing the mapping of the names.
E.g., for the example message file given in the last section we could
call the gencat program as follow (assume ex.msg contains
the sources).
gencat -H ex.h -o ex.cat ex.msg
This generates a header file with the following content:
#define SetTwoSet 0x2 /* u.msg:8 */ #define SetOneSet 0x1 /* u.msg:4 */ #define SetOnetwo 0x2 /* u.msg:6 */
As can be seen the various symbols given in the source file are mangled
to generate unique identifiers and these identifiers get numbers
assigned. Reading the source file and knowing about the rules will
allow to predict the content of the header file (it is deterministic)
but this is not necessary. The gencat program can take care for
everything. All the programmer has to do is to put the generated header
file in the dependency list of the source files of her/his project and
to add a rules to regenerate the header of any of the input files
change.
One word about the symbol mangling. Every symbol consists of two parts:
the name of the message set plus the name of the message or the special
string Set. So SetOnetwo means this macro can be used to
access the translation with identifier two in the message set
SetOne.
The other names denote the names of the message sets. The special
string Set is used in the place of the message identifier.
If in the code the second string of the set SetOne is used the C
code should look like this:
catgets (catdesc, SetOneSet, SetOnetwo,
" Message with ID \"two\", which gets the value 2 assigned")
Writing the function this way will allow to change the message number and even the set number without requiring any change in the C source code. (The text of the string is normally not the same; this is only for this example.)
To illustrate the usual way to work with the symbolic version numbers here is a little example. Assume we want to write the very complex and famous greeting program. We start by writing the code as usual:
#include <stdio.h>
int
main (void)
{
printf ("Hello, world!\n");
return 0;
}
Now we want to internationalize the message and therefore replace the message with whatever the user wants.
#include <nl_types.h>
#include <stdio.h>
#include "msgnrs.h"
int
main (void)
{
nl_catd catdesc = catopen ("hello.cat", NL_CAT_LOCALE);
printf (catgets (catdesc, SetMainSet, SetMainHello,
"Hello, world!\n"));
catclose (catdesc);
return 0;
}
We see how the catalog object is opened and the returned descriptor used in the other function calls. It is not really necessary to check for failure of any of the functions since even in these situations the functions will behave reasonable. They simply will be return a translation.
What remains unspecified here are the constants SetMainSet and
SetMainHello. These are the symbolic names describing the
message. To get the actual definitions which match the information in
the catalog file we have to create the message catalog source file and
process it using the gencat program.
$ Messages for the famous greeting program. $quote " $set Main Hello "Hallo, Welt!\n"
Now we can start building the program (assume the message catalog source
file is named hello.msg and the program source file hello.c):
% gencat -H msgnrs.h -o hello.cat hello.msg % cat msgnrs.h #define MainSet 0x1 /* hello.msg:4 */ #define MainHello 0x1 /* hello.msg:5 */ % gcc -o hello hello.c -I. % cp hello.cat /usr/share/locale/de/LC_MESSAGES % echo $LC_ALL de % ./hello Hallo, Welt! %
The call of the gencat program creates the missing header file
msgnrs.h as well as the message catalog binary. The former is
used in the compilation of hello.c while the latter is placed in a
directory in which the catopen function will try to locate it.
Please check the LC_ALL environment variable and the default path
for catopen presented in the description above.
Sun Microsystems tried to standardize a different approach to message
translation in the Uniforum group. There never was a real standard
defined but still the interface was used in Sun's operation systems.
Since this approach fits better in the development process of free
software it is also used throughout the GNU package and the GNU
gettext package provides support for this outside the GNU C
Library.
The code of the libintl from GNU gettext is the same as
the code in the GNU C Library. So the documentation in the GNU
gettext manual is also valid for the functionality here. The
following text will describe the library functions in detail. But the
numerous helper programs are not described in this manual. Instead
people should read the GNU gettext manual
(see Top).
We will only give a short overview.
Though the catgets functions are available by default on more
systems the gettext interface is at least as portable as the
former. The GNU gettext package can be used wherever the
functions are not available.
gettext family of functions.
gettext.
gettext family of functionsThe paradigms underlying the gettext approach to message
translations is different from that of the catgets functions the
basic functionally is equivalent. There are functions of the following
categories:
gettext works.
The gettext functions have a very simple interface. The most
basic function just takes the string which shall be translated as the
argument and it returns the translation. This is fundamentally
different from the catgets approach where an extra key is
necessary and the original string is only used for the error case.
If the string which has to be translated is the only argument this of
course means the string itself is the key. I.e., the translation will
be selected based on the original string. The message catalogs must
therefore contain the original strings plus one translation for any such
string. The task of the gettext function is it to compare the
argument string with the available strings in the catalog and return the
appropriate translation. Of course this process is optimized so that
this process is not more expensive than an access using an atomic key
like in catgets.
The gettext approach has some advantages but also some
disadvantages. Please see the GNU gettext manual for a detailed
discussion of the pros and cons.
All the definitions and declarations for gettext can be found in
the libintl.h header file. On systems where these functions are
not part of the C library they can be found in a separate library named
libintl.a (or accordingly different for shared libraries).
| char * gettext (const char *msgid) | Function |
The gettext function searches the currently selected message
catalogs for a string which is equal to msgid. If there is such a
string available it is returned. Otherwise the argument string
msgid is returned.
Please note that all though the return value is Please note that above we wrote "message catalogs" (plural). This is a specialty of the GNU implementation of these functions and we will say more about this when we talk about the ways message catalogs are selected (see Locating gettext catalog). The printf (gettext ("Operation failed: %m\n"));
Here the errno value is used in the So there is no easy way to detect a missing message catalog beside comparing the argument string with the result. But it is normally the task of the user to react on missing catalogs. The program cannot guess when a message catalog is really necessary since for a user who s peaks the language the program was developed in does not need any translation. |
The remaining two functions to access the message catalog add some
functionality to select a message catalog which is not the default one.
This is important if parts of the program are developed independently.
Every part can have its own message catalog and all of them can be used
at the same time. The C library itself is an example: internally it
uses the gettext functions but since it must not depend on a
currently selected default message catalog it must specify all ambiguous
information.
| char * dgettext (const char *domainname, const char *msgid) | Function |
The dgettext functions acts just like the gettext
function. It only takes an additional first argument domainname
which guides the selection of the message catalogs which are searched
for the translation. If the domainname parameter is the null
pointer the dgettext function is exactly equivalent to
gettext since the default value for the domain name is used.
As for |
| char * dcgettext (const char *domainname, const char *msgid, int category) | Function |
The dcgettext adds another argument to those which
dgettext takes. This argument category specifies the last
piece of information needed to localize the message catalog. I.e., the
domain name and the locale category exactly specify which message
catalog has to be used (relative to a given directory, see below).
The dcgettext (domain, string, LC_MESSAGES) instead of dgettext (domain, string) This also shows which values are expected for the third parameter. One
has to use the available selectors for the categories available in
The As for |
When using the three functions above in a program it is a frequent case that the msgid argument is a constant string. So it is worth to optimize this case. Thinking shortly about this one will realize that as long as no new message catalog is loaded the translation of a message will not change. I.e., the algorithm to determine the translation is deterministic.
Exactly this is what the optimizations implemented in the
libintl.h header will use. Whenever a program is compiler with
the GNU C compiler, optimization is selected and the msgid
argument to gettext, dgettext or dcgettext is a
constant string the actual function call will only be done the first
time the message is used and then always only if any new message catalog
was loaded and so the result of the translation lookup might be
different. See the libintl.h header file for details. For the
user it is only important to know that the result is always the same,
independent of the compiler or compiler options in use.
The functions to retrieve the translations for a given message have a remarkable simple interface. But to provide the user of the program still the opportunity to select exactly the translation s/he wants and also to provide the programmer the possibility to influence the way to locate the search for catalogs files there is a quite complicated underlying mechanism which controls all this. The code is complicated the use is easy.
Basically we have two different tasks to perform which can also be
performed by the catgets functions:
There can be arbitrarily many packages installed and they can follow different guidelines for the placement of their files.
This is the functionality required by the specifications for
gettext and this is also what the catgets functions are
able to do. But there are some problems unresolved:
de, german, or
deutsch and the program should always react the same.
de_DE.ISO-8859-1 which means German, spoken in Germany,
coded using the ISO 8859-1 character set there is the possibility
that a message catalog matching this exactly is not available. But
there could be a catalog matching de and if the character set
used on the machine is always ISO 8859-1 there is no reason why this
later message catalog should not be used. (We call this message
inheritance.)
We can divide the configuration actions in two parts: the one is performed by the programmer, the other by the user. We will start with the functions the programmer can use since the user configuration will be based on this.
As the functions described in the last sections already mention separate
sets of messages can be selected by a domain name. This is a
simple string which should be unique for each program part with uses a
separate domain. It is possible to use in one program arbitrarily many
domains at the same time. E.g., the GNU C Library itself uses a domain
named libc while the program using the C Library could use a
domain named foo. The important point is that at any time
exactly one domain is active. This is controlled with the following
function.
| char * textdomain (const char *domainname) | Function |
The textdomain function sets the default domain, which is used in
all future gettext calls, to domainname. Please note that
dgettext and dcgettext calls are not influenced if the
domainname parameter of these functions is not the null pointer.
Before the first call to The function returns the value which is from now on taken as the default
domain. If the system went out of memory the returned value is
If the domainname parameter is the null pointer no new default domain is set. Instead the currently selected default domain is returned. If the domainname parameter is the empty string the default domain
is reset to its initial value, the domain with the name |
| char * bindtextdomain (const char *domainname, const char *dirname) | Function |
The bindtextdomain function can be used to specify the directly
which contains the message catalogs for domain domainname for the
different languages. To be correct, this is the directory where the
hierarchy of directories is expected. Details are explained below.
For the programmer it is important to note that the translations which
come with the program have be placed in a directory hierarchy starting
at, say, The If the program which wish to use If the dirname parameter is the null pointer the |
gettextThe last sections described what the programmer can do to internationalize the messages of the program. But it is finally up to the user to select the message s/he wants to see. S/He must understand them.
The POSIX locale model uses the environment variables LC_COLLATE,
LC_CTYPE, LC_MESSAGES, LC_MONETARY, NUMERIC,
and LC_TIME to select the locale which is to be used. This way
the user can influence lots of functions. As we mentioned above the
gettext functions also take advantage of this.
To understand how this happens it is necessary to take a look at the various components of the filename which gets computed to locate a message catalog. It is composed as follows:
dir_name/locale/LC_category/domain_name.mo
The default value for dir_name is system specific. It is computed
from the value given as the prefix while configuring the C library.
This value normally is /usr or /. For the former the
complete dir_name is:
/usr/share/locale
We can use /usr/share since the .mo files containing the
message catalogs are system independent, all systems can use the same
files. If the program executed the bindtextdomain function for
the message domain that is currently handled the dir_name
component is the exactly the value which was given to the function as
the second parameter. I.e., bindtextdomain allows to overwrite
the only system dependent and fixed value to make it possible to
address file everywhere in the filesystem.
The category is the name of the locale category which was selected
in the program code. For gettext and dgettext this is
always LC_MESSAGES, for dcgettext this is selected by the
value of the third parameter. As said above it should be avoided to
ever use a category other than LC_MESSAGES.
The locale component is computed based on the category used. Just
like for the setlocale function here comes the user selection
into the play. Some environment variables are examined in a fixed order
and the first environment variable set determines the return value of
the lookup process. In detail, for the category LC_xxx the
following variables in this order are examined:
LANGUAGE
LC_ALL
LC_xxx
LANG
This looks very familiar. With the exception of the LANGUAGE
environment variable this is exactly the lookup order the
setlocale function uses. But why introducing the LANGUAGE
variable?
The reason is that the syntax of the values these variables can have is
different to what is expected by the setlocale function. If we
would set LC_ALL to a value following the extended syntax that
would mean the setlocale function will never be able to use the
value of this variable as well. An additional variable removes this
problem plus we can select the language independently of the locale
setting which sometimes is useful.
While for the LC_xxx variables the value should consist of
exactly one specification of a locale the LANGUAGE variable's
value can consist of a colon separated list of locale names. The
attentive reader will realize that this is the way we manage to
implement one of our additional demands above: we want to be able to
specify an ordered list of language.
Back to the constructed filename we have only one component missing.
The domain_name part is the name which was either registered using
the textdomain function or which was given to dgettext or
dcgettext as the first parameter. Now it becomes obvious that a
good choice for the domain name in the program code is a string which is
closely related to the program/package name. E.g., for the GNU C
Library the domain name is libc.
A limit piece of example code should show how the programmer is supposed to work:
{
textdomain ("test-package");
bindtextdomain ("test-package", "/usr/local/share/locale");
puts (gettext ("Hello, world!");
}
At the program start the default domain is messages. The
textdomain call changes this to test-package. The
bindtextdomain call specifies that the message catalogs for the
domain test-package can be found below the directory
/usr/local/share/locale.
If now the user set in her/his environment the variable LANGUAGE
to de the gettext function will try to use the
translations from the file
/usr/local/share/locale/de/LC_MESSAGES/test-package.mo
From the above descriptions it should be clear which component of this filename is determined by which source.
In the above example we assumed that the LANGUAGE environment
variable to de. This might be an appropriate selection but what
happens if the user wants to use LC_ALL because of the wider
usability and here the required value is de_DE.ISO-8859-1? We
already mentioned above that a situation like this is not infrequent.
E.g., a person might prefer reading a dialect and if this is not
available fall back on the standard language.
The gettext functions know about situations like this and can
handle them gracefully. The functions recognize the format of the value
of the environment variable. It can split the value is different pieces
and by leaving out the only or the other part it can construct new
values. This happens of course in a predictable way. To understand
this one must know the format of the environment variable value. There
are to more or less standardized forms:
language[_territory[.codeset]][@modifier]
language[_territory][+audience][+special][,[sponsor][_revision]]
The functions will automatically recognize which format is used. Less specific locale names will be stripped of in the order of the following list:
revision
sponsor
special
codeset
normalized codeset
territory
audience/modifier
From the last entry one can see that the meaning of the modifier
field in the X/Open format and the audience format have the same
meaning. Beside one can see that the language field for obvious
reasons never will be dropped.
The only new thing is the normalized codeset entry. This is
another goodie which is introduced to help reducing the chaos which
derives from the inability of the people to standardize the names of
character sets. Instead of ISO-8859-1 one can often see 8859-1,
88591, iso8859-1, or iso_8859-1. The normalized
codeset value is generated from the user-provided character set name by
applying the following rules:
"iso".
So all of the above name will be normalized to iso88591. This
allows the program user much more freely choosing the locale name.
Even this extended functionality still does not help to solve the
problem that completely different names can be used to denote the same
locale (e.g., de and german). To be of help in this
situation the locale implementation and also the gettext
functions know about aliases.
The file /usr/share/locale/locale.alias (replace /usr with
whatever prefix you used for configuring the C library) contains a
mapping of alternative names to more regular names. The system manager
is free to add new entries to fill her/his own needs. The selected
locale from the environment is compared with the entries in the first
column of this file ignoring the case. If they match the value of the
second column is used instead for the further handling.
In the description of the format of the environment variables we already mentioned the character set as a factor in the selection of the message catalog. In fact, only catalogs which contain text written using the character set of the system/program can be used (directly; there will come a solution for this some day). This means for the user that s/he will always have to take care for this. If in the collection of the message catalogs there are files for the same language but coded using different character sets the user has to be careful.
gettextThe GNU C Library does not contain the source code for the programs to
handle message catalogs for the gettext functions. As part of
the GNU project the GNU gettext package contains everything the
developer needs. The functionality provided by the tools in this
package by far exceeds the abilities of the gencat program
described above for the catgets functions.
There is a program msgfmt which is the equivalent program to the
gencat program. It generates from the human-readable and
-editable form of the message catalog a binary file which can be used by
the gettext functions. But there are several more programs
available.
The xgettext program can be used to automatically extract the
translatable messages from a source file. I.e., the programmer need not
take care for the translations and the list of messages which have to be
translated. S/He will simply wrap the translatable string in calls to
gettext et.al and the rest will be done by xgettext. This
program has a lot of option which help to customize the output or do
help to understand the input better.
Other programs help to the manage development cycle when new messages appear in the source files or when a new translation of the messages appear. Here it should only be noted that using all the tools in GNU gettext it is possible to completely automate the handling of message catalogs. Beside marking the translatable string in the source code and generating the translations the developers do not have to do anything themselves.
This chapter describes functions for searching and sorting arrays of arbitrary objects. You pass the appropriate comparison function to be applied as an argument, along with the size of the objects in the array and the total number of elements.
bsearch function.
qsort function.
hsearch function.
tsearch function.
In order to use the sorted array library functions, you have to describe how to compare the elements of the array.
To do this, you supply a comparison function to compare two elements of
the array. The library will call this function, passing as arguments
pointers to two array elements to be compared. Your comparison function
should return a value the way strcmp (see String/Array Comparison) does: negative if the first argument is "less" than the
second, zero if they are "equal", and positive if the first argument
is "greater".
Here is an example of a comparison function which works with an array of
numbers of type double:
int
compare_doubles (const void *a, const void *b)
{
const double *da = (const double *) a;
const double *db = (const double *) b;
return (*da > *db) - (*da < *db);
}
The header file stdlib.h defines a name for the data type of
comparison functions. This type is a GNU extension.
int comparison_fn_t (const void *, const void *);
Generally searching for a specific element in an array means that
potentially all elements must be checked. The GNU C library contains
functions to perform linear search. The prototypes for the following
two functions can be found in search.h.
| void * lfind (const void *key, void *base, size_t *nmemb, size_t size, comparison_fn_t compar) | Function |
The lfind function searches in the array with *nmemb
elements of size bytes pointed to by base for an element
which matches the one pointed to by key. The function pointed to
by compar is used decide whether two elements match.
The return value is a pointer to the matching element in the array
starting at base if it is found. If no matching element is
available The mean runtime of this function is |
| void * lsearch (const void *key, void *base, size_t *nmemb, size_t size, comparison_fn_t compar) | Function |
The lsearch function is similar to the lfind function. It
searches the given array for an element and returns it if found. The
difference is that if no matching element is found the lsearch
function adds the object pointed to by key (with a size of
size bytes) at the end of the array and it increments the value of
*nmemb to reflect this addition.
This means for the caller that if it is not sure that the array contains
the element one is searching for the memory allocated for the array
starting at base must have room for at least size more
bytes. If one is sure the element is in the array it is better to use
|
To search a sorted array for an element matching the key, use the
bsearch function. The prototype for this function is in
the header file stdlib.h.
| void * bsearch (const void *key, const void *array, size_t count, size_t size, comparison_fn_t compare) | Function |
The bsearch function searches the sorted array array for an object
that is equivalent to key. The array contains count elements,
each of which is of size size bytes.
The compare function is used to perform the comparison. This function is called with two pointer arguments and should return an integer less than, equal to, or greater than zero corresponding to whether its first argument is considered less than, equal to, or greater than its second argument. The elements of the array must already be sorted in ascending order according to this comparison function. The return value is a pointer to the matching array element, or a null pointer if no match is found. If the array contains more than one element that matches, the one that is returned is unspecified. This function derives its name from the fact that it is implemented using the binary search algorithm. |
To sort an array using an arbitrary comparison function, use the
qsort function. The prototype for this function is in
stdlib.h.
| void qsort (void *array, size_t count, size_t size, comparison_fn_t compare) | Function |
|
The qsort function sorts the array array. The array contains
count elements, each of which is of size size.
The compare function is used to perform the comparison on the array elements. This function is called with two pointer arguments and should return an integer less than, equal to, or greater than zero corresponding to whether its first argument is considered less than, equal to, or greater than its second argument. Warning: If two objects compare as equal, their order after sorting is unpredictable. That is to say, the sorting is not stable. This can make a difference when the comparison considers only part of the elements. Two elements with the same sort key may differ in other respects. If you want the effect of a stable sort, you can get this result by writing the comparison function so that, lacking other reason distinguish between two elements, it compares them by their addresses. Note that doing this may make the sorting algorithm less efficient, so do it only if necessary. Here is a simple example of sorting an array of doubles in numerical order, using the comparison function defined above (see Comparison Functions): {
double *array;
int size;
...
qsort (array, size, sizeof (double), compare_doubles);
}
The |
Here is an example showing the use of qsort and bsearch
with an array of structures. The objects in the array are sorted
by comparing their name fields with the strcmp function.
Then, we can look up individual objects based on their names.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* Define an array of critters to sort. */
struct critter
{
const char *name;
const char *species;
};
struct critter muppets[] =
{
{"Kermit", "frog"},
{"Piggy", "pig"},
{"Gonzo", "whatever"},
{"Fozzie", "bear"},
{"Sam", "eagle"},
{"Robin", "frog"},
{"Animal", "animal"},
{"Camilla", "chicken"},
{"Sweetums", "monster"},
{"Dr. Strangepork", "pig"},
{"Link Hogthrob", "pig"},
{"Zoot", "human"},
{"Dr. Bunsen Honeydew", "human"},
{"Beaker", "human"},
{"Swedish Chef", "human"}
};
int count = sizeof (muppets) / sizeof (struct critter);
/* This is the comparison function used for sorting and searching. */
int
critter_cmp (const struct critter *c1, const struct critter *c2)
{
return strcmp (c1->name, c2->name);
}
/* Print information about a critter. */
void
print_critter (const struct critter *c)
{
printf ("%s, the %s\n", c->name, c->species);
}
/* Do the lookup into the sorted array. */
void
find_critter (const char *name)
{
struct critter target, *result;
target.name = name;
result = bsearch (&target, muppets, count, sizeof (struct critter),
critter_cmp);
if (result)
print_critter (result);
else
printf ("Couldn't find %s.\n", name);
}
/* Main program. */
int
main (void)
{
int i;
for (i = 0; i < count; i++)
print_critter (&muppets[i]);
printf ("\n");
qsort (muppets, count, sizeof (struct critter), critter_cmp);
for (i = 0; i < count; i++)
print_critter (&muppets[i]);
printf ("\n");
find_critter ("Kermit");
find_critter ("Gonzo");
find_critter ("Janice");
return 0;
}
The output from this program looks like:
Kermit, the frog Piggy, the pig Gonzo, the whatever Fozzie, the bear Sam, the eagle Robin, the frog Animal, the animal Camilla, the chicken Sweetums, the monster Dr. Strangepork, the pig Link Hogthrob, the pig Zoot, the human Dr. Bunsen Honeydew, the human Beaker, the human Swedish Chef, the human Animal, the animal Beaker, the human Camilla, the chicken Dr. Bunsen Honeydew, the human Dr. Strangepork, the pig Fozzie, the bear Gonzo, the whatever Kermit, the frog Link Hogthrob, the pig Piggy, the pig Robin, the frog Sam, the eagle Swedish Chef, the human Sweetums, the monster Zoot, the human Kermit, the frog Gonzo, the whatever Couldn't find Janice.
hsearch function.The functions mentioned so far in this chapter are searching in a sorted or unsorted array. There are other methods to organize information which later should be searched. The costs of insert, delete and search differ. One possible implementation is using hashing tables.
| int hcreate (size_t nel) | Function |
The hcreate function creates a hashing table which can contain at
least nel elements. There is no possibility to grow this table so
it is necessary to choose the value for nel wisely. The used
methods to implement this function might make it necessary to make the
number of elements in the hashing table larger than the expected maximal
number of elements. Hashing tables usually work inefficient if they are
filled 80% or more. The constant access time guaranteed by hashing can
only be achieved if few collisions exist. See Knuth's "The Art of
Computer Programming, Part 3: Searching and Sorting" for more
information.
The weakest aspect of this function is that there can be at most one hashing table used through the whole program. The table is allocated in local memory out of control of the programmer. As an extension the GNU C library provides an additional set of functions with an reentrant interface which provide a similar interface but which allow to keep arbitrarily many hashing tables. It is possible to use more than one hashing table in the program run if
the former table is first destroyed by a call to The function returns a non-zero value if successful. If it return zero something went wrong. This could either mean there is already a hashing table in use or the program runs out of memory. |
| void hdestroy (void) | Function |
The hdestroy function can be used to free all the resources
allocated in a previous call of hcreate. After a call to this
function it is again possible to call hcreate and allocate a new
table with possibly different size.
It is important to remember that the elements contained in the hashing
table at the time |
Entries of the hashing table and keys for the search are defined using this type:
| struct ENTRY | Data type |
Both elements of this structure are pointers to zero-terminated strings.
This is a limiting restriction of the functionality of the
hsearch functions. They can only be used for data sets which use
the NUL character always and solely to terminate the records. It is not
possible to handle general binary data.
|
| ENTRY * hsearch (ENTRY item, ACTION action) | Function |
To search in a hashing table created using hcreate the
hsearch function must be used. This function can perform simple
search for an element (if action has the FIND) or it can
alternatively insert the key element into the hashing table, possibly
replacing a previous value (if action is ENTER).
The key is denoted by a pointer to an object of type The return value depends on the action parameter value. If it is
|
As mentioned before the hashing table used by the functions described so
far is global and there can be at any time at most one hashing table in
the program. A solution is to use the following functions which are a
GNU extension. All have in common that they operate on a hashing table
which is described by the content of an object of the type struct
hsearch_data. This type should be treated as opaque, none of its
members should be changed directly.
| int hcreate_r (size_t nel, struct hsearch_data *htab) | Function |
The hcreate_r function initializes the object pointed to by
htab to contain a hashing table with at least nel elements.
So this function is equivalent to the hcreate function except
that the initialized data structure is controlled by the user.
This allows to have more than once hashing table at one time. The
memory necessary for the The return value is non-zero if the operation were successful. if the return value is zero something went wrong which probably means the programs runs out of memory. |
| void hdestroy_r (struct hsearch_data *htab) | Function |
The hdestroy_r function frees all resources allocated by the
hcreate_r function for this very same object htab. As for
hdestroy it is the programs responsibility to free the strings
for the elements of the table.
|
| int hsearch_r (ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab) | Function |
The hsearch_r function is equivalent to hsearch. The
meaning of the first two arguments is identical. But instead of
operating on a single global hashing table the function works on the
table described by the object pointed to by htab (which is
initialized by a call to hcreate_r).
Another difference to
|
tsearch function.Another common form to organize data for efficient search is to use
trees. The tsearch function family provides a nice interface to
functions to organize possibly large amounts of data by providing a mean
access time proportional to the logarithm of the number of elements.
The GNU C library implementation even guarantees that this bound is
never exceeded even for input data which cause problems for simple
binary tree implementations.
The functions described in the chapter are all described in the System V and X/Open specifications and are therefore quite portable.
In contrast to the hsearch functions the tsearch functions
can be used with arbitrary data and not only zero-terminated strings.
The tsearch functions have the advantage that no function to
initialize data structures is necessary. A simple pointer of type
void * initialized to NULL is a valid tree and can be
extended or searched.
| void * tsearch (const void *key, void **rootp, comparison_fn_t compar) | Function |
The tsearch function searches in the tree pointed to by
*rootp for an element matching key. The function
pointed to by compar is used to determine whether two elements
match. See Comparison Functions, for a specification of the functions
which can be used for the compar parameter.
If the tree does not contain a matching entry the key value will
be added to the tree. The tree is represented by a pointer to a pointer since it is sometimes
necessary to change the root node of the tree. So it must not be
assumed that the variable pointed to by rootp has the same value
after the call. This also shows that it is not safe to call the
The return value is a pointer to the matching element in the tree. If a
new element was created the pointer points to the new data (which is in
fact key). If an entry had to be created and the program ran out
of space |
| void * tfind (const void *key, void *const *rootp, comparison_fn_t compar) | Function |
The tfind function is similar to the tsearch function. It
locates an element matching the one pointed to by key and returns
a pointer to this element. But if no matching element is available no
new element is entered (note that the rootp parameter points to a
constant pointer). Instead the function returns NULL.
|
Another advantage of the tsearch function in contrast to the
hsearch functions is that there is an easy way to remove
elements.
| void * tdelete (const void *key, void **rootp, comparison_fn_t compar) | Function |
To remove a specific element matching key from the tree
tdelete can be used. It locates the matching element using the
same method as tfind. The corresponding element is then removed
and the data if this tree node is returned by the function. If there is
no matching entry in the tree nothing can be deleted and the function
returns NULL.
|
| void tdestroy (void *vroot, __free_fn_t freefct) | Function |
If the complete search tree has to be removed one can use
tdestroy. It frees all resources allocated by the tsearch
function to generate the tree pointed to by vroot.
For the data in each tree node the function freefct is called. The pointer to the data is passed as the argument to the function. If no such work is necessary freefct must point to a function doing nothing. It is called in any case. This function is a GNU extension and not covered by the System V or X/Open specifications. |
In addition to the function to create and destroy the tree data structure there is another function which allows to apply a function on all elements of the tree. The function must have this type:
void __action_fn_t (const void *nodep, VISIT value, int level);
The nodep is the data value of the current node (once given as the
key argument to tsearch). level is a numeric value
which corresponds to the depth of the current node in the tree. The
root node has the depth 0 and its children have a depth of
1 and so on. The VISIT type is an enumeration type.
| VISIT | Data Type |
The VISIT value indicates the status of the current node in the
tree and how the function is called. The status of a node is either
`leaf' or `internal node'. For each leaf node the function is called
exactly once, for each internal node it is called three times: before
the first child is processed, after the first child is processed and
after both children are processed. This makes it possible to handle all
three methods of tree traversal (or even a combination of them).
|
| void twalk (const void *root, __action_fn_t action) | Function |
For each node in the tree with a node pointed to by root the
twalk function calls the function provided by the parameter
action. For leaf nodes the function is called exactly once with
value set to leaf. For internal nodes the function is
called three times, setting the value parameter or action to
the appropriate value. The level argument for the action
function is computed while descending the tree with increasing the value
by one for the descend to a child, starting with the value 0 for
the root node.
Since the functions used for the action parameter to |
The GNU C Library provides pattern matching facilities for two kinds of patterns: regular expressions and file-name wildcards. The library also provides a facility for expanding variable and command references and parsing text into words in the way the shell does.
This section describes how to match a wildcard pattern against a
particular string. The result is a yes or no answer: does the
string fit the pattern or not. The symbols described here are all
declared in fnmatch.h.
| int fnmatch (const char *pattern, const char *string, int flags) | Function |
This function tests whether the string string matches the pattern
pattern. It returns 0 if they do match; otherwise, it
returns the nonzero value FNM_NOMATCH. The arguments
pattern and string are both strings.
The argument flags is a combination of flag bits that alter the details of matching. See below for a list of the defined flags. In the GNU C Library, |
These are the available flags for the flags argument:
FNM_FILE_NAME
/ character specially, for matching file names. If
this flag is set, wildcard constructs in pattern cannot match
/ in string. Thus, the only way to match / is with
an explicit / in pattern.
FNM_PATHNAME
FNM_FILE_NAME; it comes from POSIX.2. We
don't recommend this name because we don't use the term "pathname" for
file names.
FNM_PERIOD
. character specially if it appears at the beginning of
string. If this flag is set, wildcard constructs in pattern
cannot match . as the first character of string.
If you set both FNM_PERIOD and FNM_FILE_NAME, then the
special treatment applies to . following / as well as to
. at the beginning of string. (The shell uses the
FNM_PERIOD and FNM_FILE_NAME flags together for matching
file names.)
FNM_NOESCAPE
\ character specially in patterns. Normally,
\ quotes the following character, turning off its special meaning
(if any) so that it matches only itself. When quoting is enabled, the
pattern \? matches only the string ?, because the question
mark in the pattern acts like an ordinary character.
If you use FNM_NOESCAPE, then \ is an ordinary character.
FNM_LEADING_DIR
/ in
string; that is to say, test whether string starts with a
directory name that pattern matches.
If this flag is set, either foo* or foobar as a pattern
would match the string foobar/frobozz.
FNM_CASEFOLD
The archetypal use of wildcards is for matching against the files in a directory, and making a list of all the matches. This is called globbing.
You could do this using fnmatch, by reading the directory entries
one by one and testing each one with fnmatch. But that would be
slow (and complex, since you would have to handle subdirectories by
hand).
The library provides a function glob to make this particular use
of wildcards convenient. glob and the other symbols in this
section are declared in glob.h.
glob.
glob.
glob.
globThe result of globbing is a vector of file names (strings). To return
this vector, glob uses a special data type, glob_t, which
is a structure. You pass glob the address of the structure, and
it fills in the structure's fields to tell you about the results.
| glob_t | Data Type |
This data type holds a pointer to a word vector. More precisely, it
records both the address of the word vector and its size. The GNU
implementation contains some more fields which are non-standard
extensions.
|
| int glob (const char *pattern, int flags, int (*errfunc) (const char *filename, int error-code), glob_t *vector-ptr) | Function |
The function glob does globbing using the pattern pattern
in the current directory. It puts the result in a newly allocated
vector, and stores the size and address of this vector into
*vector-ptr. The argument flags is a combination of
bit flags; see Flags for Globbing, for details of the flags.
The result of globbing is a sequence of file names. The function
To return this vector, Normally, If
In the event of an error, |
This section describes the flags that you can specify in the
flags argument to glob. Choose the flags you want,
and combine them with the C bitwise OR operator |.
GLOB_APPEND
glob. This way you can effectively expand
several words as if they were concatenated with spaces between them.
In order for appending to work, you must not modify the contents of the
word vector structure between calls to glob. And, if you set
GLOB_DOOFFS in the first call to glob, you must also
set it when you append to the results.
Note that the pointer stored in gl_pathv may no longer be valid
after you call glob the second time, because glob might
have relocated the vector. So always fetch gl_pathv from the
glob_t structure after each glob call; never save
the pointer across calls.
GLOB_DOOFFS
gl_offs field says how many slots to leave.
The blank slots contain null pointers.
GLOB_ERR
glob tries its best to keep
on going despite any errors, reading whatever directories it can.
You can exercise even more control than this by specifying an
error-handler function errfunc when you call glob. If
errfunc is not a null pointer, then glob doesn't give up
right away when it can't read a directory; instead, it calls
errfunc with two arguments, like this:
(*errfunc) (filename, error-code)
The argument filename is the name of the directory that
glob couldn't open or couldn't read, and error-code is the
errno value that was reported to glob.
If the error handler function returns nonzero, then glob gives up
right away. Otherwise, it continues.
GLOB_MARK
/ to the
directory's name when returning it.
GLOB_NOCHECK
glob returns that there were no
matches.)
GLOB_NOSORT
GLOB_NOESCAPE
\ character specially in patterns. Normally,
\ quotes the following character, turning off its special meaning
(if any) so that it matches only itself. When quoting is enabled, the
pattern \? matches only the string ?, because the question
mark in the pattern acts like an ordinary character.
If you use GLOB_NOESCAPE, then \ is an ordinary character.
glob does its work by calling the function fnmatch
repeatedly. It handles the flag GLOB_NOESCAPE by turning on the
FNM_NOESCAPE flag in calls to fnmatch.
Beside the flags described in the last section, the GNU implementation of
glob allows a few more flags which are also defined in the
glob.h file. Some of the extensions implement functionality
which is available in modern shell implementations.
GLOB_PERIOD
. character (period) is treated special. It cannot be
matched by wildcards. See Wildcard Matching, FNM_PERIOD.
GLOB_MAGCHAR
GLOB_MAGCHAR value is not to be given to glob in the
flags parameter. Instead, glob sets this bit in the
gl_flags element of the glob_t structure provided as the
result if the pattern used for matching contains any wildcard character.
GLOB_ALTDIRFUNC
glob implementation uses the user-supplied
functions specified in the structure pointed to by pglob
parameter. For more information about the functions refer to the
sections about directory handling see Accessing Directories, and
Reading Attributes.
GLOB_BRACE
The string between the matching braces is separated into single
expressions by splitting at , (comma) characters. The commas
themself are discarded. Please note what we said above about recursive
brace expressions. The commas used to separate the subexpressions must
be at the same level. Commas in brace subexpressions are not matched.
They are used during expansion of the brace expression of the deeper
level. The example below shows this
glob ("{foo/{,bar,biz},baz}", GLOB_BRACE, NULL, &result)
is equivalent to the sequence
glob ("foo/", GLOB_BRACE, NULL, &result)
glob ("foo/bar", GLOB_BRACE|GLOB_APPEND, NULL, &result)
glob ("foo/biz", GLOB_BRACE|GLOB_APPEND, NULL, &result)
glob ("baz", GLOB_BRACE|GLOB_APPEND, NULL, &result)
if we leave aside error handling.
GLOB_NOMAGIC
GLOB_TILDE
~ (tilde) is handled special
if it appears at the beginning of the pattern. Instead of being taken
verbatim it is used to represent the home directory of a known user.
If ~ is the only character in pattern or it is followed by a
/ (slash), the home directory of the process owner is
substituted. Using getlogin and getpwnam the information
is read from the system databases. As an example take user bart
with his home directory at /home/bart. For him a call like
glob ("~/bin/*", GLOB_TILDE, NULL, &result)
would return the contents of the directory /home/bart/bin.
Instead of referring to the own home directory it is also possible to
name the home directory of other users. To do so one has to append the
user name after the tilde character. So the contents of user
homer's bin directory can be retrieved by
glob ("~homer/bin/*", GLOB_TILDE, NULL, &result)
If the user name is not valid or the home directory cannot be determined
for some reason the pattern is left untouched and itself used as the
result. I.e., if in the last example home is not available the
tilde expansion yields to "~homer/bin/*" and glob is not
looking for a directory named ~homer.
This functionality is equivalent to what is available in C-shells if the
nonomatch flag is set.
GLOB_TILDE_CHECK
glob behaves like as if GLOB_TILDE is
given. The only difference is that if the user name is not available or
the home directory cannot be determined for other reasons this leads to
an error. glob will return GLOB_NOMATCH instead of using
the pattern itself as the name.
This functionality is equivalent to what is available in C-shells if
nonomatch flag is not set.
GLOB_ONLYDIR
This functionality is only available with the GNU glob
implementation. It is mainly used internally to increase the
performance but might be useful for a user as well and therefore is
documented here.
Calling glob will in most cases allocate resources which are used
to represent the result of the function call. If the same object of
type glob_t is used in multiple call to glob the resources
are freed or reused so that no leaks appear. But this does not include
the time when all glob calls are done.
| void globfree (glob_t *pglob) | Function |
The globfree function frees all resources allocated by previous
calls to glob associated with the object pointed to by
pglob. This function should be called whenever the currently used
glob_t typed object isn't used anymore.
|
The GNU C library supports two interfaces for matching regular expressions. One is the standard POSIX.2 interface, and the other is what the GNU system has had for many years.
Both interfaces are declared in the header file regex.h.
If you define _POSIX_C_SOURCE, then only the POSIX.2
functions, structures, and constants are declared.
regcomp to prepare to match.
regcomp.
regexec to match the compiled
pattern that you get from regcomp.
Before you can actually match a regular expression, you must compile it. This is not true compilation--it produces a special data structure, not machine instructions. But it is like ordinary compilation in that its purpose is to enable you to "execute" the pattern fast. (See Matching POSIX Regexps, for how to use the compiled regular expression for matching.)
There is a special data type for compiled regular expressions:
| regex_t | Data Type |
This type of object holds a compiled regular expression.
It is actually a structure. It has just one field that your programs
should look at:
There are several other fields, but we don't describe them here, because only the functions in the library should use them. |
After you create a regex_t object, you can compile a regular
expression into it by calling regcomp.
| int regcomp (regex_t *compiled, const char *pattern, int cflags) | Function |
The function regcomp "compiles" a regular expression into a
data structure that you can use with regexec to match against a
string. The compiled regular expression format is designed for
efficient matching. regcomp stores it into *compiled.
It's up to you to allocate an object of type The argument cflags lets you specify various options that control the syntax and semantics of regular expressions. See Flags for POSIX Regexps. If you use the flag If you don't use
|
Here are the possible nonzero values that regcomp can return:
REG_BADBR
\{...\} construct in the regular
expression. A valid \{...\} construct must contain either
a single number, or two numbers in increasing order separated by a
comma.
REG_BADPAT
REG_BADRPT
? or * appeared in a bad
position (with no preceding subexpression to act on).
REG_ECOLLATE
REG_ECTYPE
REG_EESCAPE
\.
REG_ESUBREG
\digit construct.
REG_EBRACK
REG_EPAREN
\( and \).
REG_EBRACE
\{ and \}.
REG_ERANGE
REG_ESPACE
regcomp ran out of memory.
These are the bit flags that you can use in the cflags operand when
compiling a regular expression with regcomp.
REG_EXTENDED
REG_ICASE
REG_NOSUB
REG_NEWLINE
$ can match before the newline and ^ can
match after. Also, don't permit . to match a newline, and don't
permit [^...] to match a newline.
Otherwise, newline acts like any other ordinary character.
Once you have compiled a regular expression, as described in POSIX Regexp Compilation, you can match it against strings using
regexec. A match anywhere inside the string counts as success,
unless the regular expression contains anchor characters (^ or
$).
| int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags) | Function |
This function tries to match the compiled regular expression
*compiled against string.
The argument eflags is a word of bit flags that enable various options. If you want to get information about what part of string actually
matched the regular expression or its subexpressions, use the arguments
matchptr and nmatch. Otherwise, pass |
You must match the regular expression with the same set of current locales that were in effect when you compiled the regular expression.
The function regexec accepts the following flags in the
eflags argument:
REG_NOTBOL
REG_NOTEOL
Here are the possible nonzero values that regexec can return:
REG_NOMATCH
REG_ESPACE
regexec ran out of memory.
When regexec matches parenthetical subexpressions of
pattern, it records which parts of string they match. It
returns that information by storing the offsets into an array whose
elements are structures of type regmatch_t. The first element of
the array (index 0) records the part of the string that matched
the entire regular expression. Each other element of the array records
the beginning and end of the part that matched a single parenthetical
subexpression.
| regmatch_t | Data Type |
This is the data type of the matcharray array that you pass to
regexec. It contains two structure fields, as follows:
|
| regoff_t | Data Type |
regoff_t is an alias for another signed integer type.
The fields of regmatch_t have type regoff_t.
|
The regmatch_t elements correspond to subexpressions
positionally; the first element (index 1) records where the first
subexpression matched, the second element records the second
subexpression, and so on. The order of the subexpressions is the order
in which they begin.
When you call regexec, you specify how long the matchptr
array is, with the nmatch argument. This tells regexec how
many elements to store. If the actual regular expression has more than
nmatch subexpressions, then you won't get offset information about
the rest of them. But this doesn't alter whether the pattern matches a
particular string or not.
If you don't want regexec to return any information about where
the subexpressions matched, you can either supply 0 for
nmatch, or use the flag REG_NOSUB when you compile the
pattern with regcomp.
Sometimes a subexpression matches a substring of no characters. This
happens when f\(o*\) matches the string fum. (It really
matches just the f.) In this case, both of the offsets identify
the point in the string where the null substring was found. In this
example, the offsets are both 1.
Sometimes the entire regular expression can match without using some of
its subexpressions at all--for example, when ba\(na\)* matches the
string ba, the parenthetical subexpression is not used. When
this happens, regexec stores -1 in both fields of the
element for that subexpression.
Sometimes matching the entire regular expression can match a particular
subexpression more than once--for example, when ba\(na\)*
matches the string bananana, the parenthetical subexpression
matches three times. When this happens, regexec usually stores
the offsets of the last part of the string that matched the
subexpression. In the case of bananana, these offsets are
6 and 8.
But the last match is not always the one that is chosen. It's more
accurate to say that the last opportunity to match is the one
that takes precedence. What this means is that when one subexpression
appears within another, then the results reported for the inner
subexpression reflect whatever happened on the last match of the outer
subexpression. For an example, consider \(ba\(na\)*s \)* matching
the string bananas bas . The last time the inner expression
actually matches is near the end of the first word. But it is
considered again in the second word, and fails to match there.
regexec reports nonuse of the "na" subexpression.
Another place where this rule applies is when the regular expression
\(ba\(na\)*s \|nefer\(ti\)* \)*
matches bananas nefertiti. The "na" subexpression does match
in the first word, but it doesn't match in the second word because the
other alternative is used there. Once again, the second repetition of
the outer subexpression overrides the first, and within that second
repetition, the "na" subexpression is not used. So regexec
reports nonuse of the "na" subexpression.
When you are finished using a compiled regular expression, you can
free the storage it uses by calling regfree.
| void regfree (regex_t *compiled) | Function |
Calling regfree frees all the storage that *compiled
points to. This includes various internal fields of the regex_t
structure that aren't documented in this manual.
|
You should always free the space in a regex_t structure with
regfree before using the structure to compile another regular
expression.
When regcomp or regexec reports an error, you can use
the function regerror to turn it into an error message string.
| size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length) | Function |
This function produces an error message string for the error code
errcode, and stores the string in length bytes of memory
starting at buffer. For the compiled argument, supply the
same compiled regular expression structure that regcomp or
regexec was working with when it got the error. Alternatively,
you can supply NULL for compiled; you will still get a
meaningful error message, but it might not be as detailed.
If the error message can't fit in length bytes (including a
terminating null character), then The return value of Here is a function which uses char *get_regerror (int errcode, regex_t *compiled)
{
size_t length = regerror (errcode, compiled, NULL, 0);
char *buffer = xmalloc (length);
(void) regerror (errcode, compiled, buffer, length);
return buffer;
}
|
Word expansion means the process of splitting a string into words and substituting for variables, commands, and wildcards just as the shell does.
For example, when you write ls -l foo.c, this string is split
into three separate words--ls, -l and foo.c.
This is the most basic function of word expansion.
When you write ls *.c, this can become many words, because
the word *.c can be replaced with any number of file names.
This is called wildcard expansion, and it is also a part of
word expansion.
When you use echo $PATH to print your path, you are taking
advantage of variable substitution, which is also part of word
expansion.
Ordinary programs can perform word expansion just like the shell by
calling the library function wordexp.
wordexp.
wordexp.
When word expansion is applied to a sequence of words, it performs the following transformations in the order shown here:
~foo with the name of
the home directory of foo.
$foo.
`cat foo` and
the equivalent $(cat foo) are replaced with the output from
the inner command.
$(($x-1)) are
replaced with the result of the arithmetic computation.
*.c
with a list of .c file names. Wildcard expansion applies to an
entire word at a time, and replaces that word with 0 or more file names
that are themselves words.
For the details of these transformations, and how to write the constructs that use them, see The BASH Manual (to appear).
wordexpAll the functions, constants and data types for word expansion are
declared in the header file wordexp.h.
Word expansion produces a vector of words (strings). To return this
vector, wordexp uses a special data type, wordexp_t, which
is a structure. You pass wordexp the address of the structure,
and it fills in the structure's fields to tell you about the results.
| wordexp_t | Data Type |
This data type holds a pointer to a word vector. More precisely, it
records both the address of the word vector and its size.
|
| int wordexp (const char *words, wordexp_t *word-vector-ptr, int flags) | Function |
Perform word expansion on the string words, putting the result in
a newly allocated vector, and store the size and address of this vector
into *word-vector-ptr. The argument flags is a
combination of bit flags; see Flags for Wordexp, for details of
the flags.
You shouldn't use any of the characters The results of word expansion are a sequence of words. The function
To return this vector, If
|
| void wordfree (wordexp_t *word-vector-ptr) | Function |
Free the storage used for the word-strings and vector that
*word-vector-ptr points to. This does not free the
structure *word-vector-ptr itself--only the other
data it points to.
|
This section describes the flags that you can specify in the
flags argument to wordexp. Choose the flags you want,
and combine them with the C operator |.
WRDE_APPEND
wordexp. This way you can effectively expand
several words as if they were concatenated with spaces between them.
In order for appending to work, you must not modify the contents of the
word vector structure between calls to wordexp. And, if you set
WRDE_DOOFFS in the first call to wordexp, you must also
set it when you append to the results.
WRDE_DOOFFS
we_offs field says how many slots to leave.
The blank slots contain null pointers.
WRDE_NOCMD
WRDE_REUSE
wordexp.
Instead of allocating a new vector of words, this call to wordexp
will use the vector that already exists (making it larger if necessary).
Note that the vector may move, so it is not safe to save an old pointer
and use it again after calling wordexp. You must fetch
we_pathv anew after each call.
WRDE_SHOWERR
wordexp gives these
commands a standard error stream that discards all output.
WRDE_UNDEF
wordexp ExampleHere is an example of using wordexp to expand several strings
and use the results to run a shell command. It also shows the use of
WRDE_APPEND to concatenate the expansions and of wordfree
to free the space allocated by wordexp.
int
expand_and_execute (const char *program, const char *options)
{
wordexp_t result;
pid_t pid
int status, i;
/* Expand the string for the program to run. */
switch (wordexp (program, &result, 0))
{
case 0: /* Successful. */
break;
case WRDE_NOSPACE:
/* If the error was WRDE_NOSPACE,
then perhaps part of the result was allocated. */
wordfree (&result);
default: /* Some other error. */
return -1;
}
/* Expand the strings specified for the arguments. */
for (i = 0; args[i]; i++)
{
if (wordexp (options, &result, WRDE_APPEND))
{
wordfree (&result);
return -1;
}
}
pid = fork ();
if (pid == 0)
{
/* This is the child process. Execute the command. */
execv (result.we_wordv[0], result.we_wordv);
exit (EXIT_FAILURE);
}
else if (pid < 0)
/* The fork failed. Report failure. */
status = -1;
else
/* This is the parent process. Wait for the child to complete. */
if (waitpid (pid, &status, 0) != pid)
status = -1;
wordfree (&result);
return status;
}
It's a standard part of shell syntax that you can use ~ at the
beginning of a file name to stand for your own home directory. You
can use ~user to stand for user's home directory.
Tilde expansion is the process of converting these abbreviations to the directory names that they stand for.
Tilde expansion applies to the ~ plus all following characters up
to whitespace or a slash. It takes place only at the beginning of a
word, and only if none of the characters to be transformed is quoted in
any way.
Plain ~ uses the value of the environment variable HOME
as the proper home directory name. ~ followed by a user name
uses getpwname to look up that user in the user database, and
uses whatever directory is recorded there. Thus, ~ followed
by your own name can give different results from plain ~, if
the value of HOME is not really your home directory.
Part of ordinary shell syntax is the use of $variable to
substitute the value of a shell variable into a command. This is called
variable substitution, and it is one part of doing word expansion.
There are two basic ways you can write a variable reference for substitution:
${variable}
${foo}s
expands into tractors.
$variable
$. The next punctuation character ends the variable
name. Thus, $foo-bar refers to the variable foo and expands
into tractor-bar.
When you use braces, you can also use various constructs to modify the value that is substituted, or test it in various ways.
${variable:-default}
${variable:=default}
${variable:?message}
Otherwise, print message as an error message on the standard error
stream, and consider word expansion a failure.
${variable:+replacement}
${#variable}
${#foo} stands for
7, because tractor is seven characters.
These variants of variable substitution let you remove part of the variable's value before substituting it. The prefix and suffix are not mere strings; they are wildcard patterns, just like the patterns that you use to match multiple file names. But in this context, they match against parts of the variable value rather than against file names.
${variable%%suffix}
If there is more than one alternative for how to match against suffix, this construct uses the longest possible match.
Thus, ${foo%%r*} substitutes t, because the largest
match for r* at the end of tractor is ractor.
${variable%suffix}
If there is more than one alternative for how to match against suffix, this construct uses the shortest possible alternative.
Thus, ${foo%%r*} substitutes tracto, because the shortest
match for r* at the end of tractor is just r.
${variable##prefix}
If there is more than one alternative for how to match against prefix, this construct uses the longest possible match.
Thus, ${foo%%r*} substitutes t, because the largest
match for r* at the end of tractor is ractor.
${variable#prefix}
If there is more than one alternative for how to match against prefix, this construct uses the shortest possible alternative.
Thus, ${foo%%r*} substitutes tracto, because the shortest
match for r* at the end of tractor is just r.
Most programs need to do either input (reading data) or output (writing data), or most frequently both, in order to do anything useful. The GNU C library provides such a large selection of input and output functions that the hardest part is often deciding which function is most appropriate!
This chapter introduces concepts and terminology relating to input and output. Other chapters relating to the GNU I/O facilities are:
Before you can read or write the contents of a file, you must establish a connection or communications channel to the file. This process is called opening the file. You can open a file for reading, writing, or both.
The connection to an open file is represented either as a stream or as a file descriptor. You pass this as an argument to the functions that do the actual read or write operations, to tell them which file to operate on. Certain functions expect streams, and others are designed to operate on file descriptors.
When you have finished reading to or writing from the file, you can terminate the connection by closing the file. Once you have closed a stream or file descriptor, you cannot do any more input or output operations on it.
When you want to do input or output to a file, you have a choice of two
basic mechanisms for representing the connection between your program
and the file: file descriptors and streams. File descriptors are
represented as objects of type int, while streams are represented
as FILE * objects.
File descriptors provide a primitive, low-level interface to input and output operations. Both file descriptors and streams can represent a connection to a device (such as a terminal), or a pipe or socket for communicating with another process, as well as a normal file. But, if you want to do control operations that are specific to a particular kind of device, you must use a file descriptor; there are no facilities to use streams in this way. You must also use file descriptors if your program needs to do input or output in special modes, such as nonblocking (or polled) input (see File Status Flags).
Streams provide a higher-level interface, layered on top of the primitive file descriptor facilities. The stream interface treats all kinds of files pretty much alike--the sole exception being the three styles of buffering that you can choose (see Stream Buffering).
The main advantage of using the stream interface is that the set of
functions for performing actual input and output operations (as opposed
to control operations) on streams is much richer and more powerful than
the corresponding facilities for file descriptors. The file descriptor
interface provides only simple functions for transferring blocks of
characters, but the stream interface also provides powerful formatted
input and output functions (printf and scanf) as well as
functions for character- and line-oriented input and output.
Since streams are implemented in terms of file descriptors, you can extract the file descriptor from a stream and perform low-level operations directly on the file descriptor. You can also initially open a connection as a file descriptor and then make a stream associated with that file descriptor.
In general, you should stick with using streams rather than file descriptors, unless there is some specific operation you want to do that can only be done on a file descriptor. If you are a beginning programmer and aren't sure what functions to use, we suggest that you concentrate on the formatted input functions (see Formatted Input) and formatted output functions (see Formatted Output).
If you are concerned about portability of your programs to systems other than GNU, you should also be aware that file descriptors are not as portable as streams. You can expect any system running ISO C to support streams, but non-GNU systems may not support file descriptors at all, or may only implement a subset of the GNU functions that operate on file descriptors. Most of the file descriptor functions in the GNU library are included in the POSIX.1 standard, however.
One of the attributes of an open file is its file position that keeps track of where in the file the next character is to be read or written. In the GNU system, and all POSIX.1 systems, the file position is simply an integer representing the number of bytes from the beginning of the file.
The file position is normally set to the beginning of the file when it is opened, and each time a character is read or written, the file position is incremented. In other words, access to the file is normally sequential.
Ordinary files permit read or write operations at any position within
the file. Some other kinds of files may also permit this. Files which
do permit this are sometimes referred to as random-access files.
You can change the file position using the fseek function on a
stream (see File Positioning) or the lseek function on a file
descriptor (see I/O Primitives). If you try to change the file
position on a file that doesn't support random access, you get the
ESPIPE error.
Streams and descriptors that are opened for append access are treated specially for output: output to such files is always appended sequentially to the end of the file, regardless of the file position. However, the file position is still used to control where in the file reading is done.
If you think about it, you'll realize that several programs can read a given file at the same time. In order for each program to be able to read the file at its own pace, each program must have its own file pointer, which is not affected by anything the other programs do.
In fact, each opening of a file creates a separate file position. Thus, if you open a file twice even in the same program, you get two streams or descriptors with independent file positions.
By contrast, if you open a descriptor and then duplicate it to get another descriptor, these two descriptors share the same file position: changing the file position of one descriptor will affect the other.
In order to open a connection to a file, or to perform other operations such as deleting a file, you need some way to refer to the file. Nearly all files have names that are strings--even files which are actually devices such as tape drives or terminals. These strings are called file names. You specify the file name to say which file you want to open or operate on.
This section describes the conventions for file names and how the operating system works with them.
In order to understand the syntax of file names, you need to understand how the file system is organized into a hierarchy of directories.
A directory is a file that contains information to associate other files with names; these associations are called links or directory entries. Sometimes, people speak of "files in a directory", but in reality, a directory only contains pointers to files, not the files themselves.
The name of a file contained in a directory entry is called a file
name component. In general, a file name consists of a sequence of one
or more such components, separated by the slash character (/). A
file name which is just one component names a file with respect to its
directory. A file name with multiple components names a directory, and
then a file in that directory, and so on.
Some other documents, such as the POSIX standard, use the term
pathname for what we call a file name, and either filename
or pathname component for what this manual calls a file name
component. We don't use this terminology because a "path" is
something completely different (a list of directories to search), and we
think that "pathname" used for something else will confuse users. We
always use "file name" and "file name component" (or sometimes just
"component", where the context is obvious) in GNU documentation. Some
macros use the POSIX terminology in their names, such as
PATH_MAX. These macros are defined by the POSIX standard, so we
cannot change their names.
You can find more detailed information about operations on directories in File System Interface.
A file name consists of file name components separated by slash
(/) characters. On the systems that the GNU C library supports,
multiple successive / characters are equivalent to a single
/ character.
The process of determining what file a file name refers to is called file name resolution. This is performed by examining the components that make up a file name in left-to-right order, and locating each successive component in the directory named by the previous component. Of course, each of the files that are referenced as directories must actually exist, be directories instead of regular files, and have the appropriate permissions to be accessible by the process; otherwise the file name resolution fails.
If a file name begins with a /, the first component in the file
name is located in the root directory of the process (usually all
processes on the system have the same root directory). Such a file name
is called an absolute file name.
Otherwise, the first component in the file name is located in the current working directory (see Working Directory). This kind of file name is called a relative file name.
The file name components . ("dot") and .. ("dot-dot")
have special meanings. Every directory has entries for these file name
components. The file name component . refers to the directory
itself, while the file name component .. refers to its
parent directory (the directory that contains the link for the
directory in question). As a special case, .. in the root
directory refers to the root directory itself, since it has no parent;
thus /.. is the same as /.
Here are some examples of file names:
/a
a, in the root directory.
/a/b
b, in the directory named a in the root directory.
a
a, in the current working directory.
/a/./b
/a/b.
./a
a, in the current working directory.
../a
a, in the parent directory of the current working
directory.
A file name that names a directory may optionally end in a /.
You can specify a file name of / to refer to the root directory,
but the empty string is not a meaningful file name. If you want to
refer to the current working directory, use a file name of . or
./.
Unlike some other operating systems, the GNU system doesn't have any
built-in support for file types (or extensions) or file versions as part
of its file name syntax. Many programs and utilities use conventions
for file names--for example, files containing C source code usually
have names suffixed with .c--but there is nothing in the file
system itself that enforces this kind of convention.
Functions that accept file name arguments usually detect these
errno error conditions relating to the file name syntax or
trouble finding the named file. These errors are referred to throughout
this manual as the usual file name errors.
EACCES
ENAMETOOLONG
PATH_MAX, or when an individual file name component
has a length greater than NAME_MAX. See Limits for Files.
In the GNU system, there is no imposed limit on overall file name
length, but some file systems may place limits on the length of a
component.
ENOENT
ENOTDIR
ELOOP
The rules for the syntax of file names discussed in File Names, are the rules normally used by the GNU system and by other POSIX systems. However, other operating systems may use other conventions.
There are two reasons why it can be important for you to be aware of file name portability issues:
The ISO C standard says very little about file name syntax, only that file names are strings. In addition to varying restrictions on the length of file names and what characters can validly appear in a file name, different operating systems use different conventions and syntax for concepts such as structured directories and file types or extensions. Some concepts such as file versions might be supported in some operating systems and not by others.
The POSIX.1 standard allows implementations to put additional restrictions on file name syntax, concerning what characters are permitted in file names and on the length of file name and file name component strings. However, in the GNU system, you do not need to worry about these restrictions; any character except the null character is permitted in a file name string, and there are no limits on the length of file name strings.
This chapter describes the functions for creating streams and performing input and output operations on them. As discussed in I/O Overview, a stream is a fairly abstract, high-level concept representing a communications channel to a file, device, or process.
printf and related functions.
printf and friends.
scanf and related functions.
For historical reasons, the type of the C data structure that represents
a stream is called FILE rather than "stream". Since most of
the library functions deal with objects of type FILE *, sometimes
the term file pointer is also used to mean "stream". This leads
to unfortunate confusion over terminology in many books on C. This
manual, however, is careful to use the terms "file" and "stream"
only in the technical sense.
The FILE type is declared in the header file stdio.h.
| FILE | Data Type |
This is the data type used to represent stream objects. A FILE
object holds all of the internal state information about the connection
to the associated file, including such things as the file position
indicator and buffering information. Each stream also has error and
end-of-file status indicators that can be tested with the ferror
and feof functions; see EOF and Errors.
|
FILE objects are allocated and managed internally by the
input/output library functions. Don't try to create your own objects of
type FILE; let the library do it. Your programs should
deal only with pointers to these objects (that is, FILE * values)
rather than the objects themselves.
When the main function of your program is invoked, it already has
three predefined streams open and available for use. These represent
the "standard" input and output channels that have been established
for the process.
These streams are declared in the header file stdio.h.
| FILE * stdin | Variable |
| The standard input stream, which is the normal source of input for the program. |
| FILE * stdout | Variable |
| The standard output stream, which is used for normal output from the program. |
| FILE * stderr | Variable |
| The standard error stream, which is used for error messages and diagnostics issued by the program. |
In the GNU system, you can specify what files or processes correspond to these streams using the pipe and redirection facilities provided by the shell. (The primitives shells use to implement these facilities are described in File System Interface.) Most other operating systems provide similar mechanisms, but the details of how to use them can vary.
In the GNU C library, stdin, stdout, and stderr are
normal variables which you can set just like any others. For example, to redirect
the standard output to a file, you could do:
fclose (stdout);
stdout = fopen ("standard-output-file", "w");
Note however, that in other systems stdin, stdout, and
stderr are macros that you cannot assign to in the normal way.
But you can use freopen to get the effect of closing one and
reopening it. See Opening Streams.
Opening a file with the fopen function creates a new stream and
establishes a connection between the stream and a file. This may
involve creating a new file.
Everything described in this section is declared in the header file
stdio.h.
| FILE * fopen (const char *filename, const char *opentype) | Function |
The fopen function opens a stream for I/O to the file
filename, and returns a pointer to the stream.
The opentype argument is a string that controls how the file is opened and specifies attributes of the resulting stream. It must begin with one of the following sequences of characters:
As you can see, Additional characters may appear after these to specify flags for the
call. Always put the mode ( The GNU C library defines one additional character for use in
opentype: the character The character Any other characters in opentype are simply ignored. They may be meaningful in other systems. If the open fails, When the sources are compiling with |
You can have multiple streams (or file descriptors) pointing to the same file open at the same time. If you do only input, this works straightforwardly, but you must be careful if any output streams are included. See Stream/Descriptor Precautions. This is equally true whether the streams are in one program (not usual) or in several programs (which can easily happen). It may be advantageous to use the file locking facilities to avoid simultaneous access. See File Locks.
| FILE * fopen64 (const char *filename, const char *opentype) | Function |
This function is similar to fopen but the stream it returns a
pointer for is opened using open64. Therefore this stream can be
used even on files larger then 2^31 bytes on 32 bits machines.
Please note that the return type is still If the sources are compiled with |
| int FOPEN_MAX | Macro |
The value of this macro is an integer constant expression that
represents the minimum number of streams that the implementation
guarantees can be open simultaneously. You might be able to open more
than this many streams, but that is not guaranteed. The value of this
constant is at least eight, which includes the three standard streams
stdin, stdout, and stderr. In POSIX.1 systems this
value is determined by the OPEN_MAX parameter; see General Limits. In BSD and GNU, it is controlled by the RLIMIT_NOFILE
resource limit; see Limits on Resources.
|
| FILE * freopen (const char *filename, const char *opentype, FILE *stream) | Function |
This function is like a combination of fclose and fopen.
It first closes the stream referred to by stream, ignoring any
errors that are detected in the process. (Because errors are ignored,
you should not use freopen on an output stream if you have
actually done any output using the stream.) Then the file named by
filename is opened with mode opentype as for fopen,
and associated with the same stream object stream.
If the operation fails, a null pointer is returned; otherwise,
When the sources are compiling with |
| FILE * freopen64 (const char *filename, const char *opentype, FILE *stream) | Function |
This function is similar to freopen. The only difference is that
on 32 bits machine the stream returned is able to read beyond the
2^31 bytes limits imposed by the normal interface. It should be
noted that the stream pointed to by stream need not be opened
using fopen64 or freopen64 since its mode is not important
for this function.
If the sources are compiled with |
When a stream is closed with fclose, the connection between the
stream and the file is cancelled. After you have closed a stream, you
cannot perform any additional operations on it.
| int fclose (FILE *stream) | Function |
This function causes stream to be closed and the connection to
the corresponding file to be broken. Any buffered output is written
and any buffered input is discarded. The fclose function returns
a value of 0 if the file was closed successfully, and EOF
if an error was detected.
It is important to check for errors when you call The function |
To close all streams currently available the GNU C Library provides another function.
| int fcloseall (void) | Function |
This function causes all open streams of the process to be closed and
the connection to corresponding files to be broken. All buffered data
is written and any buffered input is discarded. The fcloseall
function returns a value of 0 if all the files were closed
successfully, and EOF if an error was detected.
This function should be used only in special situation, e.g., when an error occurred and the program must be aborted. Normally each single stream should be closed separately so that problems with one stream can be identified. It is also problematic since the standard streams (see Standard Streams) will also be closed. The function |
If the main function to your program returns, or if you call the
exit function (see Normal Termination), all open streams are
automatically closed properly. If your program terminates in any other
manner, such as by calling the abort function (see Aborting a Program) or from a fatal signal (see Signal Handling), open streams
might not be closed properly. Buffered output might not be flushed and
files may be incomplete. For more information on buffering of streams,
see Stream Buffering.
This section describes functions for performing character- and line-oriented output.
These functions are declared in the header file stdio.h.
| int fputc (int c, FILE *stream) | Function |
The fputc function converts the character c to type
unsigned char, and writes it to the stream stream.
EOF is returned if a write error occurs; otherwise the
character c is returned.
|
| int putc (int c, FILE *stream) | Function |
This is just like fputc, except that most systems implement it as
a macro, making it faster. One consequence is that it may evaluate the
stream argument more than once, which is an exception to the
general rule for macros. putc is usually the best function to
use for writing a single character.
|
| int putchar (int c) | Function |
The putchar function is equivalent to putc with
stdout as the value of the stream argument.
|
| int fputs (const char *s, FILE *stream) | Function |
The function fputs writes the string s to the stream
stream. The terminating null character is not written.
This function does not add a newline character, either.
It outputs only the characters in the string.
This function returns For example: fputs ("Are ", stdout);
fputs ("you ", stdout);
fputs ("hungry?\n", stdout);
outputs the text |
| int puts (const char *s) | Function |
The puts function writes the string s to the stream
stdout followed by a newline. The terminating null character of
the string is not written. (Note that fputs does not
write a newline as this function does.)
puts ("This is a message.");
|
| int putw (int w, FILE *stream) | Function |
This function writes the word w (that is, an int) to
stream. It is provided for compatibility with SVID, but we
recommend you use fwrite instead (see Block Input/Output).
|
This section describes functions for performing character-oriented input.
These functions are declared in the header file stdio.h.
These functions return an int value that is either a character of
input, or the special value EOF (usually -1). It is important to
store the result of these functions in a variable of type int
instead of char, even when you plan to use it only as a
character. Storing EOF in a char variable truncates its
value to the size of a character, so that it is no longer
distinguishable from the valid character (char) -1. So always
use an int for the result of getc and friends, and check
for EOF after the call; once you've verified that the result is
not EOF, you can be sure that it will fit in a char
variable without loss of information.
| int fgetc (FILE *stream) | Function |
This function reads the next character as an unsigned char from
the stream stream and returns its value, converted to an
int. If an end-of-file condition or read error occurs,
EOF is returned instead.
|
| int getc (FILE *stream) | Function |
This is just like fgetc, except that it is permissible (and
typical) for it to be implemented as a macro that evaluates the
stream argument more than once. getc is often highly
optimized, so it is usually the best function to use to read a single
character.
|
| int getchar (void) | Function |
The getchar function is equivalent to getc with stdin
as the value of the stream argument.
|
Here is an example of a function that does input using fgetc. It
would work just as well using getc instead, or using
getchar () instead of fgetc (stdin).
int
y_or_n_p (const char *question)
{
fputs (question, stdout);
while (1)
{
int c, answer;
/* Write a space to separate answer from question. */
fputc (' ', stdout);
/* Read the first character of the line.
This should be the answer character, but might not be. */
c = tolower (fgetc (stdin));
answer = c;
/* Discard rest of input line. */
while (c != '\n' && c != EOF)
c = fgetc (stdin);
/* Obey the answer if it was valid. */
if (answer == 'y')
return 1;
if (answer == 'n')
return 0;
/* Answer was invalid: ask for valid answer. */
fputs ("Please answer y or n:", stdout);
}
}
| int getw (FILE *stream) | Function |
This function reads a word (that is, an int) from stream.
It's provided for compatibility with SVID. We recommend you use
fread instead (see Block Input/Output). Unlike getc,
any int value could be a valid result. getw returns
EOF when it encounters end-of-file or an error, but there is no
way to distinguish this from an input word with value -1.
|
Since many programs interpret input on the basis of lines, it's convenient to have functions to read a line of text from a stream.
Standard C has functions to do this, but they aren't very safe: null
characters and even (for gets) long lines can confuse them. So
the GNU library provides the nonstandard getline function that
makes it easy to read lines reliably.
Another GNU extension, getdelim, generalizes getline. It
reads a delimited record, defined as everything through the next
occurrence of a specified delimiter character.
All these functions are declared in stdio.h.
| ssize_t getline (char **lineptr, size_t *n, FILE *stream) | Function |
This function reads an entire line from stream, storing the text
(including the newline and a terminating null character) in a buffer
and storing the buffer address in *lineptr.
Before calling If you set In either case, when When This function is a GNU extension, but it is the recommended way to read lines from a stream. The alternative standard functions are unreliable. If an error occurs or end of file is reached, |
| ssize_t getdelim (char **lineptr, size_t *n, int delimiter, FILE *stream) | Function |
This function is like getline except that the character which
tells it to stop reading is not necessarily newline. The argument
delimiter specifies the delimiter character; getdelim keeps
reading until it sees that character (or end of file).
The text is stored in lineptr, including the delimiter character
and a terminating null. Like
ssize_t
getline (char **lineptr, size_t *n, FILE *stream)
{
return getdelim (lineptr, n, '\n', stream);
}
|
| char * fgets (char *s, int count, FILE *stream) | Function |
The fgets function reads characters from the stream stream
up to and including a newline character and stores them in the string
s, adding a null character to mark the end of the string. You
must supply count characters worth of space in s, but the
number of characters read is at most count - 1. The extra
character space is used to hold the null character at the end of the
string.
If the system is already at end of file when you call Warning: If the input data has a null character, you can't tell.
So don't use |
| char * gets (char *s) | Deprecated function |
The function gets reads characters from the stream stdin
up to the next newline character, and stores them in the string s.
The newline character is discarded (note that this differs from the
behavior of fgets, which copies the newline character into the
string). If gets encounters a read error or end-of-file, it
returns a null pointer; otherwise it returns s.
Warning: The |
In parser programs it is often useful to examine the next character in the input stream without removing it from the stream. This is called "peeking ahead" at the input because your program gets a glimpse of the input it will read next.
Using stream I/O, you can peek ahead at input by first reading it and
then unreading it (also called pushing it back on the stream).
Unreading a character makes it available to be input again from the stream,
by the next call to fgetc or other input function on that stream.
ungetc to do unreading.
Here is a pictorial explanation of unreading. Suppose you have a
stream reading a file that contains just six characters, the letters
foobar. Suppose you have read three characters so far. The
situation looks like this:
f o o b a r
^
so the next input character will be b.
If instead of reading b you unread the letter o, you get a
situation like this:
f o o b a r
|
o--
^
so that the next input characters will be o and b.
If you unread 9 instead of o, you get this situation:
f o o b a r
|
9--
^
so that the next input characters will be 9 and b.
ungetc To Do UnreadingThe function to unread a character is called ungetc, because it
reverses the action of getc.
| int ungetc (int c, FILE *stream) | Function |
The ungetc function pushes back the character c onto the
input stream stream. So the next input from stream will
read c before anything else.
If c is The character that you push back doesn't have to be the same as the last
character that was actually read from the stream. In fact, it isn't
necessary to actually read any characters from the stream before
unreading them with The GNU C library only supports one character of pushback--in other
words, it does not work to call Pushing back characters doesn't alter the file; only the internal
buffering for the stream is affected. If a file positioning function
(such as Unreading a character on a stream that is at end of file clears the end-of-file indicator for the stream, because it makes the character of input available. After you read that character, trying to read again will encounter end of file. |
Here is an example showing the use of getc and ungetc to
skip over whitespace characters. When this function reaches a
non-whitespace character, it unreads that character to be seen again on
the next read operation on the stream.
#include <stdio.h>
#include <ctype.h>
void
skip_whitespace (FILE *stream)
{
int c;
do
/* No need to check for EOF because it is not
isspace, and ungetc ignores EOF. */
c = getc (stream);
while (isspace (c));
ungetc (c, stream);
}
This section describes how to do input and output operations on blocks of data. You can use these functions to read and write binary data, as well as to read and write text in fixed-size blocks instead of by characters or lines.
Binary files are typically used to read and write blocks of data in the same format as is used to represent the data in a running program. In other words, arbitrary blocks of memory--not just character or string objects--can be written to a binary file, and meaningfully read in again by the same program.
Storing data in binary form is often considerably more efficient than using the formatted I/O functions. Also, for floating-point numbers, the binary form avoids possible loss of precision in the conversion process. On the other hand, binary files can't be examined or modified easily using many standard file utilities (such as text editors), and are not portable between different implementations of the language, or different kinds of computers.
These functions are declared in stdio.h.
| size_t fread (void *data, size_t size, size_t count, FILE *stream) | Function |
|
This function reads up to count objects of size size into
the array data, from the stream stream. It returns the
number of objects actually read, which might be less than count if
a read error occurs or the end of the file is reached. This function
returns a value of zero (and doesn't read anything) if either size
or count is zero.
If |
| size_t fwrite (const void *data, size_t size, size_t count, FILE *stream) | Function |
| This function writes up to count objects of size size from the array data, to the stream stream. The return value is normally count, if the call succeeds. Any other value indicates some sort of error, such as running out of space. |
The functions described in this section (printf and related
functions) provide a convenient way to perform formatted output. You
call printf with a format string or template string
that specifies how to format the values of the remaining arguments.
Unless your program is a filter that specifically performs line- or
character-oriented processing, using printf or one of the other
related functions described in this section is usually the easiest and
most concise way to perform output. These functions are especially
useful for printing error messages, tables of data, and the like.
vprintf and friends.
parse_printf_format.
The printf function can be used to print any number of arguments.
The template string argument you supply in a call provides
information not only about the number of additional arguments, but also
about their types and what style should be used for printing them.
Ordinary characters in the template string are simply written to the
output stream as-is, while conversion specifications introduced by
a % character in the template cause subsequent arguments to be
formatted and written to the output stream. For example,
int pct = 37;
char filename[] = "foo.txt";
printf ("Processing of `%s' is %d%% finished.\nPlease be patient.\n",
filename, pct);
produces output like
Processing of `foo.txt' is 37% finished. Please be patient.
This example shows the use of the %d conversion to specify that
an int argument should be printed in decimal notation, the
%s conversion to specify printing of a string argument, and
the %% conversion to print a literal % character.
There are also conversions for printing an integer argument as an
unsigned value in octal, decimal, or hexadecimal radix (%o,
%u, or %x, respectively); or as a character value
(%c).
Floating-point numbers can be printed in normal, fixed-point notation
using the %f conversion or in exponential notation using the
%e conversion. The %g conversion uses either %e
or %f format, depending on what is more appropriate for the
magnitude of the particular number.
You can control formatting more precisely by writing modifiers
between the % and the character that indicates which conversion
to apply. These slightly alter the ordinary behavior of the conversion.
For example, most conversion specifications permit you to specify a
minimum field width and a flag indicating whether you want the result
left- or right-justified within the field.
The specific flags and modifiers that are permitted and their interpretation vary depending on the particular conversion. They're all described in more detail in the following sections. Don't worry if this all seems excessively complicated at first; you can almost always get reasonable free-format output without using any of the modifiers at all. The modifiers are mostly used to make the output look "prettier" in tables.
This section provides details about the precise syntax of conversion
specifications that can appear in a printf template
string.
Characters in the template string that are not part of a conversion specification are printed as-is to the output stream. Multibyte character sequences (see Character Set Handling) are permitted in a template string.
The conversion specifications in a printf template string have
the general form:
% [ param-no $] flags width [ . precision ] type conversion
For example, in the conversion specifier %-10.8ld, the -
is a flag, 10 specifies the field width, the precision is
8, the letter l is a type modifier, and d specifies
the conversion style. (This particular type specifier says to
print a long int argument in decimal notation, with a minimum of
8 digits left-justified in a field at least 10 characters wide.)
In more detail, output conversion specifications consist of an
initial % character followed in sequence by:
printf function a assigned to the
formats in the order of appearance in the format string. But in some
situations (such as message translation) this is not desirable and this
extension allows to specify and explicit parameter to be used.
The param-no part of the format must be an integer in the range of 1 to the maximum number of arguments present to the function call. Some implementations limit this number to a certainly upper bound. The exact limit can be retrieved by the following constant.
| NL_ARGMAX | Macro |
The value of ARGMAX is the maximum value allowed for the
specification of an positional parameter in a printf call. The
actual value in effect at runtime can be retrieved by using
sysconf using the _SC_NL_ARGMAX parameter see Sysconf Definition.
Some system have a quite low limit such as 9 for System V systems. The GNU C library has no real limit. |
If any of the formats has a specification for the parameter position all of them in the format string shall have one. Otherwise the behaviour is undefined.
You can also specify a field width of *. This means that the
next argument in the argument list (before the actual value to be
printed) is used as the field width. The value must be an int.
If the value is negative, this means to set the - flag (see
below) and to use the absolute value as the field width.
.) followed optionally by a decimal integer
(which defaults to zero if omitted).
You can also specify a precision of *. This means that the next
argument in the argument list (before the actual value to be printed) is
used as the precision. The value must be an int, and is ignored
if it is negative. If you specify * for both the field width and
precision, the field width argument precedes the precision argument.
Other C library versions may not recognize this syntax.
int,
but you can specify h, l, or L for other integer
types.)
The exact options that are permitted and how they are interpreted vary between the different conversion specifiers. See the descriptions of the individual conversions for information about the particular options that they use.
With the -Wformat option, the GNU C compiler checks calls to
printf and related functions. It examines the format string and
verifies that the correct number and types of arguments are supplied.
There is also a GNU C syntax to tell the compiler that a function you
write uses a printf-style format string.
See Function Attributes, for more information.
Here is a table summarizing what all the different conversions do:
%d, %i
%d and %i are synonymous for
output, but are different when used with scanf for input
(see Table of Input Conversions).
%o
%u
%x, %X
%x uses
lower-case letters and %X uses upper-case. See Integer Conversions, for details.
%f
%e, %E
%e uses
lower-case letters and %E uses upper-case. See Floating-Point Conversions, for details.
%g, %G
%g uses
lower-case letters and %G uses upper-case. See Floating-Point Conversions, for details.
%a, %A
%a uses
lower-case letters and %A uses upper-case. See Floating-Point Conversions, for details.
%c
%s
%p
%n
%m
errno.
(This is a GNU extension.)
See Other Output Conversions.
%%
% character. See Other Output Conversions.
If the syntax of a conversion specification is invalid, unpredictable things will happen, so don't do this. If there aren't enough function arguments provided to supply values for all the conversion specifications in the template string, or if the arguments are not of the correct types, the results are unpredictable. If you supply more arguments than conversion specifications, the extra argument values are simply ignored; this is sometimes useful.
This section describes the options for the %d, %i,
%o, %u, %x, and %X conversion
specifications. These conversions print integers in various formats.
The %d and %i conversion specifications both print an
int argument as a signed decimal number; while %o,
%u, and %x print the argument as an unsigned octal,
decimal, or hexadecimal number (respectively). The %X conversion
specification is just like %x except that it uses the characters
ABCDEF as digits instead of abcdef.
The following flags are meaningful:
-
+
%d and %i conversions, print a
plus sign if the value is positive.
%d and %i conversions, if the result
doesn't start with a plus or minus sign, prefix it with a space
character instead. Since the + flag ensures that the result
includes a sign, this flag is ignored if you supply both of them.
#
%o conversion, this forces the leading digit to be
0, as if by increasing the precision. For %x or
%X, this prefixes a leading 0x or 0X (respectively)
to the result. This doesn't do anything useful for the %d,
%i, or %u conversions. Using this flag produces output
which can be parsed by the strtoul function (see Parsing of Integers) and scanf with the %i conversion
(see Numeric Input Conversions).
'
LC_NUMERIC category; see General Numeric. This flag is a
GNU extension.
0
-
flag is also specified, or if a precision is specified.
If a precision is supplied, it specifies the minimum number of digits to appear; leading zeros are produced if necessary. If you don't specify a precision, the number is printed with as many digits as it needs. If you convert a value of zero with an explicit precision of zero, then no characters at all are produced.
Without a type modifier, the corresponding argument is treated as an
int (for the signed conversions %i and %d) or
unsigned int (for the unsigned conversions %o, %u,
%x, and %X). Recall that since printf and friends
are variadic, any char and short arguments are
automatically converted to int by the default argument
promotions. For arguments of other integer types, you can use these
modifiers:
hh
signed char or unsigned
char, as appropriate. A char argument is converted to an
int or unsigned int by the default argument promotions
anyway, but the h modifier says to convert it back to a
char again.
This modifier was introduced in ISO C 9x.
h
short int or unsigned
short int, as appropriate. A short argument is converted to an
int or unsigned int by the default argument promotions
anyway, but the h modifier says to convert it back to a
short again.
j
intmax_t or uintmax_t, as
appropriate.
This modifier was introduced in ISO C 9x.
l
long int or unsigned long
int, as appropriate. Two l characters is like the L
modifier, below.
L
ll
q
long long int. (This type is
an extension supported by the GNU C compiler. On systems that don't
support extra-long integers, this is the same as long int.)
The q modifier is another name for the same thing, which comes
from 4.4 BSD; a long long int is sometimes called a "quad"
int.
t
ptrdiff_t.
This modifier was introduced in ISO C 9x.
z
Z
size_t.
z was introduced in ISO C 9x. Z is a GNU extension
predating this addition and should not be used anymore in new code.
Here is an example. Using the template string:
"|%5d|%-5d|%+5d|%+-5d|% 5d|%05d|%5.0d|%5.2d|%d|\n"
to print numbers using the different options for the %d
conversion gives results like:
| 0|0 | +0|+0 | 0|00000| | 00|0| | 1|1 | +1|+1 | 1|00001| 1| 01|1| | -1|-1 | -1|-1 | -1|-0001| -1| -01|-1| |100000|100000|+100000| 100000|100000|100000|100000|100000|
In particular, notice what happens in the last case where the number is too large to fit in the minimum field width specified.
Here are some more examples showing how unsigned integers print under various format options, using the template string:
"|%5u|%5o|%5x|%5X|%#5o|%#5x|%#5X|%#10.8x|\n"
| 0| 0| 0| 0| 0| 0x0| 0X0|0x00000000| | 1| 1| 1| 1| 01| 0x1| 0X1|0x00000001| |100000|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0|
This section discusses the conversion specifications for floating-point
numbers: the %f, %e, %E, %g, and %G
conversions.
The %f conversion prints its argument in fixed-point notation,
producing output of the form
[-]ddd.ddd,
where the number of digits following the decimal point is controlled
by the precision you specify.
The %e conversion prints its argument in exponential notation,
producing output of the form
[-]d.ddde[+|-]dd.
Again, the number of digits following the decimal point is controlled by
the precision. The exponent always contains at least two digits. The
%E conversion is similar but the exponent is marked with the letter
E instead of e.
The %g and %G conversions print the argument in the style
of %e or %E (respectively) if the exponent would be less
than -4 or greater than or equal to the precision; otherwise they use the
%f style. Trailing zeros are removed from the fractional portion
of the result and a decimal-point character appears only if it is
followed by a digit.
The %a and %A conversions are meant for representing
floating-point number exactly in textual form so that they can be
exchanged as texts between different programs and/or machines. The
numbers are represented is the form
[-]0xh.hhhp[+|-]dd.
At the left of the decimal-point character exactly one digit is print.
This character is only 0 if the number is denormalized.
Otherwise the value is unspecified; it is implementation dependent how many
bits are used. The number of hexadecimal digits on the right side of
the decimal-point character is equal to the precision. If the precision
is zero it is determined to be large enough to provide an exact
representation of the number (or it is large enough to distinguish two
adjacent values if the FLT_RADIX is not a power of 2,
see Floating Point Parameters). For the %a conversion
lower-case characters are used to represent the hexadecimal number and
the prefix and exponent sign are printed as 0x and p
respectively. Otherwise upper-case characters are used and 0X
and P are used for the representation of prefix and exponent
string. The exponent to the base of two is printed as a decimal number
using at least one digit but at most as many digits as necessary to
represent the value exactly.
If the value to be printed represents infinity or a NaN, the output is
[-]inf or nan respectively if the conversion
specifier is %a, %e, %f, or %g and it is
[-]INF or NAN respectively if the conversion is
%A, %E, or %G.
The following flags can be used to modify the behavior:
-
+
+ flag ensures that the result includes
a sign, this flag is ignored if you supply both of them.
#
%g and %G conversions,
this also forces trailing zeros after the decimal point to be left
in place where they would otherwise be removed.
'
LC_NUMERIC category;
see General Numeric. This flag is a GNU extension.
0
- flag is also
specified.
The precision specifies how many digits follow the decimal-point
character for the %f, %e, and %E conversions. For
these conversions, the default precision is 6. If the precision
is explicitly 0, this suppresses the decimal point character
entirely. For the %g and %G conversions, the precision
specifies how many significant digits to print. Significant digits are
the first digit before the decimal point, and all the digits after it.
If the precision is 0 or not specified for %g or %G,
it is treated like a value of 1. If the value being printed
cannot be expressed accurately in the specified number of digits, the
value is rounded to the nearest number that fits.
Without a type modifier, the floating-point conversions use an argument
of type double. (By the default argument promotions, any
float arguments are automatically converted to double.)
The following type modifier is supported:
L
L specifies that the argument is a long
double.
Here are some examples showing how numbers print using the various floating-point conversions. All of the numbers were printed using this template string:
"|%13.4a|%13.4f|%13.4e|%13.4g|\n"
Here is the output:
| 0x0.0000p+0| 0.0000| 0.0000e+00| 0| | 0x1.0000p-1| 0.5000| 5.0000e-01| 0.5| | 0x1.0000p+0| 1.0000| 1.0000e+00| 1| | -0x1.0000p+0| -1.0000| -1.0000e+00| -1| | 0x1.9000p+6| 100.0000| 1.0000e+02| 100| | 0x1.f400p+9| 1000.0000| 1.0000e+03| 1000| | 0x1.3880p+13| 10000.0000| 1.0000e+04| 1e+04| | 0x1.81c8p+13| 12345.0000| 1.2345e+04| 1.234e+04| | 0x1.86a0p+16| 100000.0000| 1.0000e+05| 1e+05| | 0x1.e240p+16| 123456.0000| 1.2346e+05| 1.235e+05|
Notice how the %g conversion drops trailing zeros.
This section describes miscellaneous conversions for printf.
The %c conversion prints a single character. The int
argument is first converted to an unsigned char. The -
flag can be used to specify left-justification in the field, but no
other flags are defined, and no precision or type modifier can be given.
For example:
printf ("%c%c%c%c%c", 'h', 'e', 'l', 'l', 'o');
prints hello.
The %s conversion prints a string. The corresponding argument
must be of type char * (or const char *). A precision can
be specified to indicate the maximum number of characters to write;
otherwise characters in the string up to but not including the
terminating null character are written to the output stream. The
- flag can be used to specify left-justification in the field,
but no other flags or type modifiers are defined for this conversion.
For example:
printf ("%3s%-6s", "no", "where");
prints nowhere .
If you accidentally pass a null pointer as the argument for a %s
conversion, the GNU library prints it as (null). We think this
is more useful than crashing. But it's not good practice to pass a null
argument intentionally.
The %m conversion prints the string corresponding to the error
code in errno. See Error Messages. Thus:
fprintf (stderr, "can't open `%s': %m\n", filename);
is equivalent to:
fprintf (stderr, "can't open `%s': %s\n", filename, strerror (errno));
The %m conversion is a GNU C library extension.
The %p conversion prints a pointer value. The corresponding
argument must be of type void *. In practice, you can use any
type of pointer.
In the GNU system, non-null pointers are printed as unsigned integers,
as if a %#x conversion were used. Null pointers print as
(nil). (Pointers might print differently in other systems.)
For example:
printf ("%p", "testing");
prints 0x followed by a hexadecimal number--the address of the
string constant "testing". It does not print the word
testing.
You can supply the - flag with the %p conversion to
specify left-justification, but no other flags, precision, or type
modifiers are defined.
The %n conversion is unlike any of the other output conversions.
It uses an argument which must be a pointer to an int, but
instead of printing anything it stores the number of characters printed
so far by this call at that location. The h and l type
modifiers are permitted to specify that the argument is of type
short int * or long int * instead of int *, but no
flags, field width, or precision are permitted.
For example,
int nchar;
printf ("%d %s%n\n", 3, "bears", &nchar);
prints:
3 bears
and sets nchar to 7, because 3 bears is seven
characters.
The %% conversion prints a literal % character. This
conversion doesn't use an argument, and no flags, field width,
precision, or type modifiers are permitted.
This section describes how to call printf and related functions.
Prototypes for these functions are in the header file stdio.h.
Because these functions take a variable number of arguments, you
must declare prototypes for them before using them. Of course,
the easiest way to make sure you have all the right prototypes is to
just include stdio.h.
| int printf (const char *template, ...) | Function |
The printf function prints the optional arguments under the
control of the template string template to the stream
stdout. It returns the number of characters printed, or a
negative value if there was an output error.
|
| int fprintf (FILE *stream, const char *template, ...) | Function |
This function is just like printf, except that the output is
written to the stream stream instead of stdout.
|
| int sprintf (char *s, const char *template, ...) | Function |
This is like printf, except that the output is stored in the character
array s instead of written to a stream. A null character is written
to mark the end of the string.
The The behavior of this function is undefined if copying takes place
between objects that overlap--for example, if s is also given
as an argument to be printed under control of the Warning: The To avoid this problem, you can use |
| int snprintf (char *s, size_t size, const char *template, ...) | Function |
The snprintf function is similar to sprintf, except that
the size argument specifies the maximum number of characters to
produce. The trailing null character is counted towards this limit, so
you should allocate at least size characters for the string s.
The return value is the number of characters which would be generated for the given input, excluding the trailing null. If this value is greater or equal to size, not all characters from the result have been stored in s. You should try again with a bigger output string. Here is an example of doing this: /* Construct a message describing the value of a variable
whose name is name and whose value is value. */
char *
make_message (char *name, char *value)
{
/* Guess we need no more than 100 chars of space. */
int size = 100;
char *buffer = (char *) xmalloc (size);
int nchars;
/* Try to print in the allocated space. */
nchars = snprintf (buffer, size, "value of %s is %s",
name, value);
if (nchars >= size)
{
/* Reallocate buffer now that we know
how much space is needed. */
buffer = (char *) xrealloc (buffer, nchars + 1);
/* Try again. */
snprintf (buffer, size, "value of %s is %s",
name, value);
}
/* The last call worked, return the string. */
return buffer;
}
In practice, it is often easier just to use Attention: In the GNU C library version 2.0 the return value
is the number of characters stored, not including the terminating null.
If this value equals |
The functions in this section do formatted output and place the results in dynamically allocated memory.
| int asprintf (char **ptr, const char *template, ...) | Function |
This function is similar to sprintf, except that it dynamically
allocates a string (as with malloc; see Unconstrained Allocation) to hold the output, instead of putting the output in a
buffer you allocate in advance. The ptr argument should be the
address of a char * object, and asprintf stores a pointer
to the newly allocated string at that location.
Here is how to use /* Construct a message describing the value of a variable
whose name is name and whose value is value. */
char *
make_message (char *name, char *value)
{
char *result;
asprintf (&result, "value of %s is %s", name, value);
return result;
}
|
| int obstack_printf (struct obstack *obstack, const char *template, ...) | Function |
This function is similar to asprintf, except that it uses the
obstack obstack to allocate the space. See Obstacks.
The characters are written onto the end of the current object.
To get at them, you must finish the object with |
The functions vprintf and friends are provided so that you can
define your own variadic printf-like functions that make use of
the same internals as the built-in formatted output functions.
The most natural way to define such functions would be to use a language
construct to say, "Call printf and pass this template plus all
of my arguments after the first five." But there is no way to do this
in C, and it would be hard to provide a way, since at the C language
level there is no way to tell how many arguments your function received.
Since that method is impossible, we provide alternative functions, the
vprintf series, which lets you pass a va_list to describe
"all of my arguments after the first five."
When it is sufficient to define a macro rather than a real function, the GNU C compiler provides a way to do this much more easily with macros. For example:
#define myprintf(a, b, c, d, e, rest...) \
printf (mytemplate , ## rest...)
See Macro Varargs, for details. But this is limited to macros, and does not apply to real functions at all.
Before calling vprintf or the other functions listed in this
section, you must call va_start (see Variadic Functions) to initialize a pointer to the variable arguments. Then you
can call va_arg to fetch the arguments that you want to handle
yourself. This advances the pointer past those arguments.
Once your va_list pointer is pointing at the argument of your
choice, you are ready to call vprintf. That argument and all
subsequent arguments that were passed to your function are used by
vprintf along with the template that you specified separately.
In some other systems, the va_list pointer may become invalid
after the call to vprintf, so you must not use va_arg
after you call vprintf. Instead, you should call va_end
to retire the pointer from service. However, you can safely call
va_start on another pointer variable and begin fetching the
arguments again through that pointer. Calling vprintf does not
destroy the argument list of your function, merely the particular
pointer that you passed to it.
GNU C does not have such restrictions. You can safely continue to fetch
arguments from a va_list pointer after passing it to
vprintf, and va_end is a no-op. (Note, however, that
subsequent va_arg calls will fetch the same arguments which
vprintf previously used.)
Prototypes for these functions are declared in stdio.h.
| int vprintf (const char *template, va_list ap) | Function |
This function is similar to printf except that, instead of taking
a variable number of arguments directly, it takes an argument list
pointer ap.
|
| int vfprintf (FILE *stream, const char *template, va_list ap) | Function |
This is the equivalent of fprintf with the variable argument list
specified directly as for vprintf.
|
| int vsprintf (char *s, const char *template, va_list ap) | Function |
This is the equivalent of sprintf with the variable argument list
specified directly as for vprintf.
|
| int vsnprintf (char *s, size_t size, const char *template, va_list ap) | Function |
This is the equivalent of snprintf with the variable argument list
specified directly as for vprintf.
|
| int vasprintf (char **ptr, const char *template, va_list ap) | Function |
The vasprintf function is the equivalent of asprintf with the
variable argument list specified directly as for vprintf.
|
| int obstack_vprintf (struct obstack *obstack, const char *template, va_list ap) | Function |
The obstack_vprintf function is the equivalent of
obstack_printf with the variable argument list specified directly
as for vprintf.
|
Here's an example showing how you might use vfprintf. This is a
function that prints error messages to the stream stderr, along
with a prefix indicating the name of the program
(see Error Messages, for a description of
program_invocation_short_name).
#include <stdio.h>
#include <stdarg.h>
void
eprintf (const char *template, ...)
{
va_list ap;
extern char *program_invocation_short_name;
fprintf (stderr, "%s: ", program_invocation_short_name);
va_start (ap, template);
vfprintf (stderr, template, ap);
va_end (ap);
}
You could call eprintf like this:
eprintf ("file `%s' does not exist\n", filename);
In GNU C, there is a special construct you can use to let the compiler
know that a function uses a printf-style format string. Then it
can check the number and types of arguments in each call to the
function, and warn you when they do not match the format string.
For example, take this declaration of eprintf:
void eprintf (const char *template, ...)
__attribute__ ((format (printf, 1, 2)));
This tells the compiler that eprintf uses a format string like
printf (as opposed to scanf; see Formatted Input);
the format string appears as the first argument;
and the arguments to satisfy the format begin with the second.
See Function Attributes, for more information.
You can use the function parse_printf_format to obtain
information about the number and types of arguments that are expected by
a given template string. This function permits interpreters that
provide interfaces to printf to avoid passing along invalid
arguments from the user's program, which could cause a crash.
All the symbols described in this section are declared in the header
file printf.h.
| size_t parse_printf_format (const char *template, size_t n, int *argtypes) | Function |
This function returns information about the number and types of
arguments expected by the printf template string template.
The information is stored in the array argtypes; each element of
this array describes one argument. This information is encoded using
the various PA_ macros, listed below.
The n argument specifies the number of elements in the array
argtypes. This is the most elements that
|
The argument types are encoded as a combination of a basic type and modifier flag bits.
| int PA_FLAG_MASK | Macro |
This macro is a bitmask for the type modifier flag bits. You can write
the expression (argtypes[i] & PA_FLAG_MASK) to extract just the
flag bits for an argument, or (argtypes[i] & ~PA_FLAG_MASK) to
extract just the basic type code.
|
Here are symbolic constants that represent the basic types; they stand for integer values.
PA_INT
int.
PA_CHAR
int, cast to char.
PA_STRING
char *, a null-terminated string.
PA_POINTER
void *, an arbitrary pointer.
PA_FLOAT
float.
PA_DOUBLE
double.
PA_LAST
PA_LAST. For example, if you have data types foo
and bar with their own specialized printf conversions,
you could define encodings for these types as:
#define PA_FOO PA_LAST #define PA_BAR (PA_LAST + 1)
Here are the flag bits that modify a basic type. They are combined with the code for the basic type using inclusive-or.
PA_FLAG_PTR
PA_INT|PA_FLAG_PTR represents the type int *.
PA_FLAG_SHORT
short. (This corresponds to the h type modifier.)
PA_FLAG_LONG
long. (This corresponds to the l type modifier.)
PA_FLAG_LONG_LONG
long long. (This corresponds to the L type modifier.)
PA_FLAG_LONG_DOUBLE
PA_FLAG_LONG_LONG, used by convention with
a base type of PA_DOUBLE to indicate a type of long double.
Here is an example of decoding argument types for a format string. We
assume this is part of an interpreter which contains arguments of type
NUMBER, CHAR, STRING and STRUCTURE (and
perhaps others which are not valid here).
/* Test whether the nargs specified objects
in the vector args are valid
for the format string format:
if so, return 1.
If not, return 0 after printing an error message. */
int
validate_args (char *format, int nargs, OBJECT *args)
{
int *argtypes;
int nwanted;
/* Get the information about the arguments.
Each conversion specification must be at least two characters
long, so there cannot be more specifications than half the
length of the string. */
argtypes = (int *) alloca (strlen (format) / 2 * sizeof (int));
nwanted = parse_printf_format (string, nelts, argtypes);
/* Check the number of arguments. */
if (nwanted > nargs)
{
error ("too few arguments (at least %d required)", nwanted);
return 0;
}
/* Check the C type wanted for each argument
and see if the object given is suitable. */
for (i = 0; i < nwanted; i++)
{
int wanted;
if (argtypes[i] & PA_FLAG_PTR)
wanted = STRUCTURE;
else
switch (argtypes[i] & ~PA_FLAG_MASK)
{
case PA_INT:
case PA_FLOAT:
case PA_DOUBLE:
wanted = NUMBER;
break;
case PA_CHAR:
wanted = CHAR;
break;
case PA_STRING:
wanted = STRING;
break;
case PA_POINTER:
wanted = STRUCTURE;
break;
}
if (TYPE (args[i]) != wanted)
{
error ("type mismatch for arg number %d", i);
return 0;
}
}
return 1;
}
printfThe GNU C library lets you define your own custom conversion specifiers
for printf template strings, to teach printf clever ways
to print the important data structures of your program.
The way you do this is by registering the conversion with the function
register_printf_function; see Registering New Conversions.
One of the arguments you pass to this function is a pointer to a handler
function that produces the actual output; see Defining the Output Handler, for information on how to write this function.
You can also install a function that just returns information about the number and type of arguments expected by the conversion specifier. See Parsing a Template String, for information about this.
The facilities of this section are declared in the header file
printf.h.
register_printf_function
to register a new output conversion.
register_printf_function.
printf
handler function.
printf handlers.
Portability Note: The ability to extend the syntax of
printf template strings is a GNU extension. ISO standard C has
nothing similar.
The function to register a new output conversion is
register_printf_function, declared in printf.h.
| int register_printf_function (int spec, printf_function handler-function, printf_arginfo_function arginfo-function) | Function |
This function defines the conversion specifier character spec.
Thus, if spec is 'z', it defines the conversion %z.
You can redefine the built-in conversions like %s, but flag
characters like # and type modifiers like l can never be
used as conversions; calling register_printf_function for those
characters has no effect.
The handler-function is the function called by The arginfo-function is the function called by
Attention: In the GNU C library version before 2.0 the
arginfo-function function did not need to be installed unless
the user uses the The return value is You can redefine the standard output conversions, but this is probably not a good idea because of the potential for confusion. Library routines written by other people could break if you do this. |
If you define a meaning for %A, what if the template contains
%+23A or %-#A? To implement a sensible meaning for these,
the handler when called needs to be able to get the options specified in
the template.
Both the handler-function and arginfo-function accept an
argument that points to a struct printf_info, which contains
information about the options appearing in an instance of the conversion
specifier. This data type is declared in the header file
printf.h.
| struct printf_info | Type |
This structure is used to pass information about the options appearing
in an instance of a conversion specifier in a printf template
string to the handler and arginfo functions for that specifier. It
contains the following members:
|
Now let's look at how to define the handler and arginfo functions
which are passed as arguments to register_printf_function.
Compatibility Note: The interface changed in the GNU libc
version 2.0. Previously the third argument was of type
va_list *.
You should define your handler functions with a prototype like:
int function (FILE *stream, const struct printf_info *info,
const void *const *args)
The stream argument passed to the handler function is the stream to which it should write output.
The info argument is a pointer to a structure that contains information about the various options that were included with the conversion in the template string. You should not modify this structure inside your handler function. See Conversion Specifier Options, for a description of this data structure.
The args is a vector of pointers to the arguments data. The number of arguments were determined by calling the argument information function provided by the user.
Your handler function should return a value just like printf
does: it should return the number of characters it has written, or a
negative value to indicate an error.
| printf_function | Data Type |
| This is the data type that a handler function should have. |
If you are going to use parse_printf_format in your
application, you must also define a function to pass as the
arginfo-function argument for each new conversion you install with
register_printf_function.
You have to define these functions with a prototype like:
int function (const struct printf_info *info,
size_t n, int *argtypes)
The return value from the function should be the number of arguments the
conversion expects. The function should also fill in no more than
n elements of the argtypes array with information about the
types of each of these arguments. This information is encoded using the
various PA_ macros. (You will notice that this is the same
calling convention parse_printf_format itself uses.)
| printf_arginfo_function | Data Type |
| This type is used to describe functions that return information about the number and type of arguments used by a conversion specifier. |
printf Extension ExampleHere is an example showing how to define a printf handler function.
This program defines a data structure called a Widget and
defines the %W conversion to print information about Widget *
arguments, including the pointer value and the name stored in the data
structure. The %W conversion supports the minimum field width and
left-justification options, but ignores everything else.
#include <stdio.h>
#include <stdlib.h>
#include <printf.h>
typedef struct
{
char *name;
}
Widget;
int
print_widget (FILE *stream,
const struct printf_info *info,
const void *const *args)
{
const Widget *w;
char *buffer;
int len;
/* Format the output into a string. */
w = *((const Widget **) (args[0]));
len = asprintf (&buffer, "<Widget %p: %s>", w, w->name);
if (len == -1)
return -1;
/* Pad to the minimum field width and print to the stream. */
len = fprintf (stream, "%*s",
(info->left ? -info->width : info->width),
buffer);
/* Clean up and return. */
free (buffer);
return len;
}
int
print_widget_arginfo (const struct printf_info *info, size_t n,
int *argtypes)
{
/* We always take exactly one argument and this is a pointer to the
structure.. */
if (n > 0)
argtypes[0] = PA_POINTER;
return 1;
}
int
main (void)
{
/* Make a widget to print. */
Widget mywidget;
mywidget.name = "mywidget";
/* Register the print function for widgets. */
register_printf_function ('W', print_widget, print_widget_arginfo);
/* Now print the widget. */
printf ("|%W|\n", &mywidget);
printf ("|%35W|\n", &mywidget);
printf ("|%-35W|\n", &mywidget);
return 0;
}
The output produced by this program looks like:
|<Widget 0xffeffb7c: mywidget>| | <Widget 0xffeffb7c: mywidget>| |<Widget 0xffeffb7c: mywidget> |
printf HandlersThe GNU libc also contains a concrete and useful application of the
printf handler extension. There are two functions available
which implement a special way to print floating-point numbers.
| int printf_size (FILE *fp, const struct printf_info *info, const void *const *args) | Function |
Print a given floating point number as for the format %f except
that there is a postfix character indicating the divisor for the
number to make this less than 1000. There are two possible divisors:
powers of 1024 or powers to 1000. Which one is used depends on the
format character specified while registered this handler. If the
character is of lower case, 1024 is used. For upper case characters,
1000 is used.
The postfix tag corresponds to bytes, kilobytes, megabytes, gigabytes, etc. The full table is: The default precision is 3, i.e., 1024 is printed with a lower-case
format character as if it were |
Due to the requirements of register_printf_function we must also
provide the function which return information about the arguments.
| int printf_size_info (const struct printf_info *info, size_t n, int *argtypes) | Function |
This function will return in argtypes the information about the
used parameters in the way the vfprintf implementation expects
it. The format always takes one argument.
|
To use these functions both functions must be registered with a call like
register_printf_function ('B', printf_size, printf_size_info);
Here we register the functions to print numbers as powers of 1000 since
the format character 'B' is an upper-case character. If we
would additionally use 'b' in a line like
register_printf_function ('b', printf_size, printf_size_info);
we could also print using power of 1024. Please note that all what is
different in these both lines in the format specifier. The
printf_size function knows about the difference of low and upper
case format specifiers.
The use of 'B' and 'b' is no coincidence. Rather it is
the preferred way to use this functionality since it is available on
some other systems also available using the format specifiers.
The functions described in this section (scanf and related
functions) provide facilities for formatted input analogous to the
formatted output facilities. These functions provide a mechanism for
reading arbitrary values under the control of a format string or
template string.
malloc the buffer.
vscanf and friends.
Calls to scanf are superficially similar to calls to
printf in that arbitrary arguments are read under the control of
a template string. While the syntax of the conversion specifications in
the template is very similar to that for printf, the
interpretation of the template is oriented more towards free-format
input and simple pattern matching, rather than fixed-field formatting.
For example, most scanf conversions skip over any amount of
"white space" (including spaces, tabs, and newlines) in the input
file, and there is no concept of precision for the numeric input
conversions as there is for the corresponding output conversions.
Ordinarily, non-whitespace characters in the template are expected to
match characters in the input stream exactly, but a matching failure is
distinct from an input error on the stream.
Another area of difference between scanf and printf is
that you must remember to supply pointers rather than immediate values
as the optional arguments to scanf; the values that are read are
stored in the objects that the pointers point to. Even experienced
programmers tend to forget this occasionally, so if your program is
getting strange errors that seem to be related to scanf, you
might want to double-check this.
When a matching failure occurs, scanf returns immediately,
leaving the first non-matching character as the next character to be
read from the stream. The normal return value from scanf is the
number of values that were assigned, so you can use this to determine if
a matching error happened before all the expected values were read.
The scanf function is typically used for things like reading in
the contents of tables. For example, here is a function that uses
scanf to initialize an array of double:
void
readarray (double *array, int n)
{
int i;
for (i=0; i<n; i++)
if (scanf (" %lf", &(array[i])) != 1)
invalid_input_error ();
}
The formatted input functions are not used as frequently as the formatted output functions. Partly, this is because it takes some care to use them properly. Another reason is that it is difficult to recover from a matching error.
If you are trying to read input that doesn't match a single, fixed
pattern, you may be better off using a tool such as Flex to generate a
lexical scanner, or Bison to generate a parser, rather than using
scanf. For more information about these tools, see , and .
A scanf template string is a string that contains ordinary
multibyte characters interspersed with conversion specifications that
start with %.
Any whitespace character (as defined by the isspace function;
see Classification of Characters) in the template causes any number
of whitespace characters in the input stream to be read and discarded.
The whitespace characters that are matched need not be exactly the same
whitespace characters that appear in the template string. For example,
write , in the template to recognize a comma with optional
whitespace before and after.
Other characters in the template string that are not part of conversion specifications must match characters in the input stream exactly; if this is not the case, a matching failure occurs.
The conversion specifications in a scanf template string
have the general form:
% flags width type conversion
In more detail, an input conversion specification consists of an initial
% character followed in sequence by:
*, which says to ignore the text
read for this specification. When scanf finds a conversion
specification that uses this flag, it reads input as directed by the
rest of the conversion specification, but it discards this input, does
not use a pointer argument, and does not increment the count of
successful assignments.
a (valid with string conversions only)
which requests allocation of a buffer long enough to store the string in.
(This is a GNU extension.)
See Dynamic String Input.
l with integer conversions such as
%d to specify that the argument is a pointer to a long int
rather than a pointer to an int.
The exact options that are permitted and how they are interpreted vary between the different conversion specifiers. See the descriptions of the individual conversions for information about the particular options that they allow.
With the -Wformat option, the GNU C compiler checks calls to
scanf and related functions. It examines the format string and
verifies that the correct number and types of arguments are supplied.
There is also a GNU C syntax to tell the compiler that a function you
write uses a scanf-style format string.
See Function Attributes, for more information.
Here is a table that summarizes the various conversion specifications:
%d
%i
%o
%u
%x, %X
%e, %f, %g, %E, %G
%s
%[
%c
%p
%p output conversion for printf. See Other Input Conversions.
%n
%%
% character in the input stream. No
corresponding argument is used. See Other Input Conversions.
If the syntax of a conversion specification is invalid, the behavior is undefined. If there aren't enough function arguments provided to supply addresses for all the conversion specifications in the template strings that perform assignments, or if the arguments are not of the correct types, the behavior is also undefined. On the other hand, extra arguments are simply ignored.
This section describes the scanf conversions for reading numeric
values.
The %d conversion matches an optionally signed integer in decimal
radix. The syntax that is recognized is the same as that for the
strtol function (see Parsing of Integers) with the value
10 for the base argument.
The %i conversion matches an optionally signed integer in any of
the formats that the C language defines for specifying an integer
constant. The syntax that is recognized is the same as that for the
strtol function (see Parsing of Integers) with the value
0 for the base argument. (You can print integers in this
syntax with printf by using the # flag character with the
%x, %o, or %d conversion. See Integer Conversions.)
For example, any of the strings 10, 0xa, or 012
could be read in as integers under the %i conversion. Each of
these specifies a number with decimal value 10.
The %o, %u, and %x conversions match unsigned
integers in octal, decimal, and hexadecimal radices, respectively. The
syntax that is recognized is the same as that for the strtoul
function (see Parsing of Integers) with the appropriate value
(8, 10, or 16) for the base argument.
The %X conversion is identical to the %x conversion. They
both permit either uppercase or lowercase letters to be used as digits.
The default type of the corresponding argument for the %d and
%i conversions is int *, and unsigned int * for the
other integer conversions. You can use the following type modifiers to
specify other sizes of integer:
hh
signed char * or unsigned
char *.
This modifier was introduced in ISO C 9x.
h
short int * or unsigned
short int *.
j
intmax_t * or uintmax_t *.
This modifier was introduced in ISO C 9x.
l
long int * or unsigned
long int *. Two l characters is like the L modifier, below.
ll
L
q
long long int * or unsigned long long int *. (The long long type is an extension supported by the
GNU C compiler. For systems that don't provide extra-long integers, this
is the same as long int.)
The q modifier is another name for the same thing, which comes
from 4.4 BSD; a long long int is sometimes called a "quad"
int.
t
ptrdiff_t *.
This modifier was introduced in ISO C 9x.
z
size_t *.
This modifier was introduced in ISO C 9x.
All of the %e, %f, %g, %E, and %G
input conversions are interchangeable. They all match an optionally
signed floating point number, in the same syntax as for the
strtod function (see Parsing of Floats).
For the floating-point input conversions, the default argument type is
float *. (This is different from the corresponding output
conversions, where the default type is double; remember that
float arguments to printf are converted to double
by the default argument promotions, but float * arguments are
not promoted to double *.) You can specify other sizes of float
using these type modifiers:
l
double *.
L
long double *.
For all the above number parsing formats there is an additional optional
flag '. When this flag is given the scanf function
expects the number represented in the input string to be formatted
according to the grouping rules of the currently selected locale
(see General Numeric).
If the "C" or "POSIX" locale is selected there is no
difference. But for a locale which specifies values for the appropriate
fields in the locale the input must have the correct form in the input.
Otherwise the longest prefix with a correct form is processed.
This section describes the scanf input conversions for reading
string and character values: %s, %[, and %c.
You have two options for how to receive the input from these conversions:
char *.
Warning: To make a robust program, you must make sure that the input (plus its terminating null) cannot possibly exceed the size of the buffer you provide. In general, the only way to do this is to specify a maximum field width one less than the buffer size. If you provide the buffer, always specify a maximum field width to prevent overflow.
scanf to allocate a big enough buffer, by specifying the
a flag character. This is a GNU extension. You should provide
an argument of type char ** for the buffer address to be stored
in. See Dynamic String Input.
The %c conversion is the simplest: it matches a fixed number of
characters, always. The maximum field with says how many characters to
read; if you don't specify the maximum, the default is 1. This
conversion doesn't append a null character to the end of the text it
reads. It also does not skip over initial whitespace characters. It
reads precisely the next n characters, and fails if it cannot get
that many. Since there is always a maximum field width with %c
(whether specified, or 1 by default), you can always prevent overflow by
making the buffer long enough.
The %s conversion matches a string of non-whitespace characters.
It skips and discards initial whitespace, but stops when it encounters
more whitespace after having read something. It stores a null character
at the end of the text that it reads.
For example, reading the input:
hello, world
with the conversion %10c produces " hello, wo", but
reading the same input with the conversion %10s produces
"hello,".
Warning: If you do not specify a field width for %s,
then the number of characters read is limited only by where the next
whitespace character appears. This almost certainly means that invalid
input can make your program crash--which is a bug.
To read in characters that belong to an arbitrary set of your choice,
use the %[ conversion. You specify the set between the [
character and a following ] character, using the same syntax used
in regular expressions. As special cases:
] character can be specified as the first character
of the set.
- character (that is, one that is not the first or
last character of the set) is used to specify a range of characters.
^ immediately follows the initial [,
then the set of allowed input characters is the everything except
the characters listed.
The %[ conversion does not skip over initial whitespace
characters.
Here are some examples of %[ conversions and what they mean:
%25[1234567890]
%25[][]
%25[^ \f\n\r\t\v]
%s, because if the input begins with a whitespace character,
%[ reports a matching failure while %s simply discards the
initial whitespace.
%25[a-z]
One more reminder: the %s and %[ conversions are
dangerous if you don't specify a maximum width or use the
a flag, because input too long would overflow whatever buffer you
have provided for it. No matter how long your buffer is, a user could
supply input that is longer. A well-written program reports invalid
input with a comprehensible error message, not with a crash.
A GNU extension to formatted input lets you safely read a string with no
maximum size. Using this feature, you don't supply a buffer; instead,
scanf allocates a buffer big enough to hold the data and gives
you its address. To use this feature, write a as a flag
character, as in %as or %a[0-9a-z].
The pointer argument you supply for where to store the input should have
type char **. The scanf function allocates a buffer and
stores its address in the word that the argument points to. You should
free the buffer with free when you no longer need it.
Here is an example of using the a flag with the %[...]
conversion specification to read a "variable assignment" of the form
variable = value.
{
char *variable, *value;
if (2 > scanf ("%a[a-zA-Z0-9] = %a[^\n]\n",
&variable, &value))
{
invalid_input_error ();
return 0;
}
...
}
This section describes the miscellaneous input conversions.
The %p conversion is used to read a pointer value. It recognizes
the same syntax as is used by the %p output conversion for
printf (see Other Output Conversions); that is, a hexadecimal
number just as the %x conversion accepts. The corresponding
argument should be of type void **; that is, the address of a
place to store a pointer.
The resulting pointer value is not guaranteed to be valid if it was not originally written during the same program execution that reads it in.
The %n conversion produces the number of characters read so far
by this call. The corresponding argument should be of type int *.
This conversion works in the same way as the %n conversion for
printf; see Other Output Conversions, for an example.
The %n conversion is the only mechanism for determining the
success of literal matches or conversions with suppressed assignments.
If the %n follows the locus of a matching failure, then no value
is stored for it since scanf returns before processing the
%n. If you store -1 in that argument slot before calling
scanf, the presence of -1 after scanf indicates an
error occurred before the %n was reached.
Finally, the %% conversion matches a literal % character
in the input stream, without using an argument. This conversion does
not permit any flags, field width, or type modifier to be specified.
Here are the descriptions of the functions for performing formatted
input.
Prototypes for these functions are in the header file stdio.h.
| int scanf (const char *template, ...) | Function |
The scanf function reads formatted input from the stream
stdin under the control of the template string template.
The optional arguments are pointers to the places which receive the
resulting values.
The return value is normally the number of successful assignments. If
an end-of-file condition is detected before any matches are performed
(including matches against whitespace and literal characters in the
template), then |
| int fscanf (FILE *stream, const char *template, ...) | Function |
This function is just like scanf, except that the input is read
from the stream stream instead of stdin.
|
| int sscanf (const char *s, const char *template, ...) | Function |
This is like scanf, except that the characters are taken from the
null-terminated string s instead of from a stream. Reaching the
end of the string is treated as an end-of-file condition.
The behavior of this function is undefined if copying takes place
between objects that overlap--for example, if s is also given
as an argument to receive a string read under control of the |
The functions vscanf and friends are provided so that you can
define your own variadic scanf-like functions that make use of
the same internals as the built-in formatted output functions.
These functions are analogous to the vprintf series of output
functions. See Variable Arguments Output, for important
information on how to use them.
Portability Note: The functions listed in this section are GNU extensions.
| int vscanf (const char *template, va_list ap) | Function |
This function is similar to scanf except that, instead of taking
a variable number of arguments directly, it takes an argument list
pointer ap of type va_list (see Variadic Functions).
|
| int vfscanf (FILE *stream, const char *template, va_list ap) | Function |
This is the equivalent of fscanf with the variable argument list
specified directly as for vscanf.
|
| int vsscanf (const char *s, const char *template, va_list ap) | Function |
This is the equivalent of sscanf with the variable argument list
specified directly as for vscanf.
|
In GNU C, there is a special construct you can use to let the compiler
know that a function uses a scanf-style format string. Then it
can check the number and types of arguments in each call to the
function, and warn you when they do not match the format string.
See Function Attributes, for details.
Many of the functions described in this chapter return the value of the
macro EOF to indicate unsuccessful completion of the operation.
Since EOF is used to report both end of file and random errors,
it's often better to use the feof function to check explicitly
for end of file and ferror to check for errors. These functions
check indicators that are part of the internal state of the stream
object, indicators set if the appropriate condition was detected by a
previous I/O operation on that stream.
These symbols are declared in the header file stdio.h.
| int EOF | Macro |
This macro is an integer value that is returned by a number of functions
to indicate an end-of-file condition, or some other error situation.
With the GNU library, EOF is -1. In other libraries, its
value may be some other negative number.
|
| void clearerr (FILE *stream) | Function |
|
This function clears the end-of-file and error indicators for the
stream stream.
The file positioning functions (see File Positioning) also clear the end-of-file indicator for the stream. |
| int feof (FILE *stream) | Function |
The feof function returns nonzero if and only if the end-of-file
indicator for the stream stream is set.
|
| int ferror (FILE *stream) | Function |
The ferror function returns nonzero if and only if the error
indicator for the stream stream is set, indicating that an error
has occurred on a previous operation on the stream.
|
In addition to setting the error indicator associated with the stream,
the functions that operate on streams also set errno in the same
way as the corresponding low-level functions that operate on file
descriptors. For example, all of the functions that perform output to a
stream--such as fputc, printf, and fflush--are
implemented in terms of write, and all of the errno error
conditions defined for write are meaningful for these functions.
For more information about the descriptor-level I/O functions, see
Low-Level I/O.
The GNU system and other POSIX-compatible operating systems organize all files as uniform sequences of characters. However, some other systems make a distinction between files containing text and files containing binary data, and the input and output facilities of ISO C provide for this distinction. This section tells you how to write programs portable to such systems.
When you open a stream, you can specify either a text stream or a
binary stream. You indicate that you want a binary stream by
specifying the b modifier in the opentype argument to
fopen; see Opening Streams. Without this
option, fopen opens the file as a text stream.
Text and binary streams differ in several ways:
'\n') characters, while a binary stream is
simply a long series of characters. A text stream might on some systems
fail to handle lines more than 254 characters long (including the
terminating newline character).
Since a binary stream is always more capable and more predictable than a text stream, you might wonder what purpose text streams serve. Why not simply always use binary streams? The answer is that on these operating systems, text and binary streams use different file formats, and the only way to read or write "an ordinary file of text" that can work with other text-oriented programs is through a text stream.
In the GNU library, and on all POSIX systems, there is no difference between text streams and binary streams. When you open a stream, you get the same kind of stream regardless of whether you ask for binary. This stream can handle any file content, and has none of the restrictions that text streams sometimes have.
The file position of a stream describes where in the file the stream is currently reading or writing. I/O on the stream advances the file position through the file. In the GNU system, the file position is represented as an integer, which counts the number of bytes from the beginning of the file. See File Position.
During I/O to an ordinary disk file, you can change the file position whenever you wish, so as to read or write any portion of the file. Some other kinds of files may also permit this. Files which support changing the file position are sometimes referred to as random-access files.
You can use the functions in this section to examine or modify the file
position indicator associated with a stream. The symbols listed below
are declared in the header file stdio.h.
| long int ftell (FILE *stream) | Function |
|
This function returns the current file position of the stream
stream.
This function can fail if the stream doesn't support file positioning,
or if the file position can't be represented in a |
| off_t ftello (FILE *stream) | Function |
The ftello function is similar to ftell only it corrects a
problem which the POSIX type system. In this type system all file
positions are described using values of type off_t which is not
necessarily of the same size as long int. Therefore using
ftell can lead to problems if the implementation is written on
top of a POSIX compliant lowlevel I/O implementation.
Therefore it is a good idea to prefer If this function fails it return The function is an extension defined in the Unix Single Specification version 2. When the sources are compiled with |
| off64_t ftello64 (FILE *stream) | Function |
This function is similar to ftello with the only difference that
the return value is of type off64_t. This also requires that the
stream stream was opened using either fopen64,
freopen64, or tmpfile64 since otherwise the underlying
file operations to position the file pointer beyond the 2^31
bytes limit might fail.
If the sources are compiled with |
| int fseek (FILE *stream, long int offset, int whence) | Function |
The fseek function is used to change the file position of the
stream stream. The value of whence must be one of the
constants SEEK_SET, SEEK_CUR, or SEEK_END, to
indicate whether the offset is relative to the beginning of the
file, the current file position, or the end of the file, respectively.
This function returns a value of zero if the operation was successful,
and a nonzero value to indicate failure. A successful call also clears
the end-of-file indicator of stream and discards any characters
that were "pushed back" by the use of
|
| int fseeko (FILE *stream, off_t offset, int whence) | Function |
This function is similar to fseek but it corrects a problem with
fseek in a system with POSIX types. Using a value of type
long int for the offset is not compatible with POSIX.
fseeko uses the correct type off_t for the offset
parameter.
For this reason it is a good idea to prefer The functionality and return value is the same as for The function is an extension defined in the Unix Single Specification version 2. When the sources are compiled with |
| int fseeko64 (FILE *stream, off64_t offset, int whence) | Function |
This function is similar to fseeko with the only difference that
the offset parameter is of type off64_t. This also
requires that the stream stream was opened using either
fopen64, freopen64, or tmpfile64 since otherwise
the underlying file operations to position the file pointer beyond the
2^31 bytes limit might fail.
If the sources are compiled with |
Portability Note: In non-POSIX systems, ftell,
ftello, fseek and fseeko might work reliably only
on binary streams. See Binary Streams.
The following symbolic constants are defined for use as the whence
argument to fseek. They are also used with the lseek
function (see I/O Primitives) and to specify offsets for file locks
(see Control Operations).
| int SEEK_SET | Macro |
This is an integer constant which, when used as the whence
argument to the fseek or fseeko function, specifies that
the offset provided is relative to the beginning of the file.
|
| int SEEK_CUR | Macro |
This is an integer constant which, when used as the whence
argument to the fseek or fseeko function, specifies that
the offset provided is relative to the current file position.
|
| int SEEK_END | Macro |
This is an integer constant which, when used as the whence
argument to the fseek or fseeko function, specifies that
the offset provided is relative to the end of the file.
|
| void rewind (FILE *stream) | Function |
The rewind function positions the stream stream at the
beginning of the file. It is equivalent to calling fseek or
fseeko on the stream with an offset argument of
0L and a whence argument of SEEK_SET, except that
the return value is discarded and the error indicator for the stream is
reset.
|
These three aliases for the SEEK_... constants exist for the
sake of compatibility with older BSD systems. They are defined in two
different header files: fcntl.h and sys/file.h.
L_SET
SEEK_SET.
L_INCR
SEEK_CUR.
L_XTND
SEEK_END.
On the GNU system, the file position is truly a character count. You
can specify any character count value as an argument to fseek or
fseeko and get reliable results for any random access file.
However, some ISO C systems do not represent file positions in this
way.
On some systems where text streams truly differ from binary streams, it is impossible to represent the file position of a text stream as a count of characters from the beginning of the file. For example, the file position on some systems must encode both a record offset within the file, and a character offset within the record.
As a consequence, if you want your programs to be portable to these systems, you must observe certain rules:
ftell on a text stream has no predictable
relationship to the number of characters you have read so far. The only
thing you can rely on is that you can use it subsequently as the
offset argument to fseek or fseeko to move back to
the same file position.
fseek or fseeko on a text stream, either the
offset must either be zero; or whence must be
SEEK_SET and the offset must be the result of an earlier
call to ftell on the same stream.
ungetc
that haven't been read or discarded. See Unreading.
But even if you observe these rules, you may still have trouble for long
files, because ftell and fseek use a long int value
to represent the file position. This type may not have room to encode
all the file positions in a large file. Using the ftello and
fseeko functions might help here since the off_t type is
expected to be able to hold all file position values but this still does
not help to handle additional information which must be associated with
a file position.
So if you do want to support systems with peculiar encodings for the
file positions, it is better to use the functions fgetpos and
fsetpos instead. These functions represent the file position
using the data type fpos_t, whose internal representation varies
from system to system.
These symbols are declared in the header file stdio.h.
| fpos_t | Data Type |
This is the type of an object that can encode information about the
file position of a stream, for use by the functions fgetpos and
fsetpos.
In the GNU system, When compiling with |
| fpos64_t | Data Type |
This is the type of an object that can encode information about the
file position of a stream, for use by the functions fgetpos64 and
fsetpos64.
In the GNU system, |
| int fgetpos (FILE *stream, fpos_t *position) | Function |
This function stores the value of the file position indicator for the
stream stream in the fpos_t object pointed to by
position. If successful, fgetpos returns zero; otherwise
it returns a nonzero value and stores an implementation-defined positive
value in errno.
When the sources are compiled with |
| int fgetpos64 (FILE *stream, fpos64_t *position) | Function |
This function is similar to fgetpos but the file position is
returned in a variable of type fpos64_t to which position
points.
If the sources are compiled with |
| int fsetpos (FILE *stream, const fpos_t *position) | Function |
This function sets the file position indicator for the stream stream
to the position position, which must have been set by a previous
call to fgetpos on the same stream. If successful, fsetpos
clears the end-of-file indicator on the stream, discards any characters
that were "pushed back" by the use of ungetc, and returns a value
of zero. Otherwise, fsetpos returns a nonzero value and stores
an implementation-defined positive value in errno.
When the sources are compiled with |
| int fsetpos64 (FILE *stream, const fpos64_t *position) | Function |
This function is similar to fsetpos but the file position used
for positioning is provided in a variable of type fpos64_t to
which position points.
If the sources are compiled with |
Characters that are written to a stream are normally accumulated and transmitted asynchronously to the file in a block, instead of appearing as soon as they are output by the application program. Similarly, streams often retrieve input from the host environment in blocks rather than on a character-by-character basis. This is called buffering.
If you are writing programs that do interactive input and output using streams, you need to understand how buffering works when you design the user interface to your program. Otherwise, you might find that output (such as progress or prompt messages) doesn't appear when you intended it to, or other unexpected behavior.
This section deals only with controlling when characters are transmitted between the stream and the file or device, and not with how things like echoing, flow control, and the like are handled on specific classes of devices. For information on common control operations on terminal devices, see Low-Level Terminal Interface.
You can bypass the stream buffering facilities altogether by using the low-level input and output functions that operate on file descriptors instead. See Low-Level I/O.
There are three different kinds of buffering strategies:
Newly opened streams are normally fully buffered, with one exception: a stream connected to an interactive device such as a terminal is initially line buffered. See Controlling Buffering, for information on how to select a different kind of buffering. Usually the automatic selection gives you the most convenient kind of buffering for the file or device you open.
The use of line buffering for interactive devices implies that output
messages ending in a newline will appear immediately--which is usually
what you want. Output that doesn't end in a newline might or might not
show up immediately, so if you want them to appear immediately, you
should flush buffered output explicitly with fflush, as described
in Flushing Buffers.
Flushing output on a buffered stream means transmitting all accumulated characters to the file. There are many circumstances when buffered output on a stream is flushed automatically:
exit.
See Normal Termination.
If you want to flush the buffered output at another time, call
fflush, which is declared in the header file stdio.h.
| int fflush (FILE *stream) | Function |
This function causes any buffered output on stream to be delivered
to the file. If stream is a null pointer, then
fflush causes buffered output on all open output streams
to be flushed.
This function returns |
Compatibility Note: Some brain-damaged operating systems have been known to be so thoroughly fixated on line-oriented input and output that flushing a line buffered stream causes a newline to be written! Fortunately, this "feature" seems to be becoming less common. You do not need to worry about this in the GNU system.
After opening a stream (but before any other operations have been
performed on it), you can explicitly specify what kind of buffering you
want it to have using the setvbuf function.
The facilities listed in this section are declared in the header
file stdio.h.
| int setvbuf (FILE *stream, char *buf, int mode, size_t size) | Function |
This function is used to specify that the stream stream should
have the buffering mode mode, which can be either _IOFBF
(for full buffering), _IOLBF (for line buffering), or
_IONBF (for unbuffered input/output).
If you specify a null pointer as the buf argument, then Otherwise, buf should be a character array that can hold at least
size characters. You should not free the space for this array as
long as the stream remains open and this array remains its buffer. You
should usually either allocate it statically, or While the array remains a stream buffer, the stream I/O functions will use the buffer for their internal purposes. You shouldn't try to access the values in the array directly while the stream is using it for buffering. The |
| int _IOFBF | Macro |
The value of this macro is an integer constant expression that can be
used as the mode argument to the setvbuf function to
specify that the stream should be fully buffered.
|
| int _IOLBF | Macro |
The value of this macro is an integer constant expression that can be
used as the mode argument to the setvbuf function to
specify that the stream should be line buffered.
|
| int _IONBF | Macro |
The value of this macro is an integer constant expression that can be
used as the mode argument to the setvbuf function to
specify that the stream should be unbuffered.
|
| int BUFSIZ | Macro |
The value of this macro is an integer constant expression that is good
to use for the size argument to setvbuf. This value is
guaranteed to be at least 256.
The value of Actually, you can get an even better value to use for the buffer size
by means of the Sometimes people also use |
| void setbuf (FILE *stream, char *buf) | Function |
If buf is a null pointer, the effect of this function is
equivalent to calling setvbuf with a mode argument of
_IONBF. Otherwise, it is equivalent to calling setvbuf
with buf, and a mode of _IOFBF and a size
argument of BUFSIZ.
The |
| void setbuffer (FILE *stream, char *buf, size_t size) | Function |
|
If buf is a null pointer, this function makes stream unbuffered.
Otherwise, it makes stream fully buffered using buf as the
buffer. The size argument specifies the length of buf.
This function is provided for compatibility with old BSD code. Use
|
| void setlinebuf (FILE *stream) | Function |
|
This function makes stream be line buffered, and allocates the
buffer for you.
This function is provided for compatibility with old BSD code. Use
|
The GNU library provides ways for you to define additional kinds of streams that do not necessarily correspond to an open file.
One such type of stream takes input from or writes output to a string.
These kinds of streams are used internally to implement the
sprintf and sscanf functions. You can also create such a
stream explicitly, using the functions described in String Streams.
More generally, you can define streams that do input/output to arbitrary objects using functions supplied by your program. This protocol is discussed in Custom Streams.
Portability Note: The facilities described in this section are specific to GNU. Other systems or C implementations might or might not provide equivalent functionality.
The fmemopen and open_memstream functions allow you to do
I/O to a string or memory buffer. These facilities are declared in
stdio.h.
| FILE * fmemopen (void *buf, size_t size, const char *opentype) | Function |
|
This function opens a stream that allows the access specified by the
opentype argument, that reads from or writes to the buffer specified
by the argument buf. This array must be at least size bytes long.
If you specify a null pointer as the buf argument, The argument opentype is the same as in When a stream open for writing is flushed or closed, a null character (zero byte) is written at the end of the buffer if it fits. You should add an extra byte to the size argument to account for this. Attempts to write more than size bytes to the buffer result in an error. For a stream open for reading, null characters (zero bytes) in the buffer do not count as "end of file". Read operations indicate end of file only when the file position advances past size bytes. So, if you want to read characters from a null-terminated string, you should supply the length of the string as the size argument. |
Here is an example of using fmemopen to create a stream for
reading from a string:
#include <stdio.h>
static char buffer[] = "foobar";
int
main (void)
{
int ch;
FILE *stream;
stream = fmemopen (buffer, strlen (buffer), "r");
while ((ch = fgetc (stream)) != EOF)
printf ("Got %c\n", ch);
fclose (stream);
return 0;
}
This program produces the following output:
Got f Got o Got o Got b Got a Got r
| FILE * open_memstream (char **ptr, size_t *sizeloc) | Function |
This function opens a stream for writing to a buffer. The buffer is
allocated dynamically (as with malloc; see Unconstrained Allocation) and grown as necessary.
When the stream is closed with A null character is written at the end of the buffer. This null character is not included in the size value stored at sizeloc. You can move the stream's file position with |
Here is an example of using open_memstream:
#include <stdio.h>
int
main (void)
{
char *bp;
size_t size;
FILE *stream;
stream = open_memstream (&bp, &size);
fprintf (stream, "hello");
fflush (stream);
printf ("buf = `%s', size = %d\n", bp, size);
fprintf (stream, ", world");
fclose (stream);
printf ("buf = `%s', size = %d\n", bp, size);
return 0;
}
This program produces the following output:
buf = `hello', size = 5 buf = `hello, world', size = 12
You can open an output stream that puts it data in an obstack. See Obstacks.
| FILE * open_obstack_stream (struct obstack *obstack) | Function |
|
This function opens a stream for writing data into the obstack obstack.
This starts an object in the obstack and makes it grow as data is
written (see Growing Objects).
Calling You can move the file position of an obstack stream with To make the object permanent, update the obstack with But how do you find out how long the object is? You can get the length
in bytes by calling obstack_1grow (obstack, 0); Whichever one you do, you must do it before calling
|
Here is a sample function that uses open_obstack_stream:
char *
make_message_string (const char *a, int b)
{
FILE *stream = open_obstack_stream (&message_obstack);
output_task (stream);
fprintf (stream, ": ");
fprintf (stream, a, b);
fprintf (stream, "\n");
fclose (stream);
obstack_1grow (&message_obstack, 0);
return obstack_finish (&message_obstack);
}
This section describes how you can make a stream that gets input from an arbitrary data source or writes output to an arbitrary data sink programmed by you. We call these custom streams.
Inside every custom stream is a special object called the cookie.
This is an object supplied by you which records where to fetch or store
the data read or written. It is up to you to define a data type to use
for the cookie. The stream functions in the library never refer
directly to its contents, and they don't even know what the type is;
they record its address with type void *.
To implement a custom stream, you must specify how to fetch or store the data in the specified place. You do this by defining hook functions to read, write, change "file position", and close the stream. All four of these functions will be passed the stream's cookie so they can tell where to fetch or store the data. The library functions don't know what's inside the cookie, but your functions will know.
When you create a custom stream, you must specify the cookie pointer,
and also the four hook functions stored in a structure of type
cookie_io_functions_t.
These facilities are declared in stdio.h.
| cookie_io_functions_t | Data Type |
This is a structure type that holds the functions that define the
communications protocol between the stream and its cookie. It has
the following members:
|
| FILE * fopencookie (void *cookie, const char *opentype, cookie_io_functions_t io-functions) | Function |
This function actually creates the stream for communicating with the
cookie using the functions in the io-functions argument.
The opentype argument is interpreted as for fopen;
see Opening Streams. (But note that the "truncate on
open" option is ignored.) The new stream is fully buffered.
The |
Here are more details on how you should define the four hook functions that a custom stream needs.
You should define the function to read data from the cookie as:
ssize_t reader (void *cookie, void *buffer, size_t size)
This is very similar to the read function; see I/O Primitives. Your function should transfer up to size bytes into
the buffer, and return the number of bytes read, or zero to
indicate end-of-file. You can return a value of -1 to indicate
an error.
You should define the function to write data to the cookie as:
ssize_t writer (void *cookie, const void *buffer, size_t size)
This is very similar to the write function; see I/O Primitives. Your function should transfer up to size bytes from
the buffer, and return the number of bytes written. You can return a
value of -1 to indicate an error.
You should define the function to perform seek operations on the cookie as:
int seeker (void *cookie, fpos_t *position, int whence)
For this function, the position and whence arguments are
interpreted as for fgetpos; see Portable Positioning. In
the GNU library, fpos_t is equivalent to off_t or
long int, and simply represents the number of bytes from the
beginning of the file.
After doing the seek operation, your function should store the resulting
file position relative to the beginning of the file in position.
Your function should return a value of 0 on success and -1
to indicate an error.
You should define the function to do cleanup operations on the cookie appropriate for closing the stream as:
int cleaner (void *cookie)
Your function should return -1 to indicate an error, and 0
otherwise.
| cookie_read_function | Data Type |
| This is the data type that the read function for a custom stream should have. If you declare the function as shown above, this is the type it will have. |
| cookie_write_function | Data Type |
| The data type of the write function for a custom stream. |
| cookie_seek_function | Data Type |
| The data type of the seek function for a custom stream. |
| cookie_close_function | Data Type |
| The data type of the close function for a custom stream. |
On systems which are based on System V messages of programs (especially
the system tools) are printed in a strict form using the fmtmsg
function. The uniformity sometimes helps the user to interpret messages
and the strictness tests of the fmtmsg function ensure that the
programmer follows some minimal requirements.
fmtmsg function.
fmtmsg and addseverity.
Messages can be printed to standard error and/or to the console. To
select the destination the programmer can use the following two values,
bitwise OR combined if wanted, for the classification parameter of
fmtmsg:
MM_PRINT
MM_CONSOLE
The erroneous piece of the system can be signalled by exactly one of the
following values which also is bitwise ORed with the
classification parameter to fmtmsg:
MM_HARD
MM_SOFT
MM_FIRM
A third component of the classification parameter to fmtmsg
can describe the part of the system which detects the problem. This is
done by using exactly one of the following values:
MM_APPL
MM_UTIL
MM_OPSYS
A last component of classification can signal the results of this message. Exactly one of the following values can be used:
MM_RECOVER
MM_NRECOV
| int fmtmsg (long int classification, const char *label, int severity, const char *text, const char *action, const char *tag) | Function |
|
Display a message described by its parameters on the device(s) specified
in the classification parameter. The label parameter
identifies the source of the message. The string should consist of two
colon separated parts where the first part has not more than 10 and the
second part not more the 14 characters. The text parameter
describes the condition of the error, the action parameter possible
steps to recover from the error and the tag parameter is a
reference to the online documentation where more information can be
found. It should contain the label value and a unique
identification number.
Each of the parameters can be a special value which means this value is to be omitted. The symbolic names for these values are:
There is another way certain fields can be omitted from the output to standard error. This is described below in the description of environment variables influencing the behaviour. The severity parameter can have one of the values in the following table:
The numeric value of these five macros are between If no parameter is ignored the output looks like this: label: severity-string: text TO FIX: action tag The colons, new line characters and the This function is specified in the X/Open Portability Guide. It is also available on all system derived from System V. The function returns the value |
There are two environment variables which influence the behaviour of
fmtmsg. The first is MSGVERB. It is used to control the
output actually happening on standard error (not the console
output). Each of the five fields can be explicitly enabled. To do
this the user has to put the MSGVERB variable with a format like
the following in the environment before calling the fmtmsg function
the first time:
MSGVERB=keyword[:keyword[:...]]
Valid keywords are label, severity, text,
action, and tag. If the environment variable is not given
or is the empty string, a not supported keyword is given or the value is
somehow else invalid, no part of the message is masked out.
The second environment variable which influences the behaviour of
fmtmsg is SEV_LEVEL. This variable and the change in the
behaviour of fmtmsg is not specified in the X/Open Portability
Guide. It is available in System V systems, though. It can be used to
introduce new severity levels. By default, only the five severity levels
described above are available. Any other numeric value would make
fmtmsg print nothing.
If the user puts SEV_LEVEL with a format like
SEV_LEVEL=[description[:description[:...]]]
in the environment of the process before the first call to
fmtmsg, where description has a value of the form
severity-keyword,level,printstring
The severity-keyword part is not used by fmtmsg but it has
to be present. The level part is a string representation of a
number. The numeric value must be a number greater than 4. This value
must be used in the severity parameter of fmtmsg to select
this class. It is not possible to overwrite any of the predefined
classes. The printstring is the string printed when a message of
this class is processed by fmtmsg (see above, fmtsmg does
not print the numeric value but instead the string representation).
There is another possibility to introduce severity classes beside using
the environment variable SEV_LEVEL. This simplifies the task of
introducing new classes in a running program. One could use the
setenv or putenv function to set the environment variable,
but this is toilsome.
| int addseverity (int severity, const char *string) | Function |
This function allows to introduce new severity classes which can be
addressed by the severity parameter of the fmtmsg function.
The severity parameter of addseverity must match the value
for the parameter with the same name of fmtmsg and string
is the string printed in the actual messages instead of the numeric
value.
If string is It is not possible to overwrite or remove one of the default severity
classes. All calls to The return value is This function is not specified in the X/Open Portability Guide although
the |
fmtmsg and addseverityHere is a simple example program to illustrate the use of the both functions described in this section.
#include <fmtmsg.h>
int
main (void)
{
addseverity (5, "NOTE2");
fmtmsg (MM_PRINT, "only1field", MM_INFO, "text2", "action2", "tag2");
fmtmsg (MM_PRINT, "UX:cat", 5, "invalid syntax", "refer to manual",
"UX:cat:001");
fmtmsg (MM_PRINT, "label:foo", 6, "text", "action", "tag");
return 0;
}
The second call to fmtmsg illustrates a use of this function how
it usually happens on System V systems which heavily use this function.
It might be worth a thought to follow the scheme used in System V
systems so we give a short explanation here. The value of the
label field (UX:cat) says that the error occurred in the
Unix program cat. The explanation of the error follows and the
value for the action parameter is "refer to manual". One
could me more specific here, if needed. The tag field contains,
as proposed above, the value of the string given for the label
parameter, and additionally a unique ID (001 in this case). For
a GNU environment this string could contain a reference to the
corresponding node in the Info page for the program.
Running this program without specifying the MSGVERB and
SEV_LEVEL function produces the following output:
UX:cat: NOTE2: invalid syntax TO FIX: refer to manual UX:cat:001
We see the different fields of the message and how the extra glue (the
colons and the TO FIX string) are printed. But only one of the
three calls to fmtmsg produced output. The first call does not
print anything because the label parameter is not in the correct
form. The string must contain two fields, separated by a colon
(see Printing Formatted Messages). The third fmtmsg call
produced no output since the class with the numeric value 6 is
not defined. Although a class with numeric value 5 is also not
defined by default, the call the addseverity introduces it and
the second call to fmtmsg produces the above output.
When we change the environment of the program to contain
SEV_LEVEL=XXX,6,NOTE when running it we get a different result:
UX:cat: NOTE2: invalid syntax TO FIX: refer to manual UX:cat:001 label:foo: NOTE: text TO FIX: action tag
Now the third call the fmtmsg produced some output and we see how
the string NOTE from the environment variable appears in the
message.
Now we can reduce the output by specifying in which fields we are
interested in. If we additionally set the environment variable
MSGVERB to the value severity:label:action we get the
following output:
UX:cat: NOTE2 TO FIX: refer to manual label:foo: NOTE TO FIX: action
I.e., the output produced by the text and the tag parameters
to fmtmsg vanished. Please also note that now there is no colon
after the NOTE and NOTE2 strings in the output. This is
not necessary since there is no more output on this line since the text
is missing.
This chapter describes functions for performing low-level input/output operations on file descriptors. These functions include the primitives for the higher-level I/O functions described in I/O on Streams, as well as functions for performing low-level control operations for which there are no equivalents on streams.
Stream-level I/O is more flexible and usually more convenient; therefore, programmers generally use the descriptor-level functions only when necessary. These are some of the usual reasons:
fileno to get the descriptor
corresponding to a stream.)
This section describes the primitives for opening and closing files
using file descriptors. The open and creat functions are
declared in the header file fcntl.h, while close is
declared in unistd.h.
| int open (const char *filename, int flags[, mode_t mode]) | Function |
The open function creates and returns a new file descriptor
for the file named by filename. Initially, the file position
indicator for the file is at the beginning of the file. The argument
mode is used only when a file is created, but it doesn't hurt
to supply the argument in any case.
The flags argument controls how the file is to be opened. This is
a bit mask; you create the value by the bitwise OR of the appropriate
parameters (using the The normal return value from
If on a 32 bits machine the sources are translated with
This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The |
| int open64 (const char *filename, int flags[, mode_t mode]) | Function |
This function is similar to open. It returns a file descriptor
which can be used to access the file named by filename. The only
the difference is that on 32 bits systems the file is opened in the
large file mode. I.e., file length and file offsets can exceed 31 bits.
When the sources are translated with |
| int creat (const char *filename, mode_t mode) | Obsolete function |
This function is obsolete. The call:
creat (filename, mode) is equivalent to: open (filename, O_WRONLY | O_CREAT | O_TRUNC, mode) If on a 32 bits machine the sources are translated with
|
| int creat64 (const char *filename, mode_t mode) | Obsolete function |
This function is similar to creat. It returns a file descriptor
which can be used to access the file named by filename. The only
the difference is that on 32 bits systems the file is opened in the
large file mode. I.e., file length and file offsets can exceed 31 bits.
To use this file descriptor one must not use the normal operations but
instead the counterparts named When the sources are translated with |
| int close (int filedes) | Function |
The function close closes the file descriptor filedes.
Closing a file has the following consequences:
This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The normal return value from
Please note that there is no separate |
To close a stream, call fclose (see Closing Streams) instead
of trying to close its underlying file descriptor with close.
This flushes any buffered output and updates the stream object to
indicate that it is closed.
In some situations it is useful to explicitly determine the size of a
file. Since the 4.2BSD days there is a function to truncate a file to
at most a given number of bytes and POSIX defines one additional
function. The prototypes for these functions are in unistd.h.
| int truncate (const char *name, off_t length) | Function |
The truncation function truncates the file named by name to
at most length bytes. I.e., if the file was larger before the
extra bytes are stripped of. If the file was small or equal to
length in size before nothing is done. The file must be writable
by the user to perform this operation.
When the source file is compiled with The return value is zero is everything went ok. Otherwise the return value is -1 and the global variable errno is set to:
This function was introduced in 4.2BSD but also was available in later System V systems. It is not added to POSIX since the authors felt it is only of marginally additional utility. See below. |
| int truncate64 (const char *name, off64_t length) | Function |
This function is similar to the truncate function. The
difference is that the length argument is 64 bits wide even on 32
bits machines which allows to handle file with a size up to 2^63
bytes.
When the source file is compiled with |
| int ftruncate (int fd, off_t length) | Function |
The ftruncate function is similar to the truncate
function. The main difference is that it takes a descriptor for an
opened file instead of a file name to identify the object. The file
must be opened for writing to successfully carry out the operation.
The POSIX standard leaves it implementation defined what happens if the
specified new length of the file is bigger than the original size.
The When the source file is compiled with On success the function returns zero. Otherwise it returns -1 and set errno to one of these values:
|
| int ftruncate64 (int id, off64_t length) | Function |
This function is similar to the ftruncate function. The
difference is that the length argument is 64 bits wide even on 32
bits machines which allows to handle file with a size up to 2^63
bytes.
When the source file is compiled with |
This section describes the functions for performing primitive input and
output operations on file descriptors: read, write, and
lseek. These functions are declared in the header file
unistd.h.
| ssize_t | Data Type |
This data type is used to represent the sizes of blocks that can be
read or written in a single operation. It is similar to size_t,
but must be a signed type.
|
| ssize_t read (int filedes, void *buffer, size_t size) | Function |
The read function reads up to size bytes from the file
with descriptor filedes, storing the results in the buffer.
(This is not necessarily a character string and there is no terminating
null character added.)
The return value is the number of bytes actually read. This might be less than size; for example, if there aren't that many bytes left in the file or if there aren't that many bytes immediately available. The exact behavior depends on what kind of file it is. Note that reading less than size bytes is not an error. A value of zero indicates end-of-file (except if the value of the
size argument is also zero). This is not considered an error.
If you keep calling If In case of an error,
Please note that there is no function named This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The |
| ssize_t pread (int filedes, void *buffer, size_t size, off_t offset) | Function |
The pread function is similar to the read function. The
first three arguments are identical and also the return values and error
codes correspond.
The difference is the fourth argument and its handling. The data block
is not read from the current position of the file descriptor
When the source file is compiled with The return value of
The function is an extension defined in the Unix Single Specification version 2. |
| ssize_t pread64 (int filedes, void *buffer, size_t size, off64_t offset) | Function |
This function is similar to the pread function. The difference
is that the offset parameter is of type off64_t instead of
off_t which makes it possible on 32 bits machines to address
files larger than 2^31 bytes and up to 2^63 bytes. The
file descriptor filedes must be opened using open64 since
otherwise the large offsets possible with off64_t will lead to
errors with a descriptor in small file mode.
When the source file is compiled with |
| ssize_t write (int filedes, const void *buffer, size_t size) | Function |
The write function writes up to size bytes from
buffer to the file with descriptor filedes. The data in
buffer is not necessarily a character string and a null character is
output like any other character.
The return value is the number of bytes actually written. This may be
size, but can always be smaller. Your program should always call
Once In the case of an error,
Unless you have arranged to prevent nbytes = TEMP_FAILURE_RETRY (write (desc, buffer, count)); Please note that there is no function named This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The |
| ssize_t pwrite (int filedes, const void *buffer, size_t size, off_t offset) | Function |
The pwrite function is similar to the write function. The
first three arguments are identical and also the return values and error
codes correspond.
The difference is the fourth argument and its handling. The data block
is not written to the current position of the file descriptor
When the source file is compiled with The return value of
The function is an extension defined in the Unix Single Specification version 2. |
| ssize_t pwrite64 (int filedes, const void *buffer, size_t size, off64_t offset) | Function |
This function is similar to the pwrite function. The difference
is that the offset parameter is of type off64_t instead of
off_t which makes it possible on 32 bits machines to address
files larger than 2^31 bytes and up to 2^63 bytes. The
file descriptor filedes must be opened using open64 since
otherwise the large offsets possible with off64_t will lead to
errors with a descriptor in small file mode.
When the source file is compiled using |
Just as you can set the file position of a stream with fseek, you
can set the file position of a descriptor with lseek. This
specifies the position in the file for the next read or
write operation. See File Positioning, for more information
on the file position and what it means.
To read the current file position value from a descriptor, use
lseek (desc, 0, SEEK_CUR).
| off_t lseek (int filedes, off_t offset, int whence) | Function |
The lseek function is used to change the file position of the
file with descriptor filedes.
The whence argument specifies how the offset should be
interpreted in the same way as for the
The return value from If you want to append to the file, setting the file position to the
current end of file with You can set the file position past the current end of the file. This
does not by itself make the file longer; If the file position cannot be changed, or the operation is in some way
invalid,
When the source file is compiled with This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The |
| off64_t lseek64 (int filedes, off64_t offset, int whence) | Function |
This function is similar to the lseek function. The difference
is that the offset parameter is of type off64_t instead of
off_t which makes it possible on 32 bits machines to address
files larger than 2^31 bytes and up to 2^63 bytes. The
file descriptor filedes must be opened using open64 since
otherwise the large offsets possible with off64_t will lead to
errors with a descriptor in small file mode.
When the source file is compiled with |
You can have multiple descriptors for the same file if you open the file
more than once, or if you duplicate a descriptor with dup.
Descriptors that come from separate calls to open have independent
file positions; using lseek on one descriptor has no effect on the
other. For example,
{
int d1, d2;
char buf[4];
d1 = open ("foo", O_RDONLY);
d2 = open ("foo", O_RDONLY);
lseek (d1, 1024, SEEK_SET);
read (d2, buf, 4);
}
will read the first four characters of the file foo. (The
error-checking code necessary for a real program has been omitted here
for brevity.)
By contrast, descriptors made by duplication share a common file position with the original descriptor that was duplicated. Anything which alters the file position of one of the duplicates, including reading or writing data, affects all of them alike. Thus, for example,
{
int d1, d2, d3;
char buf1[4], buf2[4];
d1 = open ("foo", O_RDONLY);
d2 = dup (d1);
d3 = dup (d2);
lseek (d3, 1024, SEEK_SET);
read (d1, buf1, 4);
read (d2, buf2, 4);
}
will read four characters starting with the 1024'th character of
foo, and then four more characters starting with the 1028'th
character.
| off_t | Data Type |
This is an arithmetic data type used to represent file sizes.
In the GNU system, this is equivalent to fpos_t or long int.
If the source is compiled with |
| off64_t | Data Type |
This type is used similar to off_t. The difference is that even
on 32 bits machines, where the off_t type would have 32 bits,
off64_t has 64 bits and so is able to address files up to
2^63 bytes in length.
When compiling with |
These aliases for the SEEK_... constants exist for the sake
of compatibility with older BSD systems. They are defined in two
different header files: fcntl.h and sys/file.h.
L_SET
SEEK_SET.
L_INCR
SEEK_CUR.
L_XTND
SEEK_END.
Given an open file descriptor, you can create a stream for it with the
fdopen function. You can get the underlying file descriptor for
an existing stream with the fileno function. These functions are
declared in the header file stdio.h.
| FILE * fdopen (int filedes, const char *opentype) | Function |
The fdopen function returns a new stream for the file descriptor
filedes.
The opentype argument is interpreted in the same way as for the
The return value is the new stream. If the stream cannot be created (for example, if the modes for the file indicated by the file descriptor do not permit the access specified by the opentype argument), a null pointer is returned instead. In some other systems, |
For an example showing the use of the fdopen function,
see Creating a Pipe.
| int fileno (FILE *stream) | Function |
This function returns the file descriptor associated with the stream
stream. If an error is detected (for example, if the stream
is not valid) or if stream does not do I/O to a file,
fileno returns -1.
|
There are also symbolic constants defined in unistd.h for the
file descriptors belonging to the standard streams stdin,
stdout, and stderr; see Standard Streams.
STDIN_FILENO
0, which is the file descriptor for
standard input.
STDOUT_FILENO
1, which is the file descriptor for
standard output.
STDERR_FILENO
2, which is the file descriptor for
standard error output.
You can have multiple file descriptors and streams (let's call both streams and descriptors "channels" for short) connected to the same file, but you must take care to avoid confusion between channels. There are two cases to consider: linked channels that share a single file position value, and independent channels that have their own file positions.
It's best to use just one channel in your program for actual data
transfer to any given file, except when all the access is for input.
For example, if you open a pipe (something you can only do at the file
descriptor level), either do all I/O with the descriptor, or construct a
stream from the descriptor with fdopen and then do all I/O with
the stream.
Channels that come from a single opening share the same file position;
we call them linked channels. Linked channels result when you
make a stream from a descriptor using fdopen, when you get a
descriptor from a stream with fileno, when you copy a descriptor
with dup or dup2, and when descriptors are inherited
during fork. For files that don't support random access, such as
terminals and pipes, all channels are effectively linked. On
random-access files, all append-type output streams are effectively
linked to each other.
If you have been using a stream for I/O, and you want to do I/O using another channel (either a stream or a descriptor) that is linked to it, you must first clean up the stream that you have been using. See Cleaning Streams.
Terminating a process, or executing a new program in the process, destroys all the streams in the process. If descriptors linked to these streams persist in other processes, their file positions become undefined as a result. To prevent this, you must clean up the streams before destroying them.
When you open channels (streams or descriptors) separately on a seekable file, each channel has its own file position. These are called independent channels.
The system handles each channel independently. Most of the time, this is quite predictable and natural (especially for input): each channel can read or write sequentially at its own place in the file. However, if some of the channels are streams, you must take these precautions:
If you do output to one channel at the end of the file, this will certainly leave the other independent channels positioned somewhere before the new end. You cannot reliably set their file positions to the new end of file before writing, because the file can always be extended by another process between when you set the file position and when you write the data. Instead, use an append-type descriptor or stream; they always output at the current end of the file. In order to make the end-of-file position accurate, you must clean the output channel you were using, if it is a stream.
It's impossible for two channels to have separate file pointers for a file that doesn't support random access. Thus, channels for reading or writing such files are always linked, never independent. Append-type channels are also always linked. For these channels, follow the rules for linked channels; see Linked Channels.
On the GNU system, you can clean up any stream with fclean:
| int fclean (FILE *stream) | Function |
| Clean up the stream stream so that its buffer is empty. If stream is doing output, force it out. If stream is doing input, give the data in the buffer back to the system, arranging to reread it. |
On other systems, you can use fflush to clean a stream in most
cases.
You can skip the fclean or fflush if you know the stream
is already clean. A stream is clean whenever its buffer is empty. For
example, an unbuffered stream is always clean. An input stream that is
at end-of-file is clean. A line-buffered stream is clean when the last
character output was a newline.
There is one case in which cleaning a stream is impossible on most
systems. This is when the stream is doing input from a file that is not
random-access. Such streams typically read ahead, and when the file is
not random access, there is no way to give back the excess data already
read. When an input stream reads from a random-access file,
fflush does clean the stream, but leaves the file pointer at an
unpredictable place; you must set the file pointer before doing any
further I/O. On the GNU system, using fclean avoids both of
these problems.
Closing an output-only stream also does fflush, so this is a
valid way of cleaning an output stream. On the GNU system, closing an
input stream does fclean.
You need not clean a stream before using its descriptor for control operations such as setting terminal modes; these operations don't affect the file position and are not affected by it. You can use any descriptor for these operations, and all channels are affected simultaneously. However, text already "output" to a stream but still buffered by the stream will be subject to the new terminal modes when subsequently flushed. To make sure "past" output is covered by the terminal settings that were in effect at the time, flush the output streams for that terminal before setting the modes. See Terminal Modes.
Some applications may need to read or write data to multiple buffers,
which are separated in memory. Although this can be done easily enough
with multiple calls to read and write, it is inefficient
because there is overhead associated with each kernel call.
Instead, many platforms provide special high-speed primitives to perform
these scatter-gather operations in a single kernel call. The GNU C
library will provide an emulation on any system that lacks these
primitives, so they are not a portability threat. They are defined in
sys/uio.h.
These functions are controlled with arrays of iovec structures,
which describe the location and size of each buffer.
| struct iovec | Data Type |
|
The
|
| ssize_t readv (int filedes, const struct iovec *vector, int count) | Function |
|
The Note that The return value is a count of bytes (not buffers) read, 0
indicating end-of-file, or -1 indicating an error. The possible
errors are the same as in |
| ssize_t writev (int filedes, const struct iovec *vector, int count) | Function |
|
The Like The return value is a count of bytes written, or -1 indicating an
error. The possible errors are the same as in |
Note that if the buffers are small (under about 1kB), high-level streams
may be easier to use than these functions. However, readv and
writev are more efficient when the individual buffers themselves
(as opposed to the total output), are large. In that case, a high-level
stream would not be able to cache the data effectively.
On modern operating systems, it is possible to mmap (pronounced "em-map") a file to a region of memory. When this is done, the file can be accessed just like an array in the program.
This is more efficient than read or write, as only regions
of the file a program actually accesses are loaded. Accesses to
not-yet-loaded parts of the mmapped region are handled in the same way as
swapped out pages.
Since mmapped pages can be stored back to their file when physical memory is low, it is possible to mmap files orders of magnitude larger than both the physical memory and swap space. The only limit is address space. The theoretical limit is 4GB on a 32-bit machine - however, the actual limit will be smaller since some areas will be reserved for other purposes.
Memory mapping only works on entire pages of memory. Thus, addresses for mapping must be page-aligned, and length values will be rounded up. To determine the size of a page the machine uses one should use
size_t page_size = (size_t) sysconf (_SC_PAGESIZE);
These functions are declared in sys/mman.h.
| void * mmap (void *address, size_t length,int protect, int flags, int filedes, off_t offset) | Function |
|
The address gives a preferred starting address for the mapping.
protect contains flags that control what kind of access is
permitted. They include Note that most hardware designs cannot support write permission without
read permission, and many do not distinguish read and execute permission.
Thus, you may receive wider permissions than you ask for, and mappings of
write-only files may be denied even if you do not use flags contains flags that control the nature of the map.
One of They include:
Possible errors include:
|
| int munmap (void *addr, size_t length) | Function |
|
It is safe to un-map multiple mappings in one command, or include unmapped space in the range. It is also possible to unmap only part of an existing mapping, however only entire pages can be removed. If length is not an even number of pages, it will be rounded up. It returns 0 for success and -1 for an error. One error is possible:
|
| int msync (void *address, size_t length, int flags) | Function |
|
When using shared mappings, the kernel can write the file at any time before the mapping is removed. To be certain data has actually been written to the file and will be accessible to non-memory-mapped I/O, it is necessary to use this function. It operates on the region address to (address + length). It may be used on part of a mapping or multiple mappings, however the region given should not contain any unmapped space. flags can contain some options:
|
| void * mremap (void *address, size_t length, size_t new_length, int flag) | Function |
|
This function can be used to change the size of an existing memory
area. address and length must cover a region entirely mapped
in the same One option is possible, The address of the resulting mapping is returned, or -1. Possible error codes include: This function is only available on a few systems. Except for performing optional optimizations one should not rely on this function.
|
Not all file descriptors may be mapped. Sockets, pipes, and most devices
only allow sequential access and do not fit into the mapping abstraction.
In addition, some regular files may not be mmapable, and older kernels may
not support mapping at all. Thus, programs using mmap should
have a fallback method to use should it fail. See Mmap.
Sometimes a program needs to accept input on multiple input channels whenever input arrives. For example, some workstations may have devices such as a digitizing tablet, function button box, or dial box that are connected via normal asynchronous serial interfaces; good user interface style requires responding immediately to input on any device. Another example is a program that acts as a server to several other processes via pipes or sockets.
You cannot normally use read for this purpose, because this
blocks the program until input is available on one particular file
descriptor; input on other channels won't wake it up. You could set
nonblocking mode and poll each file descriptor in turn, but this is very
inefficient.
A better solution is to use the select function. This blocks the
program until input or output is ready on a specified set of file
descriptors, or until a timer expires, whichever comes first. This
facility is declared in the header file sys/types.h.
In the case of a server socket (see Listening), we say that
"input" is available when there are pending connections that could be
accepted (see Accepting Connections). accept for server
sockets blocks and interacts with select just as read does
for normal input.
The file descriptor sets for the select function are specified
as fd_set objects. Here is the description of the data type
and some macros for manipulating these objects.
| fd_set | Data Type |
The fd_set data type represents file descriptor sets for the
select function. It is actually a bit array.
|
| int FD_SETSIZE | Macro |
The value of this macro is the maximum number of file descriptors that a
fd_set object can hold information about. On systems with a
fixed maximum number, FD_SETSIZE is at least that number. On
some systems, including GNU, there is no absolute limit on the number of
descriptors open, but this macro still has a constant value which
controls the number of bits in an fd_set; if you get a file
descriptor with a value as high as FD_SETSIZE, you cannot put
that descriptor into an fd_set.
|
| void FD_ZERO (fd_set *set) | Macro |
| This macro initializes the file descriptor set set to be the empty set. |
| void FD_SET (int filedes, fd_set *set) | Macro |
| This macro adds filedes to the file descriptor set set. |
| void FD_CLR (int filedes, fd_set *set) | Macro |
| This macro removes filedes from the file descriptor set set. |
| int FD_ISSET (int filedes, fd_set *set) | Macro |
| This macro returns a nonzero value (true) if filedes is a member of the file descriptor set set, and zero (false) otherwise. |
Next, here is the description of the select function itself.
| int select (int nfds, fd_set *read-fds, fd_set *write-fds, fd_set *except-fds, struct timeval *timeout) | Function |
The select function blocks the calling process until there is
activity on any of the specified sets of file descriptors, or until the
timeout period has expired.
The file descriptors specified by the read-fds argument are checked to see if they are ready for reading; the write-fds file descriptors are checked to see if they are ready for writing; and the except-fds file descriptors are checked for exceptional conditions. You can pass a null pointer for any of these arguments if you are not interested in checking for that kind of condition. A file descriptor is considered ready for reading if it is not at end of
file. A server socket is considered ready for reading if there is a
pending connection which can be accepted with "Exceptional conditions" does not mean errors--errors are reported immediately when an erroneous system call is executed, and do not constitute a state of the descriptor. Rather, they include conditions such as the presence of an urgent message on a socket. (See Sockets, for information on urgent messages.) The The timeout specifies the maximum time to wait. If you pass a
null pointer for this argument, it means to block indefinitely until one
of the file descriptors is ready. Otherwise, you should provide the
time in The normal return value from If Any signal will cause If an error occurs,
|
Portability Note: The select function is a BSD Unix
feature.
Here is an example showing how you can use select to establish a
timeout period for reading from a file descriptor. The input_timeout
function blocks the calling process until input is available on the
file descriptor, or until the timeout period expires.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
int
input_timeout (int filedes, unsigned int seconds)
{
fd_set set;
struct timeval timeout;
/* Initialize the file descriptor set. */
FD_ZERO (&set);
FD_SET (filedes, &set);
/* Initialize the timeout data structure. */
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
/* select returns 0 if timeout, 1 if input available, -1 if error. */
return TEMP_FAILURE_RETRY (select (FD_SETSIZE,
&set, NULL, NULL,
&timeout));
}
int
main (void)
{
fprintf (stderr, "select returned %d.\n",
input_timeout (STDIN_FILENO, 5));
return 0;
}
There is another example showing the use of select to multiplex
input from multiple sockets in Server Example.
In most modern operation systems the normal I/O operations are not
executed synchronously. I.e., even if a write system call
returns this does not mean the data is actually written to the media,
e.g., the disk.
In situations where synchronization points are necessary the user can use special functions which ensure that all operations finished before they return.
| int sync (void) | Function |
|
A call to this function will not return as long as there is data which
that is not written to the device. All dirty buffers in the kernel will
be written and so an overall consistent system can be achieved (if no
other process in parallel writes data).
A prototype for The return value is zero to indicate no error. |
More often it is wanted that not all data in the system is committed.
Programs want to ensure that data written to a given file are all
committed and in this situation sync is overkill.
| int fsync (int fildes) | Function |
The fsync can be used to make sure all data associated with the
open file fildes is written to the device associated with the
descriptor. The function call does not return unless all actions have
finished.
A prototype for This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The return value of the function is zero if no error occurred. Otherwise it is -1 and the global variable errno is set to the following values:
|
Sometimes it is not even necessary to write all data associated with a file descriptor. E.g., in database files which do not change in size it is enough to write all the file content data to the device. Meta-information like the modification time etc. are not that important and leaving such information uncommitted does not prevent a successful recovering of the file in case of a problem.
| int fdatasync (int fildes) | Function |
When a call to the fdatasync function returns it is made sure
that all of the file data is written to the device. For all pending I/O
operations the parts guaranteeing data integrity finished.
Not all systems implement the The prototype for The return value of the function is zero if no error occurred. Otherwise it is -1 and the global variable errno is set to the following values:
|
The POSIX.1b standard defines a new set of I/O operations which can
reduce the time an application spends waiting at I/O significantly. The
new functions allow a program to initiate one or more I/O operations and
then immediately resume the normal work while the I/O operations are
executed in parallel. The functionality is available if the
unistd.h file defines the symbol _POSIX_ASYNCHRONOUS_IO.
These functions are part of the library with realtime functions named
librt. They are not actually part of the libc binary.
The implementation of these functions can be done using support in the
kernel (if available) or using an implementation based on threads at
userlevel. In the latter case it might be necessary to link applications
with the thread library libpthread in addition to librt.
All AIO operations operate on files which were opened previously. There
might be arbitrarily many operations for one file running. The
asynchronous I/O operations are controlled using a data structure named
struct aiocb (AIO control block). It is defined in
aio.h as follows.
| struct aiocb | Data Type |
The POSIX.1b standard mandates that the struct aiocb structure
contains at least the members described in the following table. There
might be more elements which are used by the implementation but
depending on these elements is not portable and is highly deprecated.
When the sources are compiled using |
For use with the AIO functions defined in the LFS there is a similar type
defined which replaces the types of the appropriate members with larger
types but otherwise is equivalent to struct aiocb. Especially
all member names are the same.
| struct aiocb64 | Data Type |
When the sources are compiled using |
| int aio_read (struct aiocb *aiocbp) | Function |
|
This function initiates an asynchronous read operation. The function
call immediately returns after the operation was enqueued or when an
error was encountered.
The first If prioritized I/O is supported by the platform the
The calling process is notified about the termination of the read
request according to the When
In the case
When the sources are compiled with |
| int aio_read64 (struct aiocb *aiocbp) | Function |
This function is similar to the aio_read function. The only
difference is that on 32 bits machines the file descriptor should
be opened in the large file mode. Internally aio_read64 uses
functionality equivalent to lseek64 (see File Position Primitive) to position the file descriptor correctly for the reading,
as opposed to lseek functionality used in aio_read.
When the sources are compiled with |
To write data asynchronously to a file there exists an equivalent pair of functions with a very similar interface.
| int aio_write (struct aiocb *aiocbp) | Function |
|
This function initiates an asynchronous write operation. The function
call immediately returns after the operation was enqueued or if before
this happens an error was encountered.
The first If prioritized I/O is supported by the platform the
The calling process is notified about the termination of the read
request according to the When
In the case
When the sources are compiled with |
| int aio_write64 (struct aiocb *aiocbp) | Function |
This function is similar to the aio_write function. The only
difference is that on 32 bits machines the file descriptor should
be opened in the large file mode. Internally aio_write64 uses
functionality equivalent to lseek64 (see File Position Primitive) to position the file descriptor correctly for the writing,
as opposed to lseek functionality used in aio_write.
When the sources are compiled with |
Beside these functions with the more or less traditional interface
POSIX.1b also defines a function with can initiate more than one
operation at once and which can handled freely mixed read and write
operation. It is therefore similar to a combination of readv and
writev.
| int lio_listio (int mode, struct aiocb *const list[], int nent, struct sigevent *sig) | Function |
The lio_listio function can be used to enqueue an arbitrary
number of read and write requests at one time. The requests can all be
meant for the same file, all for different files or every solution in
between.
The other members of each element of the array pointed to by
The mode argument determines how If mode is In case mode is Possible values for
If the mode parameter is When the sources are compiled with |
| int lio_listio64 (int mode, struct aiocb *const list, int nent, struct sigevent *sig) | Function |
This function is similar to the aio_listio function. The only
difference is that only 32 bits machines the file descriptor should
be opened in the large file mode. Internally lio_listio64 uses
functionality equivalent to lseek64 (see File Position Primitive) to position the file descriptor correctly for the reading or
writing, as opposed to lseek functionality used in
lio_listio.
When the sources are compiled with |
As already described in the documentation of the functions in the last
section it must be possible to get information about the status of a I/O
request. When the operation is performed really asynchronous (as with
aio_read and aio_write and with aio_listio when the
mode is LIO_NOWAIT) one sometimes needs to know whether a
specific request already terminated and if yes, what the result was..
The following two function allow to get this kind of information.
| int aio_error (const struct aiocb *aiocbp) | Function |
This function determines the error state of the request described by the
struct aiocb variable pointed to by aiocbp. If the
request has not yet terminated the value returned is always
EINPROGRESS. Once the request has terminated the value
aio_error returns is either 0 if the request completed
successfully or it returns the value which would be stored in the
errno variable if the request would have been done using
read, write, or fsync.
The function can return When the sources are compiled with |
| int aio_error64 (const struct aiocb64 *aiocbp) | Function |
This function is similar to aio_error with the only difference
that the argument is a reference to a variable of type struct
aiocb64.
When the sources are compiled with |
| ssize_t aio_return (const struct aiocb *aiocbp) | Function |
This function can be used to retrieve the return status of the operation
carried out by the request described in the variable pointed to by
aiocbp. As long as the error status of this request as returned
by aio_error is EINPROGRESS the return of this function is
undefined.
Once the request is finished this function can be used exactly once to
retrieve the return value. Following calls might lead to undefined
behaviour. The return value itself is the value which would have been
returned by the The function can return When the sources are compiled with |
| int aio_return64 (const struct aiocb64 *aiocbp) | Function |
This function is similar to aio_return with the only difference
that the argument is a reference to a variable of type struct
aiocb64.
When the sources are compiled with |
When dealing with asynchronous operations it is sometimes necessary to get into a consistent state. This would mean for AIO that one wants to know whether a certain request or a group of request were processed. This could be done by waiting for the notification sent by the system after the operation terminated but this sometimes would mean wasting resources (mainly computation time). Instead POSIX.1b defines two functions which will help with most kinds of consistency.
The aio_fsync and aio_fsync64 functions are only available
if in unistd.h the symbol _POSIX_SYNCHRONIZED_IO is
defined.
| int aio_fsync (int op, struct aiocb *aiocbp) | Function |
Calling this function forces all I/O operations operating queued at the
time of the function call operating on the file descriptor
aiocbp->aio_fildes into the synchronized I/O completion state
(see Synchronizing I/O). The aio_fsync function return
immediately but the notification through the method described in
aiocbp->aio_sigevent will happen only after all requests for this
file descriptor terminated and the file is synchronized. This also
means that requests for this very same file descriptor which are queued
after the synchronization request are not effected.
If op is As long as the synchronization has not happened a call to
The return value of this function is 0 if the request was
successfully filed. Otherwise the return value is -1 and
When the sources are compiled with |
| int aio_fsync64 (int op, struct aiocb64 *aiocbp) | Function |
This function is similar to aio_fsync with the only difference
that the argument is a reference to a variable of type struct
aiocb64.
When the sources are compiled with |
Another method of synchronization is to wait until one or more requests of a
specific set terminated. This could be achieved by the aio_*
functions to notify the initiating process about the termination but in
some situations this is not the ideal solution. In a program which
constantly updates clients somehow connected to the server it is not
always the best solution to go round robin since some connections might
be slow. On the other hand letting the aio_* function notify the
caller might also be not the best solution since whenever the process
works on preparing data for on client it makes no sense to be
interrupted by a notification since the new client will not be handled
before the current client is served. For situations like this
aio_suspend should be used.
| int aio_suspend (const struct aiocb *const list[], int nent, const struct timespec *timeout) | Function |
When calling this function the calling thread is suspended until at
least one of the requests pointed to by the nent elements of the
array list has completed. If any of the requests already has
completed at the time aio_suspend is called the function returns
immediately. Whether a request has terminated or not is done by
comparing the error status of the request with EINPROGRESS. If
an element of list is NULL the entry is simply ignored.
If no request has finished the calling process is suspended. If
timeout is The return value of the function is 0 if one or more requests
from the list have terminated. Otherwise the function returns
-1 and
When the sources are compiled with |
| int aio_suspend64 (const struct aiocb64 *const list[], int nent, const struct timespec *timeout) | Function |
This function is similar to aio_suspend with the only difference
that the argument is a reference to a variable of type struct
aiocb64.
When the sources are compiled with |
When one or more requests are asynchronously processed it might be useful in some situations to cancel a selected operation, e.g., if it becomes obvious that the written data is not anymore accurate and would have to be overwritten soon. As an example assume an application, which writes data in files in a situation where new incoming data would have to be written in a file which will be updated by an enqueued request. The POSIX AIO implementation provides such a function but this function is not capable to force the cancelation of the request. It is up to the implementation to decide whether it is possible to cancel the operation or not. Therefore using this function is merely a hint.
| int aio_cancel (int fildes, struct aiocb *aiocbp) | Function |
The aio_cancel function can be used to cancel one or more
outstanding requests. If the aiocbp parameter is NULL the
function tries to cancel all outstanding requests which would process
the file descriptor fildes (i.e.,, whose aio_fildes member
is fildes). If aiocbp is not NULL the very specific
request pointed to by aiocbp is tried to be canceled.
For requests which were successfully canceled the normal notification
about the termination of the request should take place. I.e., depending
on the After a request is successfully canceled a call to The return value of the function is If an error occurred during the execution of
When the sources are compiled with |
| int aio_cancel64 (int fildes, struct aiocb *aiocbp) | Function |
This function is similar to aio_cancel with the only difference
that the argument is a reference to a variable of type struct
aiocb64.
When the sources are compiled with |
The POSIX standard does not specify how the AIO functions are implemented. They could be system calls but it is also possible to emulate them at userlevel.
At least the available implementation at the point of this writing is a userlevel implementation which uses threads for handling the enqueued requests. This implementation requires to make some decisions about limitations but hard limitations are something which better should be avoided the GNU C library implementation provides a mean to tune the AIO implementation individually for each use.
| struct aioinit | Data Type |
This data type is used to pass the configuration or tunable parameters
to the implementation. The program has to initialize the members of
this struct and pass it to the implementation using the aio_init
function.
|
| void aio_init (const struct aioinit *init) | Function |
|
This function must be called before any other AIO function. Calling it
is completely voluntarily since it only is meant to help the AIO
implementation to perform better.
Before calling the The function has no return value and no error cases are defined. It is a extension which follows a proposal from the SGI implementation in Irix 6. It is not covered by POSIX.1b or Unix98. |
This section describes how you can perform various other operations on
file descriptors, such as inquiring about or setting flags describing
the status of the file descriptor, manipulating record locks, and the
like. All of these operations are performed by the function fcntl.
The second argument to the fcntl function is a command that
specifies which operation to perform. The function and macros that name
various flags that are used with it are declared in the header file
fcntl.h. Many of these flags are also used by the open
function; see Opening and Closing Files.
| int fcntl (int filedes, int command, ...) | Function |
The fcntl function performs the operation specified by
command on the file descriptor filedes. Some commands
require additional arguments to be supplied. These additional arguments
and the return value and error conditions are given in the detailed
descriptions of the individual commands.
Briefly, here is a list of what the various commands are.
This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time |
You can duplicate a file descriptor, or allocate another file descriptor that refers to the same open file as the original. Duplicate descriptors share one file position and one set of file status flags (see File Status Flags), but each has its own set of file descriptor flags (see Descriptor Flags).
The major use of duplicating a file descriptor is to implement redirection of input or output: that is, to change the file or pipe that a particular file descriptor corresponds to.
You can perform this operation using the fcntl function with the
F_DUPFD command, but there are also convenient functions
dup and dup2 for duplicating descriptors.
The fcntl function and flags are declared in fcntl.h,
while prototypes for dup and dup2 are in the header file
unistd.h.
| int dup (int old) | Function |
This function copies descriptor old to the first available
descriptor number (the first number not currently open). It is
equivalent to fcntl (old, F_DUPFD, 0).
|
| int dup2 (int old, int new) | Function |
|
This function copies the descriptor old to descriptor number
new.
If old is an invalid descriptor, then If old and new are different numbers, and old is a
valid descriptor number, then close (new); fcntl (old, F_DUPFD, new) However, |
| int F_DUPFD | Macro |
This macro is used as the command argument to fcntl, to
copy the file descriptor given as the first argument.
The form of the call in this case is: fcntl (old, F_DUPFD, next-filedes) The next-filedes argument is of type The return value from
|
Here is an example showing how to use dup2 to do redirection.
Typically, redirection of the standard streams (like stdin) is
done by a shell or shell-like program before calling one of the
exec functions (see Executing a File) to execute a new
program in a child process. When the new program is executed, it
creates and initializes the standard streams to point to the
corresponding file descriptors, before its main function is
invoked.
So, to redirect standard input to a file, the shell could do something like:
pid = fork ();
if (pid == 0)
{
char *filename;
char *program;
int file;
...
file = TEMP_FAILURE_RETRY (open (filename, O_RDONLY));
dup2 (file, STDIN_FILENO);
TEMP_FAILURE_RETRY (close (file));
execv (program, NULL);
}
There is also a more detailed example showing how to implement redirection in the context of a pipeline of processes in Launching Jobs.
File descriptor flags are miscellaneous attributes of a file descriptor. These flags are associated with particular file descriptors, so that if you have created duplicate file descriptors from a single opening of a file, each descriptor has its own set of flags.
Currently there is just one file descriptor flag: FD_CLOEXEC,
which causes the descriptor to be closed if you use any of the
exec... functions (see Executing a File).
The symbols in this section are defined in the header file
fcntl.h.
| int F_GETFD | Macro |
This macro is used as the command argument to fcntl, to
specify that it should return the file descriptor flags associated
with the filedes argument.
The normal return value from In case of an error,
|
| int F_SETFD | Macro |
This macro is used as the command argument to fcntl, to
specify that it should set the file descriptor flags associated with the
filedes argument. This requires a third int argument to
specify the new flags, so the form of the call is:
fcntl (filedes, F_SETFD, new-flags) The normal return value from |
The following macro is defined for use as a file descriptor flag with
the fcntl function. The value is an integer constant usable
as a bit mask value.
| int FD_CLOEXEC | Macro |
This flag specifies that the file descriptor should be closed when
an exec function is invoked; see Executing a File. When
a file descriptor is allocated (as with open or dup),
this bit is initially cleared on the new file descriptor, meaning that
descriptor will survive into the new program after exec.
|
If you want to modify the file descriptor flags, you should get the
current flags with F_GETFD and modify the value. Don't assume
that the flags listed here are the only ones that are implemented; your
program may be run years from now and more flags may exist then. For
example, here is a function to set or clear the flag FD_CLOEXEC
without altering any other flags:
/* Set theFD_CLOEXECflag of desc if value is nonzero, or clear the flag if value is 0. Return 0 on success, or -1 on error witherrnoset. */ int set_cloexec_flag (int desc, int value) { int oldflags = fcntl (desc, F_GETFD, 0); /* If reading the flags failed, return error indication now. if (oldflags < 0) return oldflags; /* Set just the flag we want to set. */ if (value != 0) oldflags |= FD_CLOEXEC; else oldflags &= ~FD_CLOEXEC; /* Store modified flag word in the descriptor. */ return fcntl (desc, F_SETFD, oldflags); }
File status flags are used to specify attributes of the opening of a
file. Unlike the file descriptor flags discussed in Descriptor Flags, the file status flags are shared by duplicated file descriptors
resulting from a single opening of the file. The file status flags are
specified with the flags argument to open;
see Opening and Closing Files.
File status flags fall into three categories, which are described in the following sections.
open and are
returned by fcntl, but cannot be changed.
open will do.
These flags are not preserved after the open call.
read and
write are done. They are set by open, and can be fetched or
changed with fcntl.
The symbols in this section are defined in the header file
fcntl.h.
open.
The file access modes allow a file descriptor to be used for reading, writing, or both. (In the GNU system, they can also allow none of these, and allow execution of the file as a program.) The access modes are chosen when the file is opened, and never change.
| int O_RDONLY | Macro |
| Open the file for read access. |
| int O_WRONLY | Macro |
| Open the file for write access. |
| int O_RDWR | Macro |
| Open the file for both reading and writing. |
In the GNU system (and not in other systems), O_RDONLY and
O_WRONLY are independent bits that can be bitwise-ORed together,
and it is valid for either bit to be set or clear. This means that
O_RDWR is the same as O_RDONLY|O_WRONLY. A file access
mode of zero is permissible; it allows no operations that do input or
output to the file, but does allow other operations such as
fchmod. On the GNU system, since "read-only" or "write-only"
is a misnomer, fcntl.h defines additional names for the file
access modes. These names are preferred when writing GNU-specific code.
But most programs will want to be portable to other POSIX.1 systems and
should use the POSIX.1 names above instead.
| int O_READ | Macro |
Open the file for reading. Same as O_RDWR; only defined on GNU.
|
| int O_WRITE | Macro |
Open the file for reading. Same as O_WRONLY; only defined on GNU.
|
| int O_EXEC | Macro |
| Open the file for executing. Only defined on GNU. |
To determine the file access mode with fcntl, you must extract
the access mode bits from the retrieved file status flags. In the GNU
system, you can just test the O_READ and O_WRITE bits in
the flags word. But in other POSIX.1 systems, reading and writing
access modes are not stored as distinct bit flags. The portable way to
extract the file access mode bits is with O_ACCMODE.
| int O_ACCMODE | Macro |
This macro stands for a mask that can be bitwise-ANDed with the file
status flag value to produce a value representing the file access mode.
The mode will be O_RDONLY, O_WRONLY, or O_RDWR.
(In the GNU system it could also be zero, and it never includes the
O_EXEC bit.)
|
The open-time flags specify options affecting how open will behave.
These options are not preserved once the file is open. The exception to
this is O_NONBLOCK, which is also an I/O operating mode and so it
is saved. See Opening and Closing Files, for how to call
open.
There are two sorts of options specified by open-time flags.
open looks up the
file name to locate the file, and whether the file can be created.
open will
perform on the file once it is open.
Here are the file name translation flags.
| int O_CREAT | Macro |
| If set, the file will be created if it doesn't already exist. |
| int O_EXCL | Macro |
If both O_CREAT and O_EXCL are set, then open fails
if the specified file already exists. This is guaranteed to never
clobber an existing file.
|
| int O_NONBLOCK | Macro |
This prevents open from blocking for a "long time" to open the
file. This is only meaningful for some kinds of files, usually devices
such as serial ports; when it is not meaningful, it is harmless and
ignored. Often opening a port to a modem blocks until the modem reports
carrier detection; if O_NONBLOCK is specified, open will
return immediately without a carrier.
Note that the |
| int O_NOCTTY | Macro |
|
If the named file is a terminal device, don't make it the controlling
terminal for the process. See Job Control, for information about
what it means to be the controlling terminal.
In the GNU system and 4.4 BSD, opening a file never makes it the
controlling terminal and |
The following three file name translation flags exist only in the GNU system.
| int O_IGNORE_CTTY | Macro |
| Do not recognize the named file as the controlling terminal, even if it refers to the process's existing controlling terminal device. Operations on the new file descriptor will never induce job control signals. See Job Control. |
| int O_NOLINK | Macro |
If the named file is a symbolic link, open the link itself instead of
the file it refers to. (fstat on the new file descriptor will
return the information returned by lstat on the link's name.)
|
| int O_NOTRANS | Macro |
| If the named file is specially translated, do not invoke the translator. Open the bare file the translator itself sees. |
The open-time action flags tell open to do additional operations
which are not really related to opening the file. The reason to do them
as part of open instead of in separate calls is that open
can do them atomically.
| int O_TRUNC | Macro |
Truncate the file to zero length. This option is only useful for
regular files, not special files such as directories or FIFOs. POSIX.1
requires that you open the file for writing to use O_TRUNC. In
BSD and GNU you must have permission to write the file to truncate it,
but you need not open for write access.
This is the only open-time action flag specified by POSIX.1. There is
no good reason for truncation to be done by |
The remaining operating modes are BSD extensions. They exist only on some systems. On other systems, these macros are not defined.
| int O_SHLOCK | Macro |
Acquire a shared lock on the file, as with flock.
See File Locks.
If |
| int O_EXLOCK | Macro |
Acquire an exclusive lock on the file, as with flock.
See File Locks. This is atomic like O_SHLOCK.
|
The operating modes affect how input and output operations using a file
descriptor work. These flags are set by open and can be fetched
and changed with fcntl.
| int O_APPEND | Macro |
The bit that enables append mode for the file. If set, then all
write operations write the data at the end of the file, extending
it, regardless of the current file position. This is the only reliable
way to append to a file. In append mode, you are guaranteed that the
data you write will always go to the current end of the file, regardless
of other processes writing to the file. Conversely, if you simply set
the file position to the end of file and write, then another process can
extend the file after you set the file position but before you write,
resulting in your data appearing someplace before the real end of file.
|
| int O_NONBLOCK | Macro |
The bit that enables nonblocking mode for the file. If this bit is set,
read requests on the file can return immediately with a failure
status if there is no input immediately available, instead of blocking.
Likewise, write requests can also return immediately with a
failure status if the output can't be written immediately.
Note that the |
| int O_NDELAY | Macro |
This is an obsolete name for O_NONBLOCK, provided for
compatibility with BSD. It is not defined by the POSIX.1 standard.
|
The remaining operating modes are BSD and GNU extensions. They exist only on some systems. On other systems, these macros are not defined.
| int O_ASYNC | Macro |
The bit that enables asynchronous input mode. If set, then SIGIO
signals will be generated when input is available. See Interrupt Input.
Asynchronous input mode is a BSD feature. |
| int O_FSYNC | Macro |
The bit that enables synchronous writing for the file. If set, each
write call will make sure the data is reliably stored on disk before
returning.
Synchronous writing is a BSD feature.
|
| int O_SYNC | Macro |
This is another name for O_FSYNC. They have the same value.
|
| int O_NOATIME | Macro |
If this bit is set, read will not update the access time of the
file. See File Times. This is used by programs that do backups, so
that backing a file up does not count as reading it.
Only the owner of the file or the superuser may use this bit.
This is a GNU extension. |
The fcntl function can fetch or change file status flags.
| int F_GETFL | Macro |
This macro is used as the command argument to fcntl, to
read the file status flags for the open file with descriptor
filedes.
The normal return value from In case of an error,
|
| int F_SETFL | Macro |
This macro is used as the command argument to fcntl, to set
the file status flags for the open file corresponding to the
filedes argument. This command requires a third int
argument to specify the new flags, so the call looks like this:
fcntl (filedes, F_SETFL, new-flags) You can't change the access mode for the file in this way; that is, whether the file descriptor was opened for reading or writing. The normal return value from |
If you want to modify the file status flags, you should get the current
flags with F_GETFL and modify the value. Don't assume that the
flags listed here are the only ones that are implemented; your program
may be run years from now and more flags may exist then. For example,
here is a function to set or clear the flag O_NONBLOCK without
altering any other flags:
/* Set theO_NONBLOCKflag of desc if value is nonzero, or clear the flag if value is 0. Return 0 on success, or -1 on error witherrnoset. */ int set_nonblock_flag (int desc, int value) { int oldflags = fcntl (desc, F_GETFL, 0); /* If reading the flags failed, return error indication now. */ if (oldflags == -1) return -1; /* Set just the flag we want to set. */ if (value != 0) oldflags |= O_NONBLOCK; else oldflags &= ~O_NONBLOCK; /* Store modified flag word in the descriptor. */ return fcntl (desc, F_SETFL, oldflags); }
The remaining fcntl commands are used to support record
locking, which permits multiple cooperating programs to prevent each
other from simultaneously accessing parts of a file in error-prone
ways.
An exclusive or write lock gives a process exclusive access for writing to the specified part of the file. While a write lock is in place, no other process can lock that part of the file.
A shared or read lock prohibits any other process from requesting a write lock on the specified part of the file. However, other processes can request read locks.
The read and write functions do not actually check to see
whether there are any locks in place. If you want to implement a
locking protocol for a file shared by multiple processes, your application
must do explicit fcntl calls to request and clear locks at the
appropriate points.
Locks are associated with processes. A process can only have one kind
of lock set for each byte of a given file. When any file descriptor for
that file is closed by the process, all of the locks that process holds
on that file are released, even if the locks were made using other
descriptors that remain open. Likewise, locks are released when a
process exits, and are not inherited by child processes created using
fork (see Creating a Process).
When making a lock, use a struct flock to specify what kind of
lock and where. This data type and the associated macros for the
fcntl function are declared in the header file fcntl.h.
| struct flock | Data Type |
This structure is used with the fcntl function to describe a file
lock. It has these members:
|
| int F_GETLK | Macro |
This macro is used as the command argument to fcntl, to
specify that it should get information about a lock. This command
requires a third argument of type struct flock * to be passed
to fcntl, so that the form of the call is:
fcntl (filedes, F_GETLK, lockp) If there is a lock already in place that would block the lock described
by the lockp argument, information about that lock overwrites
There might be more than one lock affecting the region specified by the
lockp argument, but If no lock applies, the only change to the lockp structure is to
update the The normal return value from
|
| int F_SETLK | Macro |
This macro is used as the command argument to fcntl, to
specify that it should set or clear a lock. This command requires a
third argument of type struct flock * to be passed to
fcntl, so that the form of the call is:
fcntl (filedes, F_SETLK, lockp) If the process already has a lock on any part of the region, the old lock
on that part is replaced with the new lock. You can remove a lock
by specifying a lock type of If the lock cannot be set, The following
|
| int F_SETLKW | Macro |
This macro is used as the command argument to fcntl, to
specify that it should set or clear a lock. It is just like the
F_SETLK command, but causes the process to block (or wait)
until the request can be specified.
This command requires a third argument of type The
|
The following macros are defined for use as values for the l_type
member of the flock structure. The values are integer constants.
F_RDLCK
F_WRLCK
F_UNLCK
As an example of a situation where file locking is useful, consider a program that can be run simultaneously by several different users, that logs status information to a common file. One example of such a program might be a game that uses a file to keep track of high scores. Another example might be a program that records usage or accounting information for billing purposes.
Having multiple copies of the program simultaneously writing to the file could cause the contents of the file to become mixed up. But you can prevent this kind of problem by setting a write lock on the file before actually writing to the file.
If the program also needs to read the file and wants to make sure that the contents of the file are in a consistent state, then it can also use a read lock. While the read lock is set, no other process can lock that part of the file for writing.
Remember that file locks are only a voluntary protocol for controlling access to a file. There is still potential for access to the file by programs that don't use the lock protocol.
If you set the O_ASYNC status flag on a file descriptor
(see File Status Flags), a SIGIO signal is sent whenever
input or output becomes possible on that file descriptor. The process
or process group to receive the signal can be selected by using the
F_SETOWN command to the fcntl function. If the file
descriptor is a socket, this also selects the recipient of SIGURG
signals that are delivered when out-of-band data arrives on that socket;
see Out-of-Band Data. (SIGURG is sent in any situation
where select would report the socket as having an "exceptional
condition". See Waiting for I/O.)
If the file descriptor corresponds to a terminal device, then SIGIO
signals are sent to the foreground process group of the terminal.
See Job Control.
The symbols in this section are defined in the header file
fcntl.h.
| int F_GETOWN | Macro |
This macro is used as the command argument to fcntl, to
specify that it should get information about the process or process
group to which SIGIO signals are sent. (For a terminal, this is
actually the foreground process group ID, which you can get using
tcgetpgrp; see Terminal Access Functions.)
The return value is interpreted as a process ID; if negative, its absolute value is the process group ID. The following
|
| int F_SETOWN | Macro |
This macro is used as the command argument to fcntl, to
specify that it should set the process or process group to which
SIGIO signals are sent. This command requires a third argument
of type pid_t to be passed to fcntl, so that the form of
the call is:
fcntl (filedes, F_SETOWN, pid) The pid argument should be a process ID. You can also pass a negative number whose absolute value is a process group ID. The return value from
|
The GNU system can handle most input/output operations on many different
devices and objects in terms of a few file primitives - read,
write and lseek. However, most devices also have a few
peculiar operations which do not fit into this model. Such as:
lseek is inapplicable).
Although some such objects such as sockets and terminals 1 have special functions of their own, it would not be practical to create functions for all these cases.
Instead these minor operations, known as IOCTLs, are assigned code
numbers and multiplexed through the ioctl function, defined in
sys/ioctl.h. The code numbers themselves are defined in many
different headers.
| int ioctl (int filedes, int command, ...) | Function |
|
The A third argument is usually present, either a single number or a pointer to a structure. The meaning of this argument, the returned value, and any error codes depends upon the command used. Often -1 is returned for a failure. |
On some systems, IOCTLs used by different devices share the same numbers. Thus, although use of an inappropriate IOCTL usually only produces an error, you should not attempt to use device-specific IOCTLs on an unknown device.
Most IOCTLs are OS-specific and/or only used in special system utilities, and are thus beyond the scope of this document. For an example of the use of an IOCTL, see Out-of-Band Data.
This chapter describes the GNU C library's functions for manipulating files. Unlike the input and output functions (see I/O on Streams; see Low-Level I/O), these functions are concerned with operating on the files themselves, rather than on their contents.
Among the facilities described in this chapter are functions for examining or modifying directories, functions for renaming and deleting files, and functions for examining and setting file attributes such as access permissions and modification times.
Each process has associated with it a directory, called its current working directory or simply working directory, that is used in the resolution of relative file names (see File Name Resolution).
When you log in and begin a new session, your working directory is
initially set to the home directory associated with your login account
in the system user database. You can find any user's home directory
using the getpwuid or getpwnam functions; see User Database.
Users can change the working directory using shell commands like
cd. The functions described in this section are the primitives
used by those commands and by other programs for examining and changing
the working directory.
Prototypes for these functions are declared in the header file
unistd.h.
| char * getcwd (char *buffer, size_t size) | Function |
The getcwd function returns an absolute file name representing
the current working directory, storing it in the character array
buffer that you provide. The size argument is how you tell
the system the allocation size of buffer.
The GNU library version of this function also permits you to specify a
null pointer for the buffer argument. Then The return value is buffer on success and a null pointer on failure.
The following
|
You could implement the behavior of GNU's getcwd (NULL, 0)
using only the standard behavior of getcwd:
char *
gnu_getcwd ()
{
int size = 100;
char *buffer = (char *) xmalloc (size);
while (1)
{
char *value = getcwd (buffer, size);
if (value != 0)
return buffer;
size *= 2;
free (buffer);
buffer = (char *) xmalloc (size);
}
}
See Malloc Examples, for information about xmalloc, which is
not a library function but is a customary name used in most GNU
software.
| char * getwd (char *buffer) | Function |
This is similar to getcwd, but has no way to specify the size of
the buffer. The GNU library provides getwd only
for backwards compatibility with BSD.
The buffer argument should be a pointer to an array at least
|
| int chdir (const char *filename) | Function |
|
This function is used to set the process's working directory to
filename.
The normal, successful return value from |
The facilities described in this section let you read the contents of a directory file. This is useful if you want your program to list all the files in a directory, perhaps as part of a menu.
The opendir function opens a directory stream whose
elements are directory entries. You use the readdir function on
the directory stream to retrieve these entries, represented as
struct dirent objects. The name of the file for each entry is
stored in the d_name member of this structure. There are obvious
parallels here to the stream facilities for ordinary files, described in
I/O on Streams.
This section describes what you find in a single directory entry, as you
might obtain it from a directory stream. All the symbols are declared
in the header file dirent.h.
| struct dirent | Data Type |
This is a structure type used to return information about directory
entries. It contains the following fields:
This structure may contain additional members in the future. When a file has multiple names, each name has its own directory entry.
The only way you can tell that the directory entries belong to a
single file is that they have the same value for the File attributes such as size, modification times, and the like are part of the file itself, not any particular directory entry. See File Attributes. |
This section describes how to open a directory stream. All the symbols
are declared in the header file dirent.h.
| DIR | Data Type |
The DIR data type represents a directory stream.
|
You shouldn't ever allocate objects of the struct dirent or
DIR data types, since the directory access functions do that for
you. Instead, you refer to these objects using the pointers returned by
the following functions.
| DIR * opendir (const char *dirname) | Function |
The opendir function opens and returns a directory stream for
reading the directory whose file name is dirname. The stream has
type DIR *.
If unsuccessful,
The |
This section describes how to read directory entries from a directory
stream, and how to close the stream when you are done with it. All the
symbols are declared in the header file dirent.h.
| struct dirent * readdir (DIR *dirstream) | Function |
|
This function reads the next entry from the directory. It normally
returns a pointer to a structure containing information about the file.
This structure is statically allocated and can be rewritten by a
subsequent call.
Portability Note: On some systems, If there are no more entries in the directory or an error is detected,
|
| int readdir_r (DIR *dirstream, struct dirent *entry, struct dirent **result) | Function |
This function is the reentrant version of readdir. Like
readdir it returns the next entry from the directory. But to
prevent conflicts for simultaneously running threads the result is not
stored in some internal memory. Instead the argument entry has to
point to a place where the result is stored.
The return value is If there are no more directory entries, Portability Note: On some systems, |
| int closedir (DIR *dirstream) | Function |
This function closes the directory stream dirstream. It returns
0 on success and -1 on failure.
The following
|
Here's a simple program that prints the names of the files in the current working directory:
#include <stddef.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int
main (void)
{
DIR *dp;
struct dirent *ep;
dp = opendir ("./");
if (dp != NULL)
{
while (ep = readdir (dp))
puts (ep->d_name);
(void) closedir (dp);
}
else
puts ("Couldn't open the directory.");
return 0;
}
The order in which files appear in a directory tends to be fairly random. A more useful program would sort the entries (perhaps by alphabetizing them) before printing them; see Scanning Directory Content, and Array Sort Function.
This section describes how to reread parts of a directory that you have
already read from an open directory stream. All the symbols are
declared in the header file dirent.h.
| void rewinddir (DIR *dirstream) | Function |
The rewinddir function is used to reinitialize the directory
stream dirstream, so that if you call readdir it
returns information about the first entry in the directory again. This
function also notices if files have been added or removed to the
directory since it was opened with opendir. (Entries for these
files might or might not be returned by readdir if they were
added or removed since you last called opendir or
rewinddir.)
|
| off_t telldir (DIR *dirstream) | Function |
The telldir function returns the file position of the directory
stream dirstream. You can use this value with seekdir to
restore the directory stream to that position.
|
| void seekdir (DIR *dirstream, off_t pos) | Function |
The seekdir function sets the file position of the directory
stream dirstream to pos. The value pos must be the
result of a previous call to telldir on this particular stream;
closing and reopening the directory can invalidate values returned by
telldir.
|
A higher-level interface to the directory handling functions is the
scandir function. With its help one can select a subset of the
entries in a directory, possibly sort them and get as the result a list
of names.
| int scandir (const char *dir, struct dirent ***namelist, int (*selector) (const struct dirent *), int (*cmp) (const void *, const void *)) | Function |
|
The Finally the entries in the namelist are sorted using the user
supplied function cmp. The arguments of the cmp function
are of type The return value of the function gives the number of entries placed in
namelist. If it is |
As said above the fourth argument to the scandir function must be
a pointer to a sorting function. For the convenience of the programmer
the GNU C library contains implementations of functions which are very
helpful for this purpose.
| int alphasort (const void *a, const void *b) | Function |
The alphasort function behaves like the strcoll function
(see String/Array Comparison). The difference is that the arguments
are not string pointers but instead they are of type
struct dirent **.
Return value of |
| int versionsort (const void *a, const void *b) | Function |
The versionsort function is like alphasort, excepted that it
uses the strverscmp function internally.
|
If the filesystem supports large files we cannot use the scandir
anymore since the dirent structure might not able to contain all
the information. The LFS provides the new type struct dirent64. To use this we need a new function.
| int scandir64 (const char *dir, struct dirent64 ***namelist, int (*selector) (const struct dirent64 *), int (*cmp) (const void *, const void *)) | Function |
The scandir64 function works like the scandir function
only that the directory entries it returns are described by elements of
type struct dirent64. The function pointed to by
selector is again used to select the wanted entries only that
selector now must point to a function which takes a
struct dirent64 * parameter.
The cmp now must be a function which expects its two arguments to
be of type |
As just said the function expected as the fourth is different from the
function expected in scandir. Therefore we cannot use the
alphasort and versionsort functions anymore. Instead we
have two similar functions available.
| int alphasort64 (const void *a, const void *b) | Function |
The alphasort64 function behaves like the strcoll function
(see String/Array Comparison). The difference is that the arguments
are not string pointers but instead they are of type
struct dirent64 **.
Return value of |
| int versionsort64 (const void *a, const void *b) | Function |
The versionsort64 function is like alphasort64, excepted that it
uses the strverscmp function internally.
|
It is important not to mix the use of scandir and the 64 bits
comparison functions or vice versa. There are systems on which this
works but on others it will fail miserably.
Here is a revised version of the directory lister found above
(see Simple Directory Lister). Using the scandir function we
can avoid using the functions which directly work with the directory
contents. After the call the found entries are available for direct
used.
#include <stdio.h>
#include <dirent.h>
static int
one (struct dirent *unused)
{
return 1;
}
int
main (void)
{
struct dirent **eps;
int n;
n = scandir ("./", &eps, one, alphasort);
if (n >= 0)
{
int cnt;
for (cnt = 0; cnt < n; ++cnt)
puts (eps[cnt]->d_name);
}
else
perror ("Couldn't open the directory");
return 0;
}
Please note the simple selector function for this example. Since
we want to see all directory entries we always return 1.
The functions to handle files in directories described so far allowed to
retrieve all the information in small pieces or process all files in a
directory (see scandir). Sometimes it is useful to process whole
hierarchies of directories and the contained files. The X/Open
specification define two functions to do this. The simpler form is
derived from an early definition in System V systems and therefore
this function is available on SVID derived systems. The prototypes and
required definitions can be found in the ftw.h header.
Both functions of this ftw family take as one of the arguments a
reference to a callback function. The functions must be of these types.
| __ftw_func_t | Data Type |
int (*) (const char *, const struct stat *, int) Type for callback functions given to the The last parameter is a flag given more information about the current file. It can have the following values:
If the sources are compiled with |
For the LFS interface and the use in the function ftw64 the
header ftw.h defines another function type.
| __ftw64_func_t | Data Type |
int (*) (const char *, const struct stat64 *, int) This type is used just like |
| __nftw_func_t | Data Type |
int (*) (const char *, const struct stat *, int, struct FTW *) The first three arguments have the same as for the
The last parameter of the callback function is a pointer to a structure with some extra information as described below. If the sources are compiled with |
For the LFS interface there is also a variant of this data type
available which has to be used with the nftw64 function.
| __nftw64_func_t | Data Type |
int (*) (const char *, const struct stat64 *, int, struct FTW *) This type is used just like |
| struct FTW | Data Type |
The contained information helps to interpret the name parameter and
gives some information about current state of the traversal of the
directory hierarchy.
|
| int ftw (const char *filename, __ftw_func_t func, int descriptors) | Function |
The ftw function calls the callback function given in the
parameter func for every item which is found in the directory
specified by filename and all directories below. The function
follows symbolic links if necessary but does not process an item twice.
If filename names no directory this item is the only object
reported by calling the callback function.
The filename given to the callback function is constructed by taking the
filename parameter and appending the names of all passed
directories and then the local file name. So the callback function can
use this parameter to access the file. Before the callback function is
called The callback function is expected to return 0 to indicate that no
error occurred and the processing should be continued. If an error
occurred in the callback function or the call to The descriptors parameter to the The return value of the When the sources are compiled with |
| int ftw64 (const char *filename, __ftw64_func_t func, int descriptors) | Function |
This function is similar to ftw but it can work on filesystems
with large files since the information about the files is reported using
a variable of type struct stat64 which is passed by reference to
the callback function.
When the sources are compiled with |
| int nftw (const char *filename, __nftw_func_t func, int descriptors, int flag) | Function |
The nftw functions works like the ftw functions. It calls
the callback function func for all items it finds in the directory
filename and below. At most descriptors file descriptors
are consumed during the nftw call.
The differences are that for one the callback function is of a different
type. It is of type The second difference is that
The return value is computed in the same way as for When the sources are compiled with |
| int nftw64 (const char *filename, __nftw64_func_t func, int descriptors, int flag) | Function |
This function is similar to nftw but it can work on filesystems
with large files since the information about the files is reported using
a variable of type struct stat64 which is passed by reference to
the callback function.
When the sources are compiled with |
In POSIX systems, one file can have many names at the same time. All of the names are equally real, and no one of them is preferred to the others.
To add a name to a file, use the link function. (The new name is
also called a hard link to the file.) Creating a new link to a
file does not copy the contents of the file; it simply makes a new name
by which the file can be known, in addition to the file's existing name
or names.
One file can have names in several directories, so the organization of the file system is not a strict hierarchy or tree.
In most implementations, it is not possible to have hard links to the
same file in multiple file systems. link reports an error if you
try to make a hard link to the file from another file system when this
cannot be done.
The prototype for the link function is declared in the header
file unistd.h.
| int link (const char *oldname, const char *newname) | Function |
The link function makes a new link to the existing file named by
oldname, under the new name newname.
This function returns a value of
|
The GNU system supports soft links or symbolic links. This is a kind of "file" that is essentially a pointer to another file name. Unlike hard links, symbolic links can be made to directories or across file systems with no restrictions. You can also make a symbolic link to a name which is not the name of any file. (Opening this link will fail until a file by that name is created.) Likewise, if the symbolic link points to an existing file which is later deleted, the symbolic link continues to point to the same file name even though the name no longer names any file.
The reason symbolic links work the way they do is that special things
happen when you try to open the link. The open function realizes
you have specified the name of a link, reads the file name contained in
the link, and opens that file name instead. The stat function
likewise operates on the file that the symbolic link points to, instead
of on the link itself.
By contrast, other operations such as deleting or renaming the file
operate on the link itself. The functions readlink and
lstat also refrain from following symbolic links, because their
purpose is to obtain information about the link. So does link,
the function that makes a hard link--it makes a hard link to the
symbolic link, which one rarely wants.
Prototypes for the functions listed in this section are in
unistd.h.
| int symlink (const char *oldname, const char *newname) | Function |
The symlink function makes a symbolic link to oldname named
newname.
The normal return value from
|
| int readlink (const char *filename, char *buffer, size_t size) | Function |
The readlink function gets the value of the symbolic link
filename. The file name that the link points to is copied into
buffer. This file name string is not null-terminated;
readlink normally returns the number of characters copied. The
size argument specifies the maximum number of characters to copy,
usually the allocation size of buffer.
If the return value equals size, you cannot tell whether or not
there was room to return the entire name. So make a bigger buffer and
call char *
readlink_malloc (char *filename)
{
int size = 100;
while (1)
{
char *buffer = (char *) xmalloc (size);
int nchars = readlink (filename, buffer, size);
if (nchars < size)
return buffer;
free (buffer);
size *= 2;
}
}
A value of
|
You can delete a file with the functions unlink or remove.
Deletion actually deletes a file name. If this is the file's only name, then the file is deleted as well. If the file has other names as well (see Hard Links), it remains accessible under its other names.
| int unlink (const char *filename) | Function |
The unlink function deletes the file name filename. If
this is a file's sole name, the file itself is also deleted. (Actually,
if any process has the file open when this happens, deletion is
postponed until all processes have closed the file.)
The function This function returns
|
| int rmdir (const char *filename) | Function |
The rmdir function deletes a directory. The directory must be
empty before it can be removed; in other words, it can only contain
entries for . and ...
In most other respects,
These two error codes are synonymous; some systems use one, and some use
the other. The GNU system always uses The prototype for this function is declared in the header file
|
| int remove (const char *filename) | Function |
This is the ISO C function to remove a file. It works like
unlink for files and like rmdir for directories.
remove is declared in stdio.h.
|
The rename function is used to change a file's name.
| int rename (const char *oldname, const char *newname) | Function |
The rename function renames the file name oldname with
newname. The file formerly accessible under the name
oldname is afterward accessible as newname instead. (If the
file had any other names aside from oldname, it continues to have
those names.)
The directory containing the name newname must be on the same file system as the file (as indicated by the name oldname). One special case for If the oldname is not a directory, then any existing file named
newname is removed during the renaming operation. However, if
newname is the name of a directory, If the oldname is a directory, then either newname must not
exist or it must name a directory that is empty. In the latter case,
the existing directory named newname is deleted first. The name
newname must not specify a subdirectory of the directory
One useful feature of If
|
Directories are created with the mkdir function. (There is also
a shell command mkdir which does the same thing.)
| int mkdir (const char *filename, mode_t mode) | Function |
The mkdir function creates a new, empty directory whose name is
filename.
The argument mode specifies the file permissions for the new directory file. See Permission Bits, for more information about this. A return value of
To use this function, your program should include the header file
|
When you issue an ls -l shell command on a file, it gives you
information about the size of the file, who owns it, when it was last
modified, and the like. This kind of information is called the
file attributes; it is associated with the file itself and not a
particular one of its names.
This section contains information about how you can inquire about and modify these attributes of files.
When you read the attributes of a file, they come back in a structure
called struct stat. This section describes the names of the
attributes, their data types, and what they mean. For the functions
to read the attributes of a file, see Reading Attributes.
The header file sys/stat.h declares all the symbols defined
in this section.
| struct stat | Data Type |
The stat structure type is used to return information about the
attributes of a file. It contains at least the following members:
|
The extensions for the Large File Support (LFS) require even on 32 bits
machine types which can handle file sizes up to 2^63. Therefore
a new definition of struct stat is necessary.
| struct stat64 | Data Type |
The members of this type are the same and have the same names as those
in struct stat. The only difference is that the members
st_ino, st_size, and st_blocks have a different
type to support larger values.
|
Some of the file attributes have special data type names which exist
specifically for those attributes. (They are all aliases for well-known
integer types that you know and love.) These typedef names are defined
in the header file sys/types.h as well as in sys/stat.h.
Here is a list of them.
| mode_t | Data Type |
This is an integer data type used to represent file modes. In the
GNU system, this is equivalent to unsigned int.
|
| ino_t | Data Type |
This is an arithmetic data type used to represent file serial numbers.
(In Unix jargon, these are sometimes called inode numbers.)
In the GNU system, this type is equivalent to unsigned long int.
If the source is compiled with |
| ino64_t | Data Type |
This is an arithmetic data type used to represent file serial numbers
for the use in LFS. In the GNU system, this type is equivalent to
unsigned long longint.
When compiling with |
| dev_t | Data Type |
This is an arithmetic data type used to represent file device numbers.
In the GNU system, this is equivalent to int.
|
| nlink_t | Data Type |
This is an arithmetic data type used to represent file link counts.
In the GNU system, this is equivalent to unsigned short int.
|
| blkcnt_t | Data Type |
This is an arithmetic data type used to represent block counts.
In the GNU system, this is equivalent to unsigned long int.
If the source is compiled with |
| blkcnt64_t | Data Type |
This is an arithmetic data type used to represent block counts for the
use in LFS. In the GNU system, this is equivalent to unsigned
long long int.
When compiling with |
To examine the attributes of files, use the functions stat,
fstat and lstat. They return the attribute information in
a struct stat object. All three functions are declared in the
header file sys/stat.h.
| int stat (const char *filename, struct stat *buf) | Function |
The stat function returns information about the attributes of the
file named by filename in the structure pointed at by buf.
If filename is the name of a symbolic link, the attributes you get
describe the file that the link points to. If the link points to a
nonexistent file name, then The return value is
When the sources are compiled with |
| int stat64 (const char *filename, struct stat64 *buf) | Function |
This function is similar to stat but it is also able to work on
file larger then 2^31 bytes on 32 bits systems. To be able to do
this the result is stored in a variable of type struct stat64 to
which buf must point.
When the sources are compiled with |
| int fstat (int filedes, struct stat *buf) | Function |
The fstat function is like stat, except that it takes an
open file descriptor as an argument instead of a file name.
See Low-Level I/O.
Like
When the sources are compiled with |
| int fstat64 (int filedes, struct stat64 *buf) | Function |
This function is similar to fstat but it is prepared to work on
large files on 32 bits platforms. For large files the file descriptor
filedes should be returned by open64 or creat64.
The buf pointer points to a variable of type struct stat64
which is able to represent the larger values.
When the sources are compiled with |
| int lstat (const char *filename, struct stat *buf) | Function |
The lstat function is like stat, except that it does not
follow symbolic links. If filename is the name of a symbolic
link, lstat returns information about the link itself; otherwise,
lstat works like stat. See Symbolic Links.
When the sources are compiled with |
| int lstat64 (const char *filename, struct stat64 *buf) | Function |
This function is similar to lstat but it is also able to work on
file larger then 2^31 bytes on 32 bits systems. To be able to do
this the result is stored in a variable of type struct stat64 to
which buf must point.
When the sources are compiled with |
The file mode, stored in the st_mode field of the file
attributes, contains two kinds of information: the file type code, and
the access permission bits. This section discusses only the type code,
which you can use to tell whether the file is a directory, whether it is
a socket, and so on. For information about the access permission,
Permission Bits.
There are two predefined ways you can access the file type portion of the file mode. First of all, for each type of file, there is a predicate macro which examines a file mode value and returns true or false--is the file of that type, or not. Secondly, you can mask out the rest of the file mode to get just a file type code. You can compare this against various constants for the supported file types.
All of the symbols listed in this section are defined in the header file
sys/stat.h.
The following predicate macros test the type of a file, given the value
m which is the st_mode field returned by stat on
that file:
| int S_ISDIR (mode_t m) | Macro |
| This macro returns nonzero if the file is a directory. |
| int S_ISCHR (mode_t m) | Macro |
| This macro returns nonzero if the file is a character special file (a device like a terminal). |
| int S_ISBLK (mode_t m) | Macro |
| This macro returns nonzero if the file is a block special file (a device like a disk). |
| int S_ISREG (mode_t m) | Macro |
| This macro returns nonzero if the file is a regular file. |
| int S_ISFIFO (mode_t m) | Macro |
| This macro returns nonzero if the file is a FIFO special file, or a pipe. See Pipes and FIFOs. |
| int S_ISLNK (mode_t m) | Macro |
| This macro returns nonzero if the file is a symbolic link. See Symbolic Links. |
| int S_ISSOCK (mode_t m) | Macro |
| This macro returns nonzero if the file is a socket. See Sockets. |
An alternate non-POSIX method of testing the file type is supported for
compatibility with BSD. The mode can be bitwise ANDed with
S_IFMT to extract the file type code, and compared to the
appropriate type code constant. For example,
S_ISCHR (mode)
is equivalent to:
((mode & S_IFMT) == S_IFCHR)
| int S_IFMT | Macro |
| This is a bit mask used to extract the file type code portion of a mode value. |
These are the symbolic names for the different file type codes:
S_IFDIR
S_IFCHR
S_IFBLK
S_IFREG
S_IFLNK
S_IFSOCK
S_IFIFO
Every file has an owner which is one of the registered user names defined on the system. Each file also has a group, which is one of the defined groups. The file owner can often be useful for showing you who edited the file (especially when you edit with GNU Emacs), but its main purpose is for access control.
The file owner and group play a role in determining access because the file has one set of access permission bits for the user that is the owner, another set that apply to users who belong to the file's group, and a third set of bits that apply to everyone else. See Access Permission, for the details of how access is decided based on this data.
When a file is created, its owner is set from the effective user ID of the process that creates it (see Process Persona). The file's group ID may be set from either effective group ID of the process, or the group ID of the directory that contains the file, depending on the system where the file is stored. When you access a remote file system, it behaves according to its own rule, not according to the system your program is running on. Thus, your program must be prepared to encounter either kind of behavior, no matter what kind of system you run it on.
You can change the owner and/or group owner of an existing file using
the chown function. This is the primitive for the chown
and chgrp shell commands.
The prototype for this function is declared in unistd.h.
| int chown (const char *filename, uid_t owner, gid_t group) | Function |
The chown function changes the owner of the file filename to
owner, and its group owner to group.
Changing the owner of the file on certain systems clears the set-user-ID and set-group-ID bits of the file's permissions. (This is because those bits may not be appropriate for the new owner.) The other file permission bits are not changed. The return value is
|
| int fchown (int filedes, int owner, int group) | Function |
This is like chown, except that it changes the owner of the file
with open file descriptor filedes.
The return value from
|
The file mode, stored in the st_mode field of the file
attributes, contains two kinds of information: the file type code, and
the access permission bits. This section discusses only the access
permission bits, which control who can read or write the file.
See Testing File Type, for information about the file type code.
All of the symbols listed in this section are defined in the header file
sys/stat.h.
These symbolic constants are defined for the file mode bits that control access permission for the file:
S_IRUSR
S_IREAD
S_IREAD is an obsolete synonym provided for BSD
compatibility.
S_IWUSR
S_IWRITE
S_IWRITE is an obsolete synonym provided for BSD compatibility.
S_IXUSR
S_IEXEC
S_IEXEC is an obsolete
synonym provided for BSD compatibility.
S_IRWXU
(S_IRUSR | S_IWUSR | S_IXUSR).
S_IRGRP
S_IWGRP
S_IXGRP
S_IRWXG
(S_IRGRP | S_IWGRP | S_IXGRP).
S_IROTH
S_IWOTH
S_IXOTH
S_IRWXO
(S_IROTH | S_IWOTH | S_IXOTH).
S_ISUID
S_ISGID
S_ISVTX
On a directory, it gives permission to delete a file in the directory
only if you own that file. Ordinarily, a user either can delete all the
files in the directory or cannot delete any of them (based on whether
the user has write permission for the directory). The same restriction
applies--you must both have write permission for the directory and own
the file you want to delete. The one exception is that the owner of the
directory can delete any file in the directory, no matter who owns it
(provided the owner has given himself write permission for the
directory). This is commonly used for the /tmp directory, where
anyone may create files, but not delete files created by other users.
Originally the sticky bit on an executable file modified the swapping policies of the system. Normally, when a program terminated, its pages in core were immediately freed and reused. If the sticky bit was set on the executable file, the system kept the pages in core for a while as if the program were still running. This was advantageous for a program likely to be run many times in succession. This usage is obsolete in modern systems. When a program terminates, its pages always remain in core as long as there is no shortage of memory in the system. When the program is next run, its pages will still be in core if no shortage arose since the last run.
On some modern systems where the sticky bit has no useful meaning for an
executable file, you cannot set the bit at all for a non-directory.
If you try, chmod fails with EFTYPE;
see Setting Permissions.
Some systems (particularly SunOS) have yet another use for the sticky bit. If the sticky bit is set on a file that is not executable, it means the opposite: never cache the pages of this file at all. The main use of this is for the files on an NFS server machine which are used as the swap area of diskless client machines. The idea is that the pages of the file will be cached in the client's memory, so it is a waste of the server's memory to cache them a second time. In this use the sticky bit also says that the filesystem may fail to record the file's modification time onto disk reliably (the idea being that no-one cares for a swap file).
This bit is only available on BSD systems (and those derived from
them). Therefore one has to use the _BSD_SOURCE feature select
macro to get the definition (see Feature Test Macros).
The actual bit values of the symbols are listed in the table above so you can decode file mode values when debugging your programs. These bit values are correct for most systems, but they are not guaranteed.
Warning: Writing explicit numbers for file permissions is bad practice. It is not only non-portable, it also requires everyone who reads your program to remember what the bits mean. To make your program clean, use the symbolic names.
Recall that the operating system normally decides access permission for a file based on the effective user and group IDs of the process, and its supplementary group IDs, together with the file's owner, group and permission bits. These concepts are discussed in detail in Process Persona.
If the effective user ID of the process matches the owner user ID of the file, then permissions for read, write, and execute/search are controlled by the corresponding "user" (or "owner") bits. Likewise, if any of the effective group ID or supplementary group IDs of the process matches the group owner ID of the file, then permissions are controlled by the "group" bits. Otherwise, permissions are controlled by the "other" bits.
Privileged users, like root, can access any file, regardless of
its file permission bits. As a special case, for a file to be
executable even for a privileged user, at least one of its execute bits
must be set.
The primitive functions for creating files (for example, open or
mkdir) take a mode argument, which specifies the file
permissions for the newly created file. But the specified mode is
modified by the process's file creation mask, or umask,
before it is used.
The bits that are set in the file creation mask identify permissions that are always to be disabled for newly created files. For example, if you set all the "other" access bits in the mask, then newly created files are not accessible at all to processes in the "other" category, even if the mode argument specified to the creation function would permit such access. In other words, the file creation mask is the complement of the ordinary access permissions you want to grant.
Programs that create files typically specify a mode argument that includes all the permissions that make sense for the particular file. For an ordinary file, this is typically read and write permission for all classes of users. These permissions are then restricted as specified by the individual user's own file creation mask.
To change the permission of an existing file given its name, call
chmod. This function ignores the file creation mask; it uses
exactly the specified permission bits.
In normal use, the file creation mask is initialized in the user's login
shell (using the umask shell command), and inherited by all
subprocesses. Application programs normally don't need to worry about
the file creation mask. It will do automatically what it is supposed to
do.
When your program should create a file and bypass the umask for its
access permissions, the easiest way to do this is to use fchmod
after opening the file, rather than changing the umask.
In fact, changing the umask is usually done only by shells. They use
the umask function.
The functions in this section are declared in sys/stat.h.
| mode_t umask (mode_t mask) | Function |
The umask function sets the file creation mask of the current
process to mask, and returns the previous value of the file
creation mask.
Here is an example showing how to read the mask with mode_t
read_umask (void)
{
mode_t mask = umask (0);
umask (mask);
return mask;
}
However, it is better to use |
| mode_t getumask (void) | Function |
| Return the current value of the file creation mask for the current process. This function is a GNU extension. |
| int chmod (const char *filename, mode_t mode) | Function |
The chmod function sets the access permission bits for the file
named by filename to mode.
If the filename names a symbolic link, This function returns
|
| int fchmod (int filedes, int mode) | Function |
This is like chmod, except that it changes the permissions of
the file currently open via descriptor filedes.
The return value from
|
When a program runs as a privileged user, this permits it to access
files off-limits to ordinary users--for example, to modify
/etc/passwd. Programs designed to be run by ordinary users but
access such files use the setuid bit feature so that they always run
with root as the effective user ID.
Such a program may also access files specified by the user, files which
conceptually are being accessed explicitly by the user. Since the
program runs as root, it has permission to access whatever file
the user specifies--but usually the desired behavior is to permit only
those files which the user could ordinarily access.
The program therefore must explicitly check whether the user would have the necessary access to a file, before it reads or writes the file.
To do this, use the function access, which checks for access
permission based on the process's real user ID rather than the
effective user ID. (The setuid feature does not alter the real user ID,
so it reflects the user who actually ran the program.)
There is another way you could check this access, which is easy to
describe, but very hard to use. This is to examine the file mode bits
and mimic the system's own access computation. This method is
undesirable because many systems have additional access control
features; your program cannot portably mimic them, and you would not
want to try to keep track of the diverse features that different systems
have. Using access is simple and automatically does whatever is
appropriate for the system you are using.
access is only only appropriate to use in setuid programs.
A non-setuid program will always use the effective ID rather than the
real ID.
The symbols in this section are declared in unistd.h.
| int access (const char *filename, int how) | Function |
The access function checks to see whether the file named by
filename can be accessed in the way specified by the how
argument. The how argument either can be the bitwise OR of the
flags R_OK, W_OK, X_OK, or the existence test
F_OK.
This function uses the real user and group ID's of the calling
process, rather than the effective ID's, to check for access
permission. As a result, if you use the function from a The return value is In addition to the usual file name errors (see File Name Errors), the following
|
These macros are defined in the header file unistd.h for use
as the how argument to the access function. The values
are integer constants.
| int R_OK | Macro |
| Argument that means, test for read permission. |
| int W_OK | Macro |
| Argument that means, test for write permission. |
| int X_OK | Macro |
| Argument that means, test for execute/search permission. |
| int F_OK | Macro |
| Argument that means, test for existence of the file. |
Each file has three time stamps associated with it: its access time,
its modification time, and its attribute modification time. These
correspond to the st_atime, st_mtime, and st_ctime
members of the stat structure; see File Attributes.
All of these times are represented in calendar time format, as
time_t objects. This data type is defined in time.h.
For more information about representation and manipulation of time
values, see Calendar Time.
Reading from a file updates its access time attribute, and writing updates its modification time. When a file is created, all three time stamps for that file are set to the current time. In addition, the attribute change time and modification time fields of the directory that contains the new entry are updated.
Adding a new name for a file with the link function updates the
attribute change time field of the file being linked, and both the
attribute change time and modification time fields of the directory
containing the new name. These same fields are affected if a file name
is deleted with unlink, remove, or rmdir. Renaming
a file with rename affects only the attribute change time and
modification time fields of the two parent directories involved, and not
the times for the file being renamed.
Changing attributes of a file (for example, with chmod) updates
its attribute change time field.
You can also change some of the time stamps of a file explicitly using
the utime function--all except the attribute change time. You
need to include the header file utime.h to use this facility.
| struct utimbuf | Data Type |
The utimbuf structure is used with the utime function to
specify new access and modification times for a file. It contains the
following members:
|
| int utime (const char *filename, const struct utimbuf *times) | Function |
|
This function is used to modify the file times associated with the file
named filename.
If times is a null pointer, then the access and modification times
of the file are set to the current time. Otherwise, they are set to the
values from the The attribute modification time for the file is set to the current time in either case (since changing the time stamps is itself a modification of the file attributes). The
|
Each of the three time stamps has a corresponding microsecond part,
which extends its resolution. These fields are called
st_atime_usec, st_mtime_usec, and st_ctime_usec;
each has a value between 0 and 999,999, which indicates the time in
microseconds. They correspond to the tv_usec field of a
timeval structure; see High-Resolution Calendar.
The utimes function is like utime, but also lets you specify
the fractional part of the file times. The prototype for this function is
in the header file sys/time.h.
| int utimes (const char *filename, struct timeval tvp[2]) | Function |
This function sets the file access and modification times for the file
named by filename. The new file access time is specified by
tvp[0], and the new modification time by
tvp[1]. This function comes from BSD.
The return values and error conditions are the same as for the |
Normally file sizes are maintained automatically. A file begins with a
size of 0 and is automatically extended when data is written
past its end. It is also possible to empty a file completely in an
open or fopen call.
However, sometimes it is necessary to reduce the size of a file.
This can be done with the truncate and ftruncate functions.
They were introduced in BSD Unix. ftruncate was later added to
POSIX.1.
Some systems allow you to extend a file (creating holes) with these
functions. This is useful when using memory-mapped I/O
(see Memory-mapped I/O), where files are not automatically extended.
However it is not portable but must be implemented if mmap allows
mapping of files (i.e., _POSIX_MAPPED_FILES is defined).
Using these functions on anything other than a regular file gives undefined results. On many systems, such a call will appear to succeed, without actually accomplishing anything.
| int truncate (const char *filename, off_t length) | Function |
|
The If length is longer, holes will be added to the end. However, some systems do not support this feature and will leave the file unchanged. The return value is 0 for success, or -1 for an error. In addition to the usual file name errors, the following errors may occur:
|
| int ftruncate (int fd, off_t length) | Function |
|
This is like
The return value is 0 for success, or -1 for an error. The following errors may occur:
|
As announced here is a little example how to use ftruncate in
combination with mmap:
int fd;
void *start;
size_t len;
int
add (off_t at, void *block, size_t size)
{
if (at + size > len)
{
/* Resize the file and remap. */
size_t ps = sysconf (_SC_PAGESIZE);
size_t ns = (at + size + ps - 1) & ~(ps - 1);
void *np;
if (ftruncate (fd, ns) < 0)
return -1;
np = mmap (NULL, ns, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (np == MAP_FAILED)
return -1;
start = np;
len = ns;
}
memcpy ((char *) start + at, block, size);
return 0;
}
The function add allows to add at arbitrary positions in the file
given blocks of memory. If the current size of the file is too small it
is extended. Please note the it is extended in multiples of a pagesize.
This is a requirement of mmap. The program has to track the real
size and once the program finished to work a final ftruncate call
should set the real size of the file.
The mknod function is the primitive for making special files,
such as files that correspond to devices. The GNU library includes
this function for compatibility with BSD.
The prototype for mknod is declared in sys/stat.h.
| int mknod (const char *filename, int mode, int dev) | Function |
The mknod function makes a special file with name filename.
The mode specifies the mode of the file, and may include the various
special file bits, such as S_IFCHR (for a character special file)
or S_IFBLK (for a block special file). See Testing File Type.
The dev argument specifies which device the special file refers to. Its exact interpretation depends on the kind of special file being created. The return value is
|
If you need to use a temporary file in your program, you can use the
tmpfile function to open it. Or you can use the tmpnam
(better: tmpnam_r) function to make a name for a temporary file and
then you can open it in the usual way with fopen.
The tempnam function is like tmpnam but lets you choose
what directory temporary files will go in, and something about what
their file names will look like. Important for multi threaded programs
is that tempnam is reentrant while tmpnam is not since it
returns a pointer to a static buffer.
These facilities are declared in the header file stdio.h.
| FILE * tmpfile (void) | Function |
This function creates a temporary binary file for update mode, as if by
calling fopen with mode "wb+". The file is deleted
automatically when it is closed or when the program terminates. (On
some other ISO C systems the file may fail to be deleted if the program
terminates abnormally).
This function is reentrant. When the sources are compiled with |
| FILE * tmpfile64 (void) | Function |
This function is similar to tmpfile but the stream it returns a
pointer for is opened using tmpfile64. Therefore this stream can be
used even on files larger then 2^31 bytes on 32 bits machines.
Please note that the return type is still If the sources are compiled with |
| char * tmpnam (char *result) | Function |
This function constructs and returns a file name that is a valid file
name and that does not name any existing file. If the result
argument is a null pointer, the return value is a pointer to an internal
static string, which might be modified by subsequent calls and therefore
makes this function non-reentrant. Otherwise, the result argument
should be a pointer to an array of at least L_tmpnam characters,
and the result is written into that array.
It is possible for Warning: Since between the time the pathname is constructed and
the file is created another process might have created a file with this
name using |
| char * tmpnam_r (char *result) | Function |
This function is nearly identical to the tmpnam function. But it
does not allow result to be a null pointer. In the latter case a
null pointer is returned.
This function is reentrant because the non-reentrant situation of
|
| int L_tmpnam | Macro |
The value of this macro is an integer constant expression that represents
the minimum allocation size of a string large enough to hold the
file name generated by the tmpnam function.
|
| int TMP_MAX | Macro |
The macro TMP_MAX is a lower bound for how many temporary names
you can create with tmpnam. You can rely on being able to call
tmpnam at least this many times before it might fail saying you
have made too many temporary file names.
With the GNU library, you can create a very large number of temporary
file names--if you actually create the files, you will probably run out
of disk space before you run out of names. Some other systems have a
fixed, small limit on the number of temporary files. The limit is never
less than |
| char * tempnam (const char *dir, const char *prefix) | Function |
This function generates a unique temporary filename. If prefix is
not a null pointer, up to five characters of this string are used as a
prefix for the file name. The return value is a string newly allocated
with malloc; you should release its storage with free when
it is no longer needed.
Because the string is dynamically allocated this function is reentrant. The directory prefix for the temporary file name is determined by testing each of the following, in sequence. The directory must exist and be writable.
This function is defined for SVID compatibility. |
| char * P_tmpdir | SVID Macro |
| This macro is the name of the default directory for temporary files. |
Older Unix systems did not have the functions just described. Instead
they used mktemp and mkstemp. Both of these functions
work by modifying a file name template string you pass. The last six
characters of this string must be XXXXXX. These six Xs
are replaced with six characters which make the whole string a unique
file name. Usually the template string is something like
/tmp/prefixXXXXXX, and each program uses a unique prefix.
Note: Because mktemp and mkstemp modify the
template string, you must not pass string constants to them.
String constants are normally in read-only storage, so your program
would crash when mktemp or mkstemp tried to modify the
string.
| char * mktemp (char *template) | Function |
The mktemp function generates a unique file name by modifying
template as described above. If successful, it returns
template as modified. If mktemp cannot find a unique file
name, it makes template an empty string and returns that. If
template does not end with XXXXXX, mktemp returns a
null pointer.
Warning: Since between the time the pathname is constructed and
the file is created another process might have created a file with this
name using |
| int mkstemp (char *template) | Function |
The mkstemp function generates a unique file name just as
mktemp does, but it also opens the file for you with open
(see Opening and Closing Files). If successful, it modifies
template in place and returns a file descriptor open on that file
for reading and writing. If mkstemp cannot create a
uniquely-named file, it returns -1. If template does not
end with XXXXXX, mkstemp returns -1 and does not
modify template.
The file is opened using mode |
Unlike mktemp, mkstemp is actually guaranteed to create a
unique file that cannot possibly clash with any other program trying to
create a temporary file. This is because it works by calling
open with the O_EXCL flag bit, which says you want to
always create a new file, and get an error if the file already exists.
A pipe is a mechanism for interprocess communication; data written to the pipe by one process can be read by another process. The data is handled in a first-in, first-out (FIFO) order. The pipe has no name; it is created for one use and both ends must be inherited from the single process which created the pipe.
A FIFO special file is similar to a pipe, but instead of being an anonymous, temporary connection, a FIFO has a name or names like any other file. Processes open the FIFO by name in order to communicate through it.
A pipe or FIFO has to be open at both ends simultaneously. If you read
from a pipe or FIFO file that doesn't have any processes writing to it
(perhaps because they have all closed the file, or exited), the read
returns end-of-file. Writing to a pipe or FIFO that doesn't have a
reading process is treated as an error condition; it generates a
SIGPIPE signal, and fails with error code EPIPE if the
signal is handled or blocked.
Neither pipes nor FIFO special files allow file positioning. Both reading and writing operations happen sequentially; reading from the beginning of the file and writing at the end.
pipe function.
The primitive for creating a pipe is the pipe function. This
creates both the reading and writing ends of the pipe. It is not very
useful for a single process to use a pipe to talk to itself. In typical
use, a process creates a pipe just before it forks one or more child
processes (see Creating a Process). The pipe is then used for
communication either between the parent or child processes, or between
two sibling processes.
The pipe function is declared in the header file
unistd.h.
| int pipe (int filedes[2]) | Function |
The pipe function creates a pipe and puts the file descriptors
for the reading and writing ends of the pipe (respectively) into
filedes[0] and filedes[1].
An easy way to remember that the input end comes first is that file
descriptor If successful,
|
Here is an example of a simple program that creates a pipe. This program
uses the fork function (see Creating a Process) to create
a child process. The parent process writes data to the pipe, which is
read by the child process.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
/* Read characters from the pipe and echo them to stdout. */
void
read_from_pipe (int file)
{
FILE *stream;
int c;
stream = fdopen (file, "r");
while ((c = fgetc (stream)) != EOF)
putchar (c);
fclose (stream);
}
/* Write some random text to the pipe. */
void
write_to_pipe (int file)
{
FILE *stream;
stream = fdopen (file, "w");
fprintf (stream, "hello, world!\n");
fprintf (stream, "goodbye, world!\n");
fclose (stream);
}
int
main (void)
{
pid_t pid;
int mypipe[2];
/* Create the pipe. */
if (pipe (mypipe))
{
fprintf (stderr, "Pipe failed.\n");
return EXIT_FAILURE;
}
/* Create the child process. */
pid = fork ();
if (pid == (pid_t) 0)
{
/* This is the child process. */
read_from_pipe (mypipe[0]);
return EXIT_SUCCESS;
}
else if (pid < (pid_t) 0)
{
/* The fork failed. */
fprintf (stderr, "Fork failed.\n");
return EXIT_FAILURE;
}
else
{
/* This is the parent process. */
write_to_pipe (mypipe[1]);
return EXIT_SUCCESS;
}
}
A common use of pipes is to send data to or receive data from a program
being run as subprocess. One way of doing this is by using a combination of
pipe (to create the pipe), fork (to create the subprocess),
dup2 (to force the subprocess to use the pipe as its standard input
or output channel), and exec (to execute the new program). Or,
you can use popen and pclose.
The advantage of using popen and pclose is that the
interface is much simpler and easier to use. But it doesn't offer as
much flexibility as using the low-level functions directly.
| FILE * popen (const char *command, const char *mode) | Function |
The popen function is closely related to the system
function; see Running a Command. It executes the shell command
command as a subprocess. However, instead of waiting for the
command to complete, it creates a pipe to the subprocess and returns a
stream that corresponds to that pipe.
If you specify a mode argument of Similarly, if you specify a mode argument of In the event of an error, |
| int pclose (FILE *stream) | Function |
The pclose function is used to close a stream created by popen.
It waits for the child process to terminate and returns its status value,
as for the system function.
|
Here is an example showing how to use popen and pclose to
filter output through another program, in this case the paging program
more.
#include <stdio.h>
#include <stdlib.h>
void
write_data (FILE * stream)
{
int i;
for (i = 0; i < 100; i++)
fprintf (stream, "%d\n", i);
if (ferror (stream))
{
fprintf (stderr, "Output to stream failed.\n");
exit (EXIT_FAILURE);
}
}
int
main (void)
{
FILE *output;
output = popen ("more", "w");
if (!output)
{
fprintf (stderr, "Could not run more.\n");
return EXIT_FAILURE;
}
write_data (output);
pclose (output);
return EXIT_SUCCESS;
}
A FIFO special file is similar to a pipe, except that it is created in a
different way. Instead of being an anonymous communications channel, a
FIFO special file is entered into the file system by calling
mkfifo.
Once you have created a FIFO special file in this way, any process can open it for reading or writing, in the same way as an ordinary file. However, it has to be open at both ends simultaneously before you can proceed to do any input or output operations on it. Opening a FIFO for reading normally blocks until some other process opens the same FIFO for writing, and vice versa.
The mkfifo function is declared in the header file
sys/stat.h.
| int mkfifo (const char *filename, mode_t mode) | Function |
The mkfifo function makes a FIFO special file with name
filename. The mode argument is used to set the file's
permissions; see Setting Permissions.
The normal, successful return value from
|
Reading or writing pipe data is atomic if the size of data written
is not greater than PIPE_BUF. This means that the data transfer
seems to be an instantaneous unit, in that nothing else in the system
can observe a state in which it is partially complete. Atomic I/O may
not begin right away (it may need to wait for buffer space or for data),
but once it does begin, it finishes immediately.
Reading or writing a larger amount of data may not be atomic; for
example, output data from other processes sharing the descriptor may be
interspersed. Also, once PIPE_BUF characters have been written,
further writes will block until some characters are read.
See Limits for Files, for information about the PIPE_BUF
parameter.
This chapter describes the GNU facilities for interprocess communication using sockets.
A socket is a generalized interprocess communication channel.
Like a pipe, a socket is represented as a file descriptor. But,
unlike pipes, sockets support communication between unrelated
processes, and even between processes running on different machines
that communicate over a network. Sockets are the primary means of
communicating with other machines; telnet, rlogin,
ftp, talk, and the other familiar network programs use
sockets.
Not all operating systems support sockets. In the GNU library, the
header file sys/socket.h exists regardless of the operating
system, and the socket functions always exist, but if the system does
not really support sockets, these functions always fail.
Incomplete: We do not currently document the facilities for broadcast messages or for configuring Internet interfaces. The reentrant functions and some newer functions that are related to IPv6 aren't documented either so far.
When you create a socket, you must specify the style of communication you want to use and the type of protocol that should implement it. The communication style of a socket defines the user-level semantics of sending and receiving data on the socket. Choosing a communication style specifies the answers to questions such as these:
Designing a program to use unreliable communication styles usually involves taking precautions to detect lost or misordered packets and to retransmit data as needed.
You must also choose a namespace for naming the socket. A socket
name ("address") is meaningful only in the context of a particular
namespace. In fact, even the data type to use for a socket name may
depend on the namespace. Namespaces are also called "domains", but we
avoid that word as it can be confused with other usage of the same
term. Each namespace has a symbolic name that starts with PF_.
A corresponding symbolic name starting with AF_ designates the
address format for that namespace.
Finally you must choose the protocol to carry out the
communication. The protocol determines what low-level mechanism is used
to transmit and receive data. Each protocol is valid for a particular
namespace and communication style; a namespace is sometimes called a
protocol family because of this, which is why the namespace names
start with PF_.
The rules of a protocol apply to the data passing between two programs, perhaps on different computers; most of these rules are handled by the operating system, and you need not know about them. What you do need to know about protocols is this:
Throughout the following description at various places
variables/parameters to denote sizes are required. And here the trouble
starts. In the first implementations the type of these variables was
simply int. This type was on almost all machines of this time 32
bits wide and so a de-factor standard required 32 bit variables. This
is important since references to variables of this type are passed to
the kernel.
But then the POSIX people came and unified the interface with the words
"all size values are of type size_t". But on 64 bit machines
size_t is 64 bits wide, and so variable references are not anymore
possible.
The Unix98 specification provides a solution by introducing a type
socklen_t. This type is used in all of the cases that POSIX
changed to use size_t. The only requirement of this type is that
it be an unsigned type of at least 32 bits. Therefore, implementations
which require that references to 32 bit variables be passed can be as
happy as implementations which use 64 bit values.
The GNU library includes support for several different kinds of sockets,
each with different characteristics. This section describes the
supported socket types. The symbolic constants listed here are
defined in sys/socket.h.
| int SOCK_STREAM | Macro |
The SOCK_STREAM style is like a pipe (see Pipes and FIFOs);
it operates over a connection with a particular remote socket, and
transmits data reliably as a stream of bytes.
Use of this style is covered in detail in Connections. |
| int SOCK_DGRAM | Macro |
The SOCK_DGRAM style is used for sending
individually-addressed packets, unreliably.
It is the diametrical opposite of SOCK_STREAM.
Each time you write data to a socket of this kind, that data becomes
one packet. Since The only guarantee that the system makes about your requests to transmit data is that it will try its best to deliver each packet you send. It may succeed with the sixth packet after failing with the fourth and fifth packets; the seventh packet may arrive before the sixth, and may arrive a second time after the sixth. The typical use for See Datagrams, for detailed information about how to use datagram sockets. |
| int SOCK_RAW | Macro |
| This style provides access to low-level network protocols and interfaces. Ordinary user programs usually have no need to use this style. |
The name of a socket is normally called an address. The functions and symbols for dealing with socket addresses were named inconsistently, sometimes using the term "name" and sometimes using "address". You can regard these terms as synonymous where sockets are concerned.
A socket newly created with the socket function has no
address. Other processes can find it for communication only if you
give it an address. We call this binding the address to the
socket, and the way to do it is with the bind function.
You need be concerned with the address of a socket if other processes are to find it and start communicating with it. You can specify an address for other sockets, but this is usually pointless; the first time you send data from a socket, or use it to initiate a connection, the system assigns an address automatically if you have not specified one.
Occasionally a client needs to specify an address because the server
discriminates based on addresses; for example, the rsh and rlogin
protocols look at the client's socket address and only bypass password
checking if it is less than IPPORT_RESERVED (see Ports).
The details of socket addresses vary depending on what namespace you are using. See Local Namespace, or Internet Namespace, for specific information.
Regardless of the namespace, you use the same functions bind and
getsockname to set and examine a socket's address. These
functions use a phony data type, struct sockaddr *, to accept the
address. In practice, the address lives in a structure of some other
data type appropriate to the address format you are using, but you cast
its address to struct sockaddr * when you pass it to
bind.
struct sockaddr.
The functions bind and getsockname use the generic data
type struct sockaddr * to represent a pointer to a socket
address. You can't use this data type effectively to interpret an
address or construct one; for that, you must use the proper data type
for the socket's namespace.
Thus, the usual practice is to construct an address in the proper
namespace-specific type, then cast a pointer to struct sockaddr *
when you call bind or getsockname.
The one piece of information that you can get from the struct
sockaddr data type is the address format designator which tells
you which data type to use to understand the address fully.
The symbols in this section are defined in the header file
sys/socket.h.
| struct sockaddr | Data Type |
The struct sockaddr type itself has the following members:
|
Each address format has a symbolic name which starts with AF_.
Each of them corresponds to a PF_ symbol which designates the
corresponding namespace. Here is a list of address format names:
AF_LOCAL
PF_LOCAL is the name of that namespace.) See Local Namespace Details, for information about this address format.
AF_UNIX
AF_LOCAL, for compatibility.
(PF_UNIX is likewise a synonym for PF_LOCAL.)
AF_FILE
AF_LOCAL, for compatibility.
(PF_FILE is likewise a synonym for PF_LOCAL.)
AF_INET
PF_INET is the name of that namespace.)
See Internet Address Formats.
AF_INET6
AF_INET, but refers to the IPv6 protocol.
(PF_INET6 is the name of the corresponding namespace.)
AF_UNSPEC
The corresponding namespace designator symbol PF_UNSPEC exists
for completeness, but there is no reason to use it in a program.
sys/socket.h defines symbols starting with AF_ for many
different kinds of networks, all or most of which are not actually
implemented. We will document those that really work, as we receive
information about how to use them.
Use the bind function to assign an address to a socket. The
prototype for bind is in the header file sys/socket.h.
For examples of use, see Local Socket Example, or see Inet Example.
| int bind (int socket, struct sockaddr *addr, socklen_t length) | Function |
The bind function assigns an address to the socket
socket. The addr and length arguments specify the
address; the detailed format of the address depends on the namespace.
The first part of the address is always the format designator, which
specifies a namespace, and says that the address is in the format for
that namespace.
The return value is
Additional conditions may be possible depending on the particular namespace of the socket. |
Use the function getsockname to examine the address of an
Internet socket. The prototype for this function is in the header file
sys/socket.h.
| int getsockname (int socket, struct sockaddr *addr, socklen_t *length-ptr) | Function |
The getsockname function returns information about the
address of the socket socket in the locations specified by the
addr and length-ptr arguments. Note that the
length-ptr is a pointer; you should initialize it to be the
allocation size of addr, and on return it contains the actual
size of the address data.
The format of the address data depends on the socket namespace. The
length of the information is usually fixed for a given namespace, so
normally you can know exactly how much space is needed and can provide
that much. The usual practice is to allocate a place for the value
using the proper data type for the socket's namespace, then cast its
address to The return value is
|
You can't read the address of a socket in the file namespace. This is consistent with the rest of the system; in general, there's no way to find a file's name from a descriptor for that file.
Each network interface has a name. This usually consists of a few
letters that relate to the type of interface, which may be followed by a
number if there is more than one interface of that type. Examples
might be lo (the loopback interface) and eth0 (the first
Ethernet interface).
Although such names are convenient for humans, it would be clumsy to have to use them whenever a program needs to refer to an interface. In such situations an interface is referred to by its index, which is an arbitrarily-assigned small positive integer.
The following functions, constants and data types are declared in the
header file net/if.h.
| size_t IFNAMSIZ | Constant |
| This constant defines the maximum buffer size needed to hold an interface name, including its terminating zero byte. |
| unsigned int if_nametoindex (const char *ifname) | Function |
| This function yields the interface index corresponding to a particular name. If no interface exists with the name given, it returns 0. |
| char * if_indextoname (unsigned int ifindex, char *ifname) | Function |
This function maps an interface index to its corresponding name. The
returned name is placed in the buffer pointed to by ifname, which
must be at least IFNAMSIZE bytes in length. If the index was
invalid, the function's return value is a null pointer, otherwise it is
ifname.
|
| struct if_nameindex | Data Type |
This data type is used to hold the information about a single
interface. It has the following members:
|
| struct if_nameindex * if_nameindex (void) | Function |
This function returns an array of if_nameindex structures, one
for every interface that is present. The end of the list is indicated
by a structure with an interface of 0 and a null name pointer. If an
error occurs, this function returns a null pointer.
The returned structure must be freed with |
| void if_freenameindex (struct if_nameindex *ptr) | Function |
This function frees the structure returned by an earlier call to
if_nameindex.
|
This section describes the details of the local namespace, whose
symbolic name (required when you create a socket) is PF_LOCAL.
The local namespace is also known as "Unix domain sockets". Another
name is file namespace since socket addresses are normally implemented
as file names.
In the local namespace, socket addresses are file names. You can specify
any file name you want as the address of the socket, but you must have
write permission on the directory containing it. In order to connect to
a socket, you must have read permission for it. It's common to put
these files in the /tmp directory.
One peculiarity of the local namespace is that the name is only used when opening the connection; once that is over with, the address is not meaningful and may not exist.
Another peculiarity is that you cannot connect to such a socket from another machine-not even if the other machine shares the file system which contains the name of the socket. You can see the socket in a directory listing, but connecting to it never succeeds. Some programs take advantage of this, such as by asking the client to send its own process ID, and using the process IDs to distinguish between clients. However, we recommend you not to use this method in protocols you design, as we might someday permit connections from other machines that mount the same file systems. Instead, send each new client an identifying number if you want it to have one.
After you close a socket in the local namespace, you should delete the
file name from the file system. Use unlink or remove to
do this; see Deleting Files.
The local namespace supports just one protocol for any communication
style; it is protocol number 0.
To create a socket in the local namespace, use the constant
PF_LOCAL as the namespace argument to socket or
socketpair. This constant is defined in sys/socket.h.
| int PF_LOCAL | Macro |
This designates the local namespace, in which socket addresses are local
names, and its associated family of protocols. PF_Local is the
macro used by Posix.1g.
|
| int PF_UNIX | Macro |
This is a synonym for PF_LOCAL, for compatibility's sake.
|
| int PF_FILE | Macro |
This is a synonym for PF_LOCAL, for compatibility's sake.
|
The structure for specifying socket names in the local namespace is
defined in the header file sys/un.h:
| struct sockaddr_un | Data Type |
This structure is used to specify local namespace socket addresses. It has
the following members:
|
You should compute the length parameter for a socket address in
the local namespace as the sum of the size of the sun_family
component and the string length (not the allocation size!) of
the file name string. This can be done using the macro SUN_LEN:
| int SUN_LEN (struct sockaddr_un * ptr) | Macro |
| The macro computes the length of socket address in the local namespace. |
Here is an example showing how to create and name a socket in the local namespace.
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
int
make_named_socket (const char *filename)
{
struct sockaddr_un name;
int sock;
size_t size;
/* Create the socket. */
sock = socket (PF_LOCAL, SOCK_DGRAM, 0);
if (sock < 0)
{
perror ("socket");
exit (EXIT_FAILURE);
}
/* Bind a name to the socket. */
name.sun_family = AF_LOCAL;
strncpy (name.sun_path, filename, sizeof (name.sun_path));
/* The size of the address is
the offset of the start of the filename,
plus its length,
plus one for the terminating null byte.
Alternatively you can just do:
size = SUN_LEN (&name);
*/
size = (offsetof (struct sockaddr_un, sun_path)
+ strlen (name.sun_path) + 1);
if (bind (sock, (struct sockaddr *) &name, size) < 0)
{
perror ("bind");
exit (EXIT_FAILURE);
}
return sock;
}
This section describes the details of the protocols and socket naming conventions used in the Internet namespace.
Originally the Internet namespace used only IP version 4 (IPv4). With the growing number of hosts on the Internet, a new protocol with a larger address space was necessary: IP version 6 (IPv6). IPv6 introduces besides 128bit addresses (IPv4 has 32bit addresses) also other features and will eventually replace IPv4.
To create a socket in the IPv4 Internet namespace, use the symbolic name
PF_INET of this namespace as the namespace argument to
socket or socketpair. For IPv6 addresses, you need the
macro PF_INET6. These macros are defined in sys/socket.h.
| int PF_INET | Macro |
| This designates the IPv4 Internet namespace and associated family of protocols. |
| int AF_INET6 | Macro |
| This designates the IPv6 Internet namespace and associated family of protocols. |
A socket address for the Internet namespace includes the following components:
You must ensure that the address and port number are represented in a canonical format called network byte order. See Byte Order, for information about this.
In the Internet namespace, for both IPv4 (AF_INET) and IPv6
(AF_INET6), a socket address consists of a host address
and a port on that host. In addition, the protocol you choose serves
effectively as a part of the address because local port numbers are
meaningful only within a particular protocol.
The data types for representing socket addresses in the Internet namespace
are defined in the header file netinet/in.h.
| struct sockaddr_in | Data Type |
This is the data type used to represent socket addresses in the
Internet namespace. It has the following members:
|
When you call bind or getsockname, you should specify
sizeof (struct sockaddr_in) as the length parameter if
you are using an IPv4 Internet namespace socket address.
| struct sockaddr_in6 | Data Type |
This is the data type used to represent socket addresses in the IPv6
namespace. It has the following members:
|
Each computer on the Internet has one or more Internet addresses,
numbers which identify that computer among all those on the Internet.
Users typically write IPv4 numeric host addresses as sequences of four
numbers, separated by periods, as in 128.52.46.32, and IPv6
numeric host addresses as sequences of up to eight numbers separated by
colons, as in 5f03:1200:836f:c100::1.
Each computer also has one or more host names, which are strings
of words separated by periods, as in mescaline.gnu.org.
Programs that let the user specify a host typically accept both numeric addresses and host names. But the program needs a numeric address to open a connection; to use a host name, you must convert it to the numeric address it stands for.
An IPv4 Internet host address is a number containing four bytes of data. Historically these are divided into two parts, a network number and a local network address number within that network. In the mid-1990s classless address were introduced which changed the behaviour. Since some functions implicitly expect the old definitions, we first describe the class based network and will then describe classless addresses. IPv6 uses only classless addresses and therefore the following paragraphs don't apply.
The class based IPv4 network number consists of the first one, two or three bytes; the rest of the bytes are the local address.
IPv4 network numbers are registered with the Network Information Center (NIC), and are divided into three classes--A, B, and C. The local network address numbers of individual machines are registered with the administrator of the particular network.
Class A networks have single-byte numbers in the range 0 to 127. There are only a small number of Class A networks, but they can each support a very large number of hosts. Medium-sized Class B networks have two-byte network numbers, with the first byte in the range 128 to 191. Class C networks are the smallest; they have three-byte network numbers, with the first byte in the range 192-255. Thus, the first 1, 2, or 3 bytes of an Internet address specifies a network. The remaining bytes of the Internet address specify the address within that network.
The Class A network 0 is reserved for broadcast to all networks. In addition, the host number 0 within each network is reserved for broadcast to all hosts in that network. These uses are obsolete now but out of compatibility reasons you shouldn't use network 0 and host number 0.
The Class A network 127 is reserved for loopback; you can always use
the Internet address 127.0.0.1 to refer to the host machine.
Since a single machine can be a member of multiple networks, it can have multiple Internet host addresses. However, there is never supposed to be more than one machine with the same host address.
There are four forms of the standard numbers-and-dots notation for Internet addresses:
a.b.c.d
a.b.c
a.b.
a.b
a
Within each part of the address, the usual C conventions for specifying
the radix apply. In other words, a leading 0x or 0X implies
hexadecimal radix; a leading 0 implies octal; and otherwise decimal
radix is assumed.
IPv4 addresses (and IPv6 addresses also) are now considered as
classless. The distinction between classes A, B, and C can be ignored.
Instead a IPv4 host address consists of a 32-bit address and a 32-bit
mask. The mask contains bits of 1 for the network part and bits of 0
for the host part. The 1-bits are contiguous from the leftmost bit, the
0-bits are contiguous from the rightmost bit so that the netmask can also
be written as a prefix length of bits of 1. Classes A, B and C are just
special cases of this general rule. For example, class A addresses have
a netmask of 255.0.0.0 or a prefix length of 8.
Classless IPv4 network addresses are written in numbers-and-dots
notation with the prefix length appended and a slash as separator. For
example the class A network 10 is written as 10.0.0.0/8.
IPv6 addresses contain 128 bits (IPv4 has 32 bits) of data. A host
address is usually written as eight 16-bit hexadecimal numbers that are
separated by colons. Two colons are used to abbreviate strings of
consecutive zeros. For example the IPv6 loopback address which is
0:0:0:0:0:0:0:1 can be just written as ::1.
IPv4 Internet host addresses are represented in some contexts as integers
(type uint32_t). In other contexts, the integer is
packaged inside a structure of type struct in_addr. It would
be better if the usage were made consistent, but it is not hard to extract
the integer from the structure or put the integer into a structure.
You will find older code that uses unsigned long int for
IPv4 Internet host addresses instead of uint32_t or struct
in_addr. Historically unsigned long int was a 32 bit number but
with 64 bit machines this has changed. Using unsigned long int
might break the code if it is used on machines where this type doesn't
have 32 bits. uint32_t is specified by Unix98 and guaranteed to have
32 bits.
IPv6 Internet host addresses have 128 bits and are packaged inside a
structure of type struct in6_addr.
The following basic definitions for Internet addresses are declared in
the header file netinet/in.h:
| struct in_addr | Data Type |
This data type is used in certain contexts to contain an IPv4 Internet
host address. It has just one field, named s_addr, which records
the host address number as an uint32_t.
|
| uint32_t INADDR_LOOPBACK | Macro |
You can use this constant to stand for "the address of this machine,"
instead of finding its actual address. It is the IPv4 Internet address
127.0.0.1, which is usually called localhost. This
special constant saves you the trouble of looking up the address of your
own machine. Also, the system usually implements INADDR_LOOPBACK
specially, avoiding any network traffic for the case of one machine
talking to itself.
|
| uint32_t INADDR_ANY | Macro |
You can use this constant to stand for "any incoming address," when
binding to an address. See Setting Address. This is the usual
address to give in the sin_addr member of struct sockaddr_in when you want to accept Internet connections.
|
| uint32_t INADDR_BROADCAST | Macro |
| This constant is the address you use to send a broadcast message. |
| uint32_t INADDR_NONE | Macro |
| This constant is returned by some functions to indicate an error. |
| struct in6_addr | Data Type |
| This data type is used to store an IPv6 address. It stores 128 bits of data, which can be accessed (via a union) in a variety of ways. |
| struct in6_addr in6addr_loopback | Constant |
This constant is the IPv6 address ::1, the loopback address. See
above for a description of what this means. The macro
IN6ADDR_LOOPBACK_INIT is provided to allow you to initialise your
own variables to this value.
|
| struct in6_addr in6addr_any | Constant |
This constant is the IPv6 address ::, the unspecified address. See
above for a description of what this means. The macro
IN6ADDR_ANY_INIT is provided to allow you to initialise your
own variables to this value.
|
These additional functions for manipulating Internet addresses are
declared in the header file arpa/inet.h. They represent Internet
addresses in network byte order; they represent network numbers and
local-address-within-network numbers in host byte order. See Byte Order, for an explanation of network and host byte order.
| int inet_aton (const char *name, struct in_addr *addr) | Function |
This function converts the IPv4 Internet host address name
from the standard numbers-and-dots notation into binary data and stores
it in the struct in_addr that addr points to.
inet_aton returns nonzero if the address is valid, zero if not.
|
| uint32_t inet_addr (const char *name) | Function |
This function converts the IPv4 Internet host address name from the
standard numbers-and-dots notation into binary data. If the input is
not valid, inet_addr returns INADDR_NONE. This is an
obsolete interface to inet_aton, described immediately above; it
is obsolete because INADDR_NONE is a valid address
(255.255.255.255), and inet_aton provides a cleaner way to
indicate error return.
|
| uint32_t inet_network (const char *name) | Function |
This function extracts the network number from the address name,
given in the standard numbers-and-dots notation. The returned address is
in host order. If the input is not valid, inet_network returns
-1.
The function works only with traditional IPv4 class A, B and C network types. It doesn't work with classless addresses and shouldn't be used anymore. |
| char * inet_ntoa (struct in_addr addr) | Function |
|
This function converts the IPv4 Internet host address addr to a
string in the standard numbers-and-dots notation. The return value is
a pointer into a statically-allocated buffer. Subsequent calls will
overwrite the same buffer, so you should copy the string if you need
to save it.
In multi-threaded programs each thread has an own statically-allocated
buffer. But still subsequent calls of Instead of |
| struct in_addr inet_makeaddr (uint32_t net, uint32_t local) | Function |
| This function makes an IPv4 Internet host address by combining the network number net with the local-address-within-network number local. |
| uint32_t inet_lnaof (struct in_addr addr) | Function |
|
This function returns the local-address-within-network part of the
Internet host address addr.
The function works only with traditional IPv4 class A, B and C network types. It doesn't work with classless addresses and shouldn't be used anymore. |
| uint32_t inet_netof (struct in_addr addr) | Function |
|
This function returns the network number part of the Internet host
address addr.
The function works only with traditional IPv4 class A, B and C network types. It doesn't work with classless addresses and shouldn't be used anymore. |
| int inet_pton (int af, const char *cp, void *buf) | Function |
This function converts an Internet address (either IPv4 or IPv6) from
presentation (textual) to network (binary) format. af should be
either AF_INET or AF_INET6, as appropriate for the type of
address being converted. cp is a pointer to the input string, and
buf is a pointer to a buffer for the result. It is the caller's
responsibility to make sure the buffer is large enough.
|
| const char * inet_ntop (int af, const void *cp, char *buf, size_t len) | Function |
This function converts an Internet address (either IPv4 or IPv6) from
network (binary) to presentation (textual) form. af should be
either AF_INET or AF_INET6, as appropriate. cp is a
pointer to the address to be converted. buf should be a pointer
to a buffer to hold the result, and len is the length of this
buffer. The return value from the function will be this buffer address.
|
Besides the standard numbers-and-dots notation for Internet addresses,
you can also refer to a host by a symbolic name. The advantage of a
symbolic name is that it is usually easier to remember. For example,
the machine with Internet address 158.121.106.19 is also known as
alpha.gnu.org; and other machines in the gnu.org
domain can refer to it simply as alpha.
Internally, the system uses a database to keep track of the mapping
between host names and host numbers. This database is usually either
the file /etc/hosts or an equivalent provided by a name server.
The functions and other symbols for accessing this database are declared
in netdb.h. They are BSD features, defined unconditionally if
you include netdb.h.
| struct hostent | Data Type |
This data type is used to represent an entry in the hosts database. It
has the following members:
|
As far as the host database is concerned, each address is just a block
of memory h_length bytes long. But in other contexts there is an
implicit assumption that you can convert IPv4 addresses to a
struct in_addr or an uint32_t. Host addresses in
a struct hostent structure are always given in network byte
order; see Byte Order.
You can use gethostbyname, gethostbyname2 or
gethostbyaddr to search the hosts database for information about
a particular host. The information is returned in a
statically-allocated structure; you must copy the information if you
need to save it across calls. You can also use getaddrinfo and
getnameinfo to obtain this information.
| struct hostent * gethostbyname (const char *name) | Function |
The gethostbyname function returns information about the host
named name. If the lookup fails, it returns a null pointer.
|
| struct hostent * gethostbyname2 (const char *name, int af) | Function |
The gethostbyname2 function is like gethostbyname, but
allows the caller to specify the desired address family (e.g.
AF_INET or AF_INET6) for the result.
|
| struct hostent * gethostbyaddr (const char *addr, int length, int format) | Function |
The gethostbyaddr function returns information about the host
with Internet address addr. The parameter addr is not
really a pointer to char - it can be a pointer to an IPv4 or an IPv6
address. The length argument is the size (in bytes) of the address
at addr. format specifies the address format; for an IPv4
Internet address, specify a value of AF_INET; for an IPv6
Internet address, use AF_INET6.
If the lookup fails, |
If the name lookup by gethostbyname or gethostbyaddr
fails, you can find out the reason by looking at the value of the
variable h_errno. (It would be cleaner design for these
functions to set errno, but use of h_errno is compatible
with other systems.)
Here are the error codes that you may find in h_errno:
HOST_NOT_FOUND
TRY_AGAIN
NO_RECOVERY
NO_ADDRESS
The lookup functions above all have one in common: they are not reentrant and therefore unusable in multi-threaded applications. Therefore provides the GNU C library a new set of functions which can be used in this context.
| int gethostbyname_r (const char *restrict name, struct hostent *restrict result_buf, char *restrict buf, size_t buflen, struct hostent **restrict result, int *restrict h_errnop) | Function |
The gethostbyname_r function returns information about the host
named name. The caller must pass a pointer to an object of type
struct hostent in the result_buf parameter. In addition
the function may need extra buffer space and the caller must pass an
pointer and the size of the buffer in the buf and buflen
parameters.
A pointer to the buffer, in which the result is stored, is available in
Here's a small example: struct hostent *
gethostname (char *host)
{
struct hostent hostbuf, *hp;
size_t hstbuflen;
char *tmphstbuf;
int res;
int herr;
hstbuflen = 1024;
tmphstbuf = malloc (hstbuflen);
while ((res = gethostbyname_r (host, &hostbuf, tmphstbuf, hstbuflen,
&hp, &herr)) == ERANGE)
{
/* Enlarge the buffer. */
hstbuflen *= 2;
tmphstbuf = realloc (tmphstbuf, hstbuflen);
}
/* Check for errors. */
if (res || hp == NULL)
return NULL;
return hp->h_name;
}
|
| int gethostbyname2_r (const char *name, int af, struct hostent *restrict result_buf, char *restrict buf, size_t buflen, struct hostent **restrict result, int *restrict h_errnop) | Function |
The gethostbyname2_r function is like gethostbyname_r, but
allows the caller to specify the desired address family (e.g.
AF_INET or AF_INET6) for the result.
|
| int gethostbyaddr_r (const char *addr, int length, int format, struct hostent *restrict result_buf, char *restrict buf, size_t buflen, struct hostent **restrict result, int *restrict h_errnop) | Function |
The gethostbyaddr_r function returns information about the host
with Internet address addr. The parameter addr is not
really a pointer to char - it can be a pointer to an IPv4 or an IPv6
address. The length argument is the size (in bytes) of the address
at addr. format specifies the address format; for an IPv4
Internet address, specify a value of AF_INET; for an IPv6
Internet address, use AF_INET6.
Similar to the |
You can also scan the entire hosts database one entry at a time using
sethostent, gethostent, and endhostent. Be careful
in using these functions, because they are not reentrant.
| void sethostent (int stayopen) | Function |
This function opens the hosts database to begin scanning it. You can
then call gethostent to read the entries.
If the stayopen argument is nonzero, this sets a flag so that
subsequent calls to |
| struct hostent * gethostent (void) | Function |
| This function returns the next entry in the hosts database. It returns a null pointer if there are no more entries. |
| void endhostent (void) | Function |
| This function closes the hosts database. |
A socket address in the Internet namespace consists of a machine's Internet address plus a port number which distinguishes the sockets on a given machine (for a given protocol). Port numbers range from 0 to 65,535.
Port numbers less than IPPORT_RESERVED are reserved for standard
servers, such as finger and telnet. There is a database
that keeps track of these, and you can use the getservbyname
function to map a service name onto a port number; see Services Database.
If you write a server that is not one of the standard ones defined in
the database, you must choose a port number for it. Use a number
greater than IPPORT_USERRESERVED; such numbers are reserved for
servers and won't ever be generated automatically by the system.
Avoiding conflicts with servers being run by other users is up to you.
When you use a socket without specifying its address, the system
generates a port number for it. This number is between
IPPORT_RESERVED and IPPORT_USERRESERVED.
On the Internet, it is actually legitimate to have two different
sockets with the same port number, as long as they never both try to
communicate with the same socket address (host address plus port
number). You shouldn't duplicate a port number except in special
circumstances where a higher-level protocol requires it. Normally,
the system won't let you do it; bind normally insists on
distinct port numbers. To reuse a port number, you must set the
socket option SO_REUSEADDR. See Socket-Level Options.
These macros are defined in the header file netinet/in.h.
| int IPPORT_RESERVED | Macro |
Port numbers less than IPPORT_RESERVED are reserved for
superuser use.
|
| int IPPORT_USERRESERVED | Macro |
Port numbers greater than or equal to IPPORT_USERRESERVED are
reserved for explicit use; they will never be allocated automatically.
|
The database that keeps track of "well-known" services is usually
either the file /etc/services or an equivalent from a name server.
You can use these utilities, declared in netdb.h, to access
the services database.
| struct servent | Data Type |
This data type holds information about entries from the services database.
It has the following members:
|
To get information about a particular service, use the
getservbyname or getservbyport functions. The information
is returned in a statically-allocated structure; you must copy the
information if you need to save it across calls.
| struct servent * getservbyname (const char *name, const char *proto) | Function |
The getservbyname function returns information about the
service named name using protocol proto. If it can't find
such a service, it returns a null pointer.
This function is useful for servers as well as for clients; servers use it to determine which port they should listen on (see Listening). |
| struct servent * getservbyport (int port, const char *proto) | Function |
The getservbyport function returns information about the
service at port port using protocol proto. If it can't
find such a service, it returns a null pointer.
|
You can also scan the services database using setservent,
getservent, and endservent. Be careful in using these
functions, because they are not reentrant.
| void setservent (int stayopen) | Function |
|
This function opens the services database to begin scanning it.
If the stayopen argument is nonzero, this sets a flag so that
subsequent calls to |
| struct servent * getservent (void) | Function |
| This function returns the next entry in the services database. If there are no more entries, it returns a null pointer. |
| void endservent (void) | Function |
| This function closes the services database. |
Different kinds of computers use different conventions for the ordering of bytes within a word. Some computers put the most significant byte within a word first (this is called "big-endian" order), and others put it last ("little-endian" order).
So that machines with different byte order conventions can communicate, the Internet protocols specify a canonical byte order convention for data transmitted over the network. This is known as the network byte order.
When establishing an Internet socket connection, you must make sure that
the data in the sin_port and sin_addr members of the
sockaddr_in structure are represented in the network byte order.
If you are encoding integer data in the messages sent through the
socket, you should convert this to network byte order too. If you don't
do this, your program may fail when running on or talking to other kinds
of machines.
If you use getservbyname and gethostbyname or
inet_addr to get the port number and host address, the values are
already in the network byte order, and you can copy them directly into
the sockaddr_in structure.
Otherwise, you have to convert the values explicitly. Use htons
and ntohs to convert values for the sin_port member. Use
htonl and ntohl to convert IPv4 addresses for the
sin_addr member. (Remember, struct in_addr is equivalent
to uint32_t.) These functions are declared in
netinet/in.h.
| uint16_t htons (uint16_t hostshort) | Function |
This function converts the uint16_t integer hostshort from
host byte order to network byte order.
|
| uint16_t ntohs (uint16_t netshort) | Function |
This function converts the uint16_t integer netshort from
network byte order to host byte order.
|
| uint32_t htonl (uint32_t hostlong) | Function |
This function converts the uint32_t integer hostlong from
host byte order to network byte order.
This is used for IPv4 internet addresses. |
| uint32_t ntohl (uint32_t netlong) | Function |
This function converts the uint32_t integer netlong from
network byte order to host byte order.
This is used for IPv4 internet addresses. |
The communications protocol used with a socket controls low-level details of how data is exchanged. For example, the protocol implements things like checksums to detect errors in transmissions, and routing instructions for messages. Normal user programs have little reason to mess with these details directly.
The default communications protocol for the Internet namespace depends on the communication style. For stream communication, the default is TCP ("transmission control protocol"). For datagram communication, the default is UDP ("user datagram protocol"). For reliable datagram communication, the default is RDP ("reliable datagram protocol"). You should nearly always use the default.
Internet protocols are generally specified by a name instead of a
number. The network protocols that a host knows about are stored in a
database. This is usually either derived from the file
/etc/protocols, or it may be an equivalent provided by a name
server. You look up the protocol number associated with a named
protocol in the database using the getprotobyname function.
Here are detailed descriptions of the utilities for accessing the
protocols database. These are declared in netdb.h.
| struct protoent | Data Type |
This data type is used to represent entries in the network protocols
database. It has the following members:
|
You can use getprotobyname and getprotobynumber to search
the protocols database for a specific protocol. The information is
returned in a statically-allocated structure; you must copy the
information if you need to save it across calls.
| struct protoent * getprotobyname (const char *name) | Function |
The getprotobyname function returns information about the
network protocol named name. If there is no such protocol, it
returns a null pointer.
|
| struct protoent * getprotobynumber (int protocol) | Function |
The getprotobynumber function returns information about the
network protocol with number protocol. If there is no such
protocol, it returns a null pointer.
|
You can also scan the whole protocols database one protocol at a time by
using setprotoent, getprotoent, and endprotoent.
Be careful in using these functions, because they are not reentrant.
| void setprotoent (int stayopen) | Function |
|
This function opens the protocols database to begin scanning it.
If the stayopen argument is nonzero, this sets a flag so that
subsequent calls to |
| struct protoent * getprotoent (void) | Function |
| This function returns the next entry in the protocols database. It returns a null pointer if there are no more entries. |
| void endprotoent (void) | Function |
| This function closes the protocols database. |
Here is an example showing how to create and name a socket in the
Internet namespace. The newly created socket exists on the machine that
the program is running on. Rather than finding and using the machine's
Internet address, this example specifies INADDR_ANY as the host
address; the system replaces that with the machine's actual address.
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
int
make_socket (uint16_t port)
{
int sock;
struct sockaddr_in name;
/* Create the socket. */
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket");
exit (EXIT_FAILURE);
}
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (port);
name.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
perror ("bind");
exit (EXIT_FAILURE);
}
return sock;
}
Here is another example, showing how you can fill in a sockaddr_in
structure, given a host name string and a port number:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void
init_sockaddr (struct sockaddr_in *name,
const char *hostname,
uint16_t port)
{
struct hostent *hostinfo;
name->sin_family = AF_INET;
name->sin_port = htons (port);
hostinfo = gethostbyname (hostname);
if (hostinfo == NULL)
{
fprintf (stderr, "Unknown host %s.\n", hostname);
exit (EXIT_FAILURE);
}
name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
}
Certain other namespaces and associated protocol families are supported
but not documented yet because they are not often used. PF_NS
refers to the Xerox Network Software protocols. PF_ISO stands
for Open Systems Interconnect. PF_CCITT refers to protocols from
CCITT. socket.h defines these symbols and others naming protocols
not actually implemented.
PF_IMPLINK is used for communicating between hosts and Internet
Message Processors. For information on this, and on PF_ROUTE, an
occasionally-used local area routing protocol, see the GNU Hurd Manual
(to appear in the future).
This section describes the actual library functions for opening and closing sockets. The same functions work for all namespaces and connection styles.
The primitive for creating a socket is the socket function,
declared in sys/socket.h.
| int socket (int namespace, int style, int protocol) | Function |
This function creates a socket and specifies communication style
style, which should be one of the socket styles listed in
Communication Styles. The namespace argument specifies
the namespace; it must be PF_LOCAL (see Local Namespace) or
PF_INET (see Internet Namespace). protocol
designates the specific protocol (see Socket Concepts); zero is
usually right for protocol.
The return value from
The file descriptor returned by the |
For examples of how to call the socket function,
see Local Socket Example, or Inet Example.
When you are finished using a socket, you can simply close its
file descriptor with close; see Opening and Closing Files.
If there is still data waiting to be transmitted over the connection,
normally close tries to complete this transmission. You
can control this behavior using the SO_LINGER socket option to
specify a timeout period; see Socket Options.
You can also shut down only reception or only transmission on a
connection by calling shutdown, which is declared in
sys/socket.h.
| int shutdown (int socket, int how) | Function |
The shutdown function shuts down the connection of socket
socket. The argument how specifies what action to
perform:
The return value is
|
A socket pair consists of a pair of connected (but unnamed)
sockets. It is very similar to a pipe and is used in much the same
way. Socket pairs are created with the socketpair function,
declared in sys/socket.h. A socket pair is much like a pipe; the
main difference is that the socket pair is bidirectional, whereas the
pipe has one input-only end and one output-only end (see Pipes and FIFOs).
| int socketpair (int namespace, int style, int protocol, int filedes[2]) | Function |
This function creates a socket pair, returning the file descriptors in
filedes[0] and filedes[1]. The socket pair
is a full-duplex communications channel, so that both reading and writing
may be performed at either end.
The namespace, style, and protocol arguments are
interpreted as for the If style specifies a connectionless communication style, then the two sockets you get are not connected, strictly speaking, but each of them knows the other as the default destination address, so they can send packets to each other. The
|
The most common communication styles involve making a connection to a particular other socket, and then exchanging data with that socket over and over. Making a connection is asymmetric; one side (the client) acts to request a connection, while the other side (the server) makes a socket and waits for the connection request.
In making a connection, the client makes a connection while the server
waits for and accepts the connection. Here we discuss what the client
program must do, using the connect function, which is declared in
sys/socket.h.
| int connect (int socket, struct sockaddr *addr, socklen_t length) | Function |
The connect function initiates a connection from the socket
with file descriptor socket to the socket whose address is
specified by the addr and length arguments. (This socket
is typically on another machine, and it must be already set up as a
server.) See Socket Addresses, for information about how these
arguments are interpreted.
Normally, The normal return value from
This function is defined as a cancelation point in multi-threaded programs. So one has to be prepared for this and make sure that possibly allocated resources (like memory, files descriptors, semaphores or whatever) are freed even if the thread is canceled. |
Now let us consider what the server process must do to accept
connections on a socket. First it must use the listen function
to enable connection requests on the socket, and then accept each
incoming connection with a call to accept (see Accepting Connections). Once connection requests are enabled on a server socket,
the select function reports when the socket has a connection
ready to be accepted (see Waiting for I/O).
The listen function is not allowed for sockets using
connectionless communication styles.
You can write a network server that does not even start running until a connection to it is requested. See Inetd Servers.
In the Internet namespace, there are no special protection mechanisms for controlling access to connect to a port; any process on any machine can make a connection to your server. If you want to restrict access to your server, make it examine the addresses associated with connection requests or implement some other handshaking or identification protocol.
In the local namespace, the ordinary file protection bits control who has access to connect to the socket.
| int listen (int socket, unsigned int n) | Function |
The listen function enables the socket socket to accept
connections, thus making it a server socket.
The argument n specifies the length of the queue for pending
connections. When the queue fills, new clients attempting to connect
fail with The
|
When a server receives a connection request, it can complete the
connection by accepting the request. Use the function accept
to do this.
A socket that has been established as a server can accept connection
requests from multiple clients. The server's original socket
does not become part of the connection; instead, accept
makes a new socket which participates in the connection.
accept returns the descriptor for this socket. The server's
original socket remains available for listening for further connection
requests.
The number of pending connection requests on a server socket is finite.
If connection requests arrive from clients faster than the server can
act upon them, the queue can fill up and additional requests are refused
with a ECONNREFUSED error. You can specify the maximum length of
this queue as an argument to the listen function, although the
system may also impose its own internal limit on the length of this
queue.
| int accept (int socket, struct sockaddr *addr, socklen_t *length_ptr) | Function |
|
This function is used to accept a connection request on the server
socket socket.
The The addr and length-ptr arguments are used to return information about the name of the client socket that initiated the connection. See Socket Addresses, for information about the format of the information. Accepting a connection does not make socket part of the
connection. Instead, it creates a new socket which becomes
connected. The normal return value of After If an error occurs,
This function is defined as a cancelation point in multi-threaded programs. So one has to be prepared for this and make sure that possibly allocated resources (like memory, files descriptors, semaphores or whatever) are freed even if the thread is canceled. |
The accept function is not allowed for sockets using
connectionless communication styles.
| int getpeername (int socket, struct sockaddr *addr, socklen_t *length-ptr) | Function |
The getpeername function returns the address of the socket that
socket is connected to; it stores the address in the memory space
specified by addr and length-ptr. It stores the length of
the address in *length-ptr.
See Socket Addresses, for information about the format of the
address. In some operating systems, The return value is
|
Once a socket has been connected to a peer, you can use the ordinary
read and write operations (see I/O Primitives) to
transfer data. A socket is a two-way communications channel, so read
and write operations can be performed at either end.
There are also some I/O modes that are specific to socket operations.
In order to specify these modes, you must use the recv and
send functions instead of the more generic read and
write functions. The recv and send functions take
an additional argument which you can use to specify various flags to
control the special I/O modes. For example, you can specify the
MSG_OOB flag to read or write out-of-band data, the
MSG_PEEK flag to peek at input, or the MSG_DONTROUTE flag
to control inclusion of routing information on output.
send.
recv.
send and recv.
The send function is declared in the header file
sys/socket.h. If your flags argument is zero, you can just
as well use write instead of send; see I/O Primitives. If the socket was connected but the connection has broken,
you get a SIGPIPE signal for any use of send or
write (see Miscellaneous Signals).
| int send (int socket, void *buffer, size_t size, int flags) | Function |
The send function is like write, but with the additional
flags flags. The possible values of flags are described
in Socket Data Options.
This function returns the number of bytes transmitted, or Note, however, that a successful return value merely indicates that the message has been sent without error, not necessarily that it has been received without error. The following
This function is defined as a cancelation point in multi-threaded programs. So one has to be prepared for this and make sure that possibly allocated resources (like memory, files descriptors, semaphores or whatever) are freed even if the thread is canceled. |
The recv function is declared in the header file
sys/socket.h. If your flags argument is zero, you can
just as well use read instead of recv; see I/O Primitives.
| int recv (int socket, void *buffer, size_t size, int flags) | Function |
The recv function is like read, but with the additional
flags flags. The possible values of flags are described
in Socket Data Options.
If nonblocking mode is set for socket, and no data is available to
be read, This function returns the number of bytes received, or
This function is defined as a cancelation point in multi-threaded programs. So one has to be prepared for this and make sure that possibly allocated resources (like memory, files descriptors, semaphores or whatever) are freed even if the thread is canceled. |
The flags argument to send and recv is a bit
mask. You can bitwise-OR the values of the following macros together
to obtain a value for this argument. All are defined in the header
file sys/socket.h.
| int MSG_OOB | Macro |
| Send or receive out-of-band data. See Out-of-Band Data. |
| int MSG_PEEK | Macro |
Look at the data but don't remove it from the input queue. This is
only meaningful with input functions such as recv, not with
send.
|
| int MSG_DONTROUTE | Macro |
| Don't include routing information in the message. This is only meaningful with output operations, and is usually only of interest for diagnostic or routing programs. We don't try to explain it here. |
Here is an example client program that makes a connection for a byte stream socket in the Internet namespace. It doesn't do anything particularly interesting once it has connected to the server; it just sends a text string to the server and exits.
This program uses init_sockaddr to set up the socket address; see
Inet Example.
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 5555
#define MESSAGE "Yow!!! Are we having fun yet?!?"
#define SERVERHOST "mescaline.gnu.org"
void
write_to_server (int filedes)
{
int nbytes;
nbytes = write (filedes, MESSAGE, strlen (MESSAGE) + 1);
if (nbytes < 0)
{
perror ("write");
exit (EXIT_FAILURE);
}
}
int
main (void)
{
extern void init_sockaddr (struct sockaddr_in *name,
const char *hostname,
uint16_t port);
int sock;
struct sockaddr_in servername;
/* Create the socket. */
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket (client)");
exit (EXIT_FAILURE);
}
/* Connect to the server. */
init_sockaddr (&servername, SERVERHOST, PORT);
if (0 > connect (sock,
(struct sockaddr *) &servername,
sizeof (servername)))
{
perror ("connect (client)");
exit (EXIT_FAILURE);
}
/* Send data to the server. */
write_to_server (sock);
close (sock);
exit (EXIT_SUCCESS);
}
The server end is much more complicated. Since we want to allow
multiple clients to be connected to the server at the same time, it
would be incorrect to wait for input from a single client by simply
calling read or recv. Instead, the right thing to do is
to use select (see Waiting for I/O) to wait for input on
all of the open sockets. This also allows the server to deal with
additional connection requests.
This particular server doesn't do anything interesting once it has gotten a message from a client. It does close the socket for that client when it detects an end-of-file condition (resulting from the client shutting down its end of the connection).
This program uses make_socket to set up the socket address; see
Inet Example.
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 5555
#define MAXMSG 512
int
read_from_client (int filedes)
{
char buffer[MAXMSG];
int nbytes;
nbytes = read (filedes, buffer, MAXMSG);
if (nbytes < 0)
{
/* Read error. */
perror ("read");
exit (EXIT_FAILURE);
}
else if (nbytes == 0)
/* End-of-file. */
return -1;
else
{
/* Data read. */
fprintf (stderr, "Server: got message: `%s'\n", buffer);
return 0;
}
}
int
main (void)
{
extern int make_socket (uint16_t port);
int sock;
fd_set active_fd_set, read_fd_set;
int i;
struct sockaddr_in clientname;
size_t size;
/* Create the socket and set it up to accept connections. */
sock = make_socket (PORT);
if (listen (sock, 1) < 0)
{
perror ("listen");
exit (EXIT_FAILURE);
}
/* Initialize the set of active sockets. */
FD_ZERO (&active_fd_set);
FD_SET (sock, &active_fd_set);
while (1)
{
/* Block until input arrives on one or more active sockets. */
read_fd_set = active_fd_set;
if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
{
perror ("select");
exit (EXIT_FAILURE);
}
/* Service all the sockets with input pending. */
for (i = 0; i < FD_SETSIZE; ++i)
if (FD_ISSET (i, &read_fd_set))
{
if (i == sock)
{
/* Connection request on original socket. */
int new;
size = sizeof (clientname);
new = accept (sock,
(struct sockaddr *) &clientname,
&size);
if (new < 0)
{
perror ("accept");
exit (EXIT_FAILURE);
}
fprintf (stderr,
"Server: connect from host %s, port %hd.\n",
inet_ntoa (clientname.sin_addr),
ntohs (clientname.sin_port));
FD_SET (new, &active_fd_set);
}
else
{
/* Data arriving on an already-connected socket. */
if (read_from_client (i) < 0)
{
close (i);
FD_CLR (i, &active_fd_set);
}
}
}
}
}
Streams with connections permit out-of-band data that is
delivered with higher priority than ordinary data. Typically the
reason for sending out-of-band data is to send notice of an
exceptional condition. The way to send out-of-band data is using
send, specifying the flag MSG_OOB (see Sending Data).
Out-of-band data is received with higher priority because the
receiving process need not read it in sequence; to read the next
available out-of-band data, use recv with the MSG_OOB
flag (see Receiving Data). Ordinary read operations do not read
out-of-band data; they read only the ordinary data.
When a socket finds that out-of-band data is on its way, it sends a
SIGURG signal to the owner process or process group of the
socket. You can specify the owner using the F_SETOWN command
to the fcntl function; see Interrupt Input. You must
also establish a handler for this signal, as described in Signal Handling, in order to take appropriate action such as reading the
out-of-band data.
Alternatively, you can test for pending out-of-band data, or wait
until there is out-of-band data, using the select function; it
can wait for an exceptional condition on the socket. See Waiting for I/O, for more information about select.
Notification of out-of-band data (whether with SIGURG or with
select) indicates that out-of-band data is on the way; the data
may not actually arrive until later. If you try to read the
out-of-band data before it arrives, recv fails with an
EWOULDBLOCK error.
Sending out-of-band data automatically places a "mark" in the stream of ordinary data, showing where in the sequence the out-of-band data "would have been". This is useful when the meaning of out-of-band data is "cancel everything sent so far". Here is how you can test, in the receiving process, whether any ordinary data was sent before the mark:
success = ioctl (socket, SIOCATMARK, &atmark);
The integer variable atmark is set to a nonzero value if
the socket's read pointer has reached the "mark".
Here's a function to discard any ordinary data preceding the out-of-band mark:
int
discard_until_mark (int socket)
{
while (1)
{
/* This is not an arbitrary limit; any size will do. */
char buffer[1024];
int atmark, success;
/* If we have reached the mark, return. */
success = ioctl (socket, SIOCATMARK, &atmark);
if (success < 0)
perror ("ioctl");
if (result)
return;
/* Otherwise, read a bunch of ordinary data and discard it.
This is guaranteed not to read past the mark
if it starts before the mark. */
success = read (socket, buffer, sizeof buffer);
if (success < 0)
perror ("read");
}
}
If you don't want to discard the ordinary data preceding the mark, you
may need to read some of it anyway, to make room in internal system
buffers for the out-of-band data. If you try to read out-of-band data
and get an EWOULDBLOCK error, try reading some ordinary data
(saving it so that you can use it when you want it) and see if that
makes room. Here is an example:
struct buffer
{
char *buffer;
int size;
struct buffer *next;
};
/* Read the out-of-band data from SOCKET and return it
as a `struct buffer', which records the address of the data
and its size.
It may be necessary to read some ordinary data
in order to make room for the out-of-band data.
If so, the ordinary data is saved as a chain of buffers
found in the `next' field of the value. */
struct buffer *
read_oob (int socket)
{
struct buffer *tail = 0;
struct buffer *list = 0;
while (1)
{
/* This is an arbitrary limit.
Does anyone know how to do this without a limit? */
char *buffer = (char *) xmalloc (1024);
int success;
int atmark;
/* Try again to read the out-of-band data. */
success = recv (socket, buffer, sizeof buffer, MSG_OOB);
if (success >= 0)
{
/* We got it, so return it. */
struct buffer *link
= (struct buffer *) xmalloc (sizeof (struct buffer));
link->buffer = buffer;
link->size = success;
link->next = list;
return link;
}
/* If we fail, see if we are at the mark. */
success = ioctl (socket, SIOCATMARK, &atmark);
if (success < 0)
perror ("ioctl");
if (atmark)
{
/* At the mark; skipping past more ordinary data cannot help.
So just wait a while. */
sleep (1);
continue;
}
/* Otherwise, read a bunch of ordinary data and save it.
This is guaranteed not to read past the mark
if it starts before the mark. */
success = read (socket, buffer, sizeof buffer);
if (success < 0)
perror ("read");
/* Save this data in the buffer list. */
{
struct buffer *link
= (struct buffer *) xmalloc (sizeof (struct buffer));
link->buffer = buffer;
link->size = success;
/* Add the new link to the end of the list. */
if (tail)
tail->next = link;
else
list = link;
tail = link;
}
}
}
This section describes how to use communication styles that don't use
connections (styles SOCK_DGRAM and SOCK_RDM). Using
these styles, you group data into packets and each packet is an
independent communication. You specify the destination for each
packet individually.
Datagram packets are like letters: you send each one independently, with its own destination address, and they may arrive in the wrong order or not at all.
The listen and accept functions are not allowed for
sockets using connectionless communication styles.
The normal way of sending data on a datagram socket is by using the
sendto function, declared in sys/socket.h.
You can call connect on a datagram socket, but this only
specifies a default destination for further data transmission on the
socket. When a socket has a default destination, then you can use
send (see Sending Data) or even write (see I/O Primitives) to send a packet there. You can cancel the default
destination by calling connect using an address format of
AF_UNSPEC in the addr argument. See Connecting, for
more information about the connect function.
| int sendto (int socket, void *buffer. size_t size, int flags, struct sockaddr *addr, socklen_t length) | Function |
The sendto function transmits the data in the buffer
through the socket socket to the destination address specified
by the addr and length arguments. The size argument
specifies the number of bytes to be transmitted.
The flags are interpreted the same way as for The return value and error conditions are also the same as for
It is also possible for one call to This function is defined as a cancelation point in multi-threaded programs. So one has to be prepared for this and make sure that possibly allocated resources (like memory, files descriptors, semaphores or whatever) are freed even if the thread is canceled. |
The recvfrom function reads a packet from a datagram socket and
also tells you where it was sent from. This function is declared in
sys/socket.h.
| int recvfrom (int socket, void *buffer, size_t size, int flags, struct sockaddr *addr, socklen_t *length-ptr) | Function |
The recvfrom function reads one packet from the socket
socket into the buffer buffer. The size argument
specifies the maximum number of bytes to be read.
If the packet is longer than size bytes, then you get the first size bytes of the packet, and the rest of the packet is lost. There's no way to read the rest of the packet. Thus, when you use a packet protocol, you must always know how long a packet to expect. The addr and length-ptr arguments are used to return the address where the packet came from. See Socket Addresses. For a socket in the local domain, the address information won't be meaningful, since you can't read the address of such a socket (see Local Namespace). You can specify a null pointer as the addr argument if you are not interested in this information. The flags are interpreted the same way as for This function is defined as a cancelation point in multi-threaded programs. So one has to be prepared for this and make sure that possibly allocated resources (like memory, files descriptors, semaphores or whatever) are freed even if the thread is canceled. |
You can use plain recv (see Receiving Data) instead of
recvfrom if you know don't need to find out who sent the packet
(either because you know where it should come from or because you
treat all possible senders alike). Even read can be used if
you don't want to specify flags (see I/O Primitives).
Here is a set of example programs that send messages over a datagram
stream in the local namespace. Both the client and server programs use
the make_named_socket function that was presented in Local Socket Example, to create and name their sockets.
First, here is the server program. It sits in a loop waiting for messages to arrive, bouncing each message back to the sender. Obviously, this isn't a particularly useful program, but it does show the general ideas involved.
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SERVER "/tmp/serversocket"
#define MAXMSG 512
int
main (void)
{
int sock;
char message[MAXMSG];
struct sockaddr_un name;
size_t size;
int nbytes;
/* Remove the filename first, it's ok if the call fails */
unlink (SERVER);
/* Make the socket, then loop endlessly. */
sock = make_named_socket (SERVER);
while (1)
{
/* Wait for a datagram. */
size = sizeof (name);
nbytes = recvfrom (sock, message, MAXMSG, 0,
(struct sockaddr *) & name, &size);
if (nbytes < 0)
{
perror ("recfrom (server)");
exit (EXIT_FAILURE);
}
/* Give a diagnostic message. */
fprintf (stderr, "Server: got message: %s\n", message);
/* Bounce the message back to the sender. */
nbytes = sendto (sock, message, nbytes, 0,
(struct sockaddr *) & name, size);
if (nbytes < 0)
{
perror ("sendto (server)");
exit (EXIT_FAILURE);
}
}
}
Here is the client program corresponding to the server above.
It sends a datagram to the server and then waits for a reply. Notice that the socket for the client (as well as for the server) in this example has to be given a name. This is so that the server can direct a message back to the client. Since the socket has no associated connection state, the only way the server can do this is by referencing the name of the client.
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SERVER "/tmp/serversocket"
#define CLIENT "/tmp/mysocket"
#define MAXMSG 512
#define MESSAGE "Yow!!! Are we having fun yet?!?"
int
main (void)
{
extern int make_named_socket (const char *name);
int sock;
char message[MAXMSG];
struct sockaddr_un name;
size_t size;
int nbytes;
/* Make the socket. */
sock = make_named_socket (CLIENT);
/* Initialize the server socket address. */
name.sun_family = AF_LOCAL;
strcpy (name.sun_path, SERVER);
size = strlen (name.sun_path) + sizeof (name.sun_family);
/* Send the datagram. */
nbytes = sendto (sock, MESSAGE, strlen (MESSAGE) + 1, 0,
(struct sockaddr *) & name, size);
if (nbytes < 0)
{
perror ("sendto (client)");
exit (EXIT_FAILURE);
}
/* Wait for a reply. */
nbytes = recvfrom (sock, message, MAXMSG, 0, NULL, 0);
if (nbytes < 0)
{
perror ("recfrom (client)");
exit (EXIT_FAILURE);
}
/* Print a diagnostic message. */
fprintf (stderr, "Client: got message: %s\n", message);
/* Clean up. */
remove (CLIENT);
close (sock);
}
Keep in mind that datagram socket communications are unreliable. In
this example, the client program waits indefinitely if the message
never reaches the server or if the server's response never comes
back. It's up to the user running the program to kill it and restart
it, if desired. A more automatic solution could be to use
select (see Waiting for I/O) to establish a timeout period
for the reply, and in case of timeout either resend the message or
shut down the socket and exit.
inetd DaemonWe've explained above how to write a server program that does its own listening. Such a server must already be running in order for anyone to connect to it.
Another way to provide service for an Internet port is to let the daemon
program inetd do the listening. inetd is a program that
runs all the time and waits (using select) for messages on a
specified set of ports. When it receives a message, it accepts the
connection (if the socket style calls for connections) and then forks a
child process to run the corresponding server program. You specify the
ports and their programs in the file /etc/inetd.conf.
inetd ServersWriting a server program to be run by inetd is very simple. Each time
someone requests a connection to the appropriate port, a new server
process starts. The connection already exists at this time; the
socket is available as the standard input descriptor and as the
standard output descriptor (descriptors 0 and 1) in the server
process. So the server program can begin reading and writing data
right away. Often the program needs only the ordinary I/O facilities;
in fact, a general-purpose filter program that knows nothing about
sockets can work as a byte stream server run by inetd.
You can also use inetd for servers that use connectionless
communication styles. For these servers, inetd does not try to accept
a connection, since no connection is possible. It just starts the
server program, which can read the incoming datagram packet from
descriptor 0. The server program can handle one request and then
exit, or you can choose to write it to keep reading more requests
until no more arrive, and then exit. You must specify which of these
two techniques the server uses, when you configure inetd.
inetdThe file /etc/inetd.conf tells inetd which ports to listen to
and what server programs to run for them. Normally each entry in the
file is one line, but you can split it onto multiple lines provided
all but the first line of the entry start with whitespace. Lines that
start with # are comments.
Here are two standard entries in /etc/inetd.conf:
ftp stream tcp nowait root /libexec/ftpd ftpd talk dgram udp wait root /libexec/talkd talkd
An entry has this format:
service style protocol wait username program arguments
The service field says which service this program provides. It
should be the name of a service defined in /etc/services.
inetd uses service to decide which port to listen on for
this entry.
The fields style and protocol specify the communication
style and the protocol to use for the listening socket. The style
should be the name of a communication style, converted to lower case
and with SOCK_ deleted--for example, stream or
dgram. protocol should be one of the protocols listed in
/etc/protocols. The typical protocol names are tcp for
byte stream connections and udp for unreliable datagrams.
The wait field should be either wait or nowait.
Use wait if style is a connectionless style and the
server, once started, handles multiple requests, as many as come in.
Use nowait if inetd should start a new process for each message
or request that comes in. If style uses connections, then
wait must be nowait.
user is the user name that the server should run as. inetd runs
as root, so it can set the user ID of its children arbitrarily. It's
best to avoid using root for user if you can; but some
servers, such as Telnet and FTP, read a username and password
themselves. These servers need to be root initially so they can log
in as commanded by the data coming over the network.
program together with arguments specifies the command to run to start the server. program should be an absolute file name specifying the executable file to run. arguments consists of any number of whitespace-separated words, which become the command-line arguments of program. The first word in arguments is argument zero, which should by convention be the program name itself (sans directories).
If you edit /etc/inetd.conf, you can tell inetd to reread the
file and obey its new contents by sending the inetd process the
SIGHUP signal. You'll have to use ps to determine the
process ID of the inetd process, as it is not fixed.
This section describes how to read or set various options that modify the behavior of sockets and their underlying communications protocols.
When you are manipulating a socket option, you must specify which level the option pertains to. This describes whether the option applies to the socket interface, or to a lower-level communications protocol interface.
Here are the functions for examining and modifying socket options.
They are declared in sys/socket.h.
| int getsockopt (int socket, int level, int optname, void *optval, socklen_t *optlen-ptr) | Function |
The getsockopt function gets information about the value of
option optname at level level for socket socket.
The option value is stored in a buffer that optval points to.
Before the call, you should supply in Most options interpret the optval buffer as a single The actual return value of
|
| int setsockopt (int socket, int level, int optname, void *optval, socklen_t optlen) | Function |
| This function is used to set the socket option optname at level level for socket socket. The value of the option is passed in the buffer optval, which has size optlen. |
| int SOL_SOCKET | Constant |
Use this constant as the level argument to getsockopt or
setsockopt to manipulate the socket-level options described in
this section.
|
Here is a table of socket-level option names; all are defined in the
header file sys/socket.h.
SO_DEBUG
int; a nonzero value means
"yes".
SO_REUSEADDR
bind (see Setting Address)
should permit reuse of local addresses for this socket. If you enable
this option, you can actually have two sockets with the same Internet
port number; but the system won't allow you to use the two
identically-named sockets in a way that would confuse the Internet. The
reason for this option is that some higher-level Internet protocols,
including FTP, require you to keep reusing the same port number.
The value has type int; a nonzero value means "yes".
SO_KEEPALIVE
int; a nonzero value means
"yes".
SO_DONTROUTE
int; a nonzero
value means "yes".
SO_LINGER
struct linger.
| struct linger | Data Type |
This structure type has the following members:
|
SO_BROADCAST
int; a nonzero value means "yes".
SO_OOBINLINE
read or recv without specifying the MSG_OOB
flag. See Out-of-Band Data. The value has type int; a
nonzero value means "yes".
SO_SNDBUF
size_t, which is the size in bytes.
SO_RCVBUF
size_t, which is the size in bytes.
SO_STYLE
SO_TYPE
getsockopt only. It is used to
get the socket's communication style. SO_TYPE is the
historical name, and SO_STYLE is the preferred name in GNU.
The value has type int and its value designates a communication
style; see Communication Styles.
SO_ERROR
getsockopt only. It is used to reset
the error status of the socket. The value is an int, which represents
the previous error status.
Many systems come with a database that records a list of networks known
to the system developer. This is usually kept either in the file
/etc/networks or in an equivalent from a name server. This data
base is useful for routing programs such as route, but it is not
useful for programs that simply communicate over the network. We
provide functions to access this data base, which are declared in
netdb.h.
| struct netent | Data Type |
This data type is used to represent information about entries in the
networks database. It has the following members:
|
Use the getnetbyname or getnetbyaddr functions to search
the networks database for information about a specific network. The
information is returned in a statically-allocated structure; you must
copy the information if you need to save it.
| struct netent * getnetbyname (const char *name) | Function |
The getnetbyname function returns information about the network
named name. It returns a null pointer if there is no such
network.
|
| struct netent * getnetbyaddr (unsigned long int net, int type) | Function |
The getnetbyaddr function returns information about the network
of type type with number net. You should specify a value of
AF_INET for the type argument for Internet networks.
|
You can also scan the networks database using setnetent,
getnetent, and endnetent. Be careful in using these
functions, because they are not reentrant.
| void setnetent (int stayopen) | Function |
|
This function opens and rewinds the networks database.
If the stayopen argument is nonzero, this sets a flag so that
subsequent calls to |
| struct netent * getnetent (void) | Function |
| This function returns the next entry in the networks database. It returns a null pointer if there are no more entries. |
| void endnetent (void) | Function |
| This function closes the networks database. |
This chapter describes functions that are specific to terminal devices. You can use these functions to do things like turn off input echoing; set serial line characteristics such as line speed and flow control; and change which characters are used for end-of-file, command-line editing, sending signals, and similar control functions.
Most of the functions in this chapter operate on file descriptors. See Low-Level I/O, for more information about what a file descriptor is and how to open a file descriptor for a terminal device.
The functions described in this chapter only work on files that
correspond to terminal devices. You can find out whether a file
descriptor is associated with a terminal by using the isatty
function.
Prototypes for the functions in this section are declared in the header
file unistd.h.
| int isatty (int filedes) | Function |
This function returns 1 if filedes is a file descriptor
associated with an open terminal device, and 0 otherwise.
|
If a file descriptor is associated with a terminal, you can get its
associated file name using the ttyname function. See also the
ctermid function, described in Identifying the Terminal.
| char * ttyname (int filedes) | Function |
If the file descriptor filedes is associated with a terminal
device, the ttyname function returns a pointer to a
statically-allocated, null-terminated string containing the file name of
the terminal file. The value is a null pointer if the file descriptor
isn't associated with a terminal, or the file name cannot be determined.
|
| int ttyname_r (int filedes, char *buf, size_t len) | Function |
The ttyname_r function is similar to the ttyname function
except that it places its result into the user-specified buffer starting
at buf with length len.
The normal return value from
|
Many of the remaining functions in this section refer to the input and output queues of a terminal device. These queues implement a form of buffering within the kernel independent of the buffering implemented by I/O streams (see I/O on Streams).
The terminal input queue is also sometimes referred to as its typeahead buffer. It holds the characters that have been received from the terminal but not yet read by any process.
The size of the input queue is described by the MAX_INPUT and
_POSIX_MAX_INPUT parameters; see Limits for Files. You
are guaranteed a queue size of at least MAX_INPUT, but the queue
might be larger, and might even dynamically change size. If input flow
control is enabled by setting the IXOFF input mode bit
(see Input Modes), the terminal driver transmits STOP and START
characters to the terminal when necessary to prevent the queue from
overflowing. Otherwise, input may be lost if it comes in too fast from
the terminal. In canonical mode, all input stays in the queue until a
newline character is received, so the terminal input queue can fill up
when you type a very long line. See Canonical or Not.
The terminal output queue is like the input queue, but for output;
it contains characters that have been written by processes, but not yet
transmitted to the terminal. If output flow control is enabled by
setting the IXON input mode bit (see Input Modes), the
terminal driver obeys START and STOP characters sent by the terminal to
stop and restart transmission of output.
Clearing the terminal input queue means discarding any characters that have been received but not yet read. Similarly, clearing the terminal output queue means discarding any characters that have been written but not yet transmitted.
POSIX systems support two basic modes of input: canonical and noncanonical.
In canonical input processing mode, terminal input is processed in
lines terminated by newline ('\n'), EOF, or EOL characters. No
input can be read until an entire line has been typed by the user, and
the read function (see I/O Primitives) returns at most a
single line of input, no matter how many bytes are requested.
In canonical input mode, the operating system provides input editing facilities: some characters are interpreted specially to perform editing operations within the current line of text, such as ERASE and KILL. See Editing Characters.
The constants _POSIX_MAX_CANON and MAX_CANON parameterize
the maximum number of bytes which may appear in a single line of
canonical input. See Limits for Files. You are guaranteed a maximum
line length of at least MAX_CANON bytes, but the maximum might be
larger, and might even dynamically change size.
In noncanonical input processing mode, characters are not grouped into lines, and ERASE and KILL processing is not performed. The granularity with which bytes are read in noncanonical input mode is controlled by the MIN and TIME settings. See Noncanonical Input.
Most programs use canonical input mode, because this gives the user a way to edit input line by line. The usual reason to use noncanonical mode is when the program accepts single-character commands or provides its own editing facilities.
The choice of canonical or noncanonical input is controlled by the
ICANON flag in the c_lflag member of struct termios.
See Local Modes.
This section describes the various terminal attributes that control how
input and output are done. The functions, data structures, and symbolic
constants are all declared in the header file termios.h.
struct termios and
related types.
The entire collection of attributes of a terminal is stored in a
structure of type struct termios. This structure is used
with the functions tcgetattr and tcsetattr to read
and set the attributes.
| struct termios | Data Type |
Structure that records all the I/O attributes of a terminal. The
structure includes at least the following members:
The |
The following sections describe the details of the members of the
struct termios structure.
| tcflag_t | Data Type |
| This is an unsigned integer type used to represent the various bit masks for terminal flags. |
| cc_t | Data Type |
| This is an unsigned integer type used to represent characters associated with various terminal control functions. |
| int NCCS | Macro |
The value of this macro is the number of elements in the c_cc
array.
|
| int tcgetattr (int filedes, struct termios *termios-p) | Function |
|
This function is used to examine the attributes of the terminal
device with file descriptor filedes. The attributes are returned
in the structure that termios-p points to.
If successful,
|
| int tcsetattr (int filedes, int when, const struct termios *termios-p) | Function |
|
This function sets the attributes of the terminal device with file
descriptor filedes. The new attributes are taken from the
structure that termios-p points to.
The when argument specifies how to deal with input and output already queued. It can be one of the following values:
If this function is called from a background process on its controlling
terminal, normally all processes in the process group are sent a
If successful,
|
Although tcgetattr and tcsetattr specify the terminal
device with a file descriptor, the attributes are those of the terminal
device itself and not of the file descriptor. This means that the
effects of changing terminal attributes are persistent; if another
process opens the terminal file later on, it will see the changed
attributes even though it doesn't have anything to do with the open file
descriptor you originally specified in changing the attributes.
Similarly, if a single process has multiple or duplicated file descriptors for the same terminal device, changing the terminal attributes affects input and output to all of these file descriptors. This means, for example, that you can't open one file descriptor or stream to read from a terminal in the normal line-buffered, echoed mode; and simultaneously have another file descriptor for the same terminal that you use to read from it in single-character, non-echoed mode. Instead, you have to explicitly switch the terminal back and forth between the two modes.
When you set terminal modes, you should call tcgetattr first to
get the current modes of the particular terminal device, modify only
those modes that you are really interested in, and store the result with
tcsetattr.
It's a bad idea to simply initialize a struct termios structure
to a chosen set of attributes and pass it directly to tcsetattr.
Your program may be run years from now, on systems that support members
not documented in this manual. The way to avoid setting these members
to unreasonable values is to avoid changing them.
What's more, different terminal devices may require different mode settings in order to function properly. So you should avoid blindly copying attributes from one terminal device to another.
When a member contains a collection of independent flags, as the
c_iflag, c_oflag and c_cflag members do, even
setting the entire member is a bad idea, because particular operating
systems have their own flags. Instead, you should start with the
current value of the member and alter only the flags whose values matter
in your program, leaving any other flags unchanged.
Here is an example of how to set one flag (ISTRIP) in the
struct termios structure while properly preserving all the other
data in the structure:
int
set_istrip (int desc, int value)
{
struct termios settings;
int result;
result = tcgetattr (desc, &settings);
if (result < 0)
{
perror ("error in tcgetattr");
return 0;
}
settings.c_iflag &= ~ISTRIP;
if (value)
settings.c_iflag |= ISTRIP;
result = tcsetattr (desc, TCSANOW, &settings);
if (result < 0)
{
perror ("error in tcgetattr");
return;
}
return 1;
}
This section describes the terminal attribute flags that control fairly low-level aspects of input processing: handling of parity errors, break signals, flow control, and <RET> and <LFD> characters.
All of these flags are bits in the c_iflag member of the
struct termios structure. The member is an integer, and you
change flags using the operators &, | and ^. Don't
try to specify the entire value for c_iflag--instead, change
only specific flags and leave the rest untouched (see Setting Modes).
| tcflag_t INPCK | Macro |
|
If this bit is set, input parity checking is enabled. If it is not set,
no checking at all is done for parity errors on input; the
characters are simply passed through to the application.
Parity checking on input processing is independent of whether parity
detection and generation on the underlying terminal hardware is enabled;
see Control Modes. For example, you could clear the If this bit is set, what happens when a parity error is detected depends
on whether the |
| tcflag_t IGNPAR | Macro |
If this bit is set, any byte with a framing or parity error is ignored.
This is only useful if INPCK is also set.
|
| tcflag_t PARMRK | Macro |
If this bit is set, input bytes with parity or framing errors are marked
when passed to the program. This bit is meaningful only when
INPCK is set and IGNPAR is not set.
The way erroneous bytes are marked is with two preceding bytes,
If a valid byte has the value |
| tcflag_t ISTRIP | Macro |
| If this bit is set, valid input bytes are stripped to seven bits; otherwise, all eight bits are available for programs to read. |
| tcflag_t IGNBRK | Macro |
|
If this bit is set, break conditions are ignored.
A break condition is defined in the context of asynchronous serial data transmission as a series of zero-value bits longer than a single byte. |
| tcflag_t BRKINT | Macro |
If this bit is set and IGNBRK is not set, a break condition
clears the terminal input and output queues and raises a SIGINT
signal for the foreground process group associated with the terminal.
If neither |
| tcflag_t IGNCR | Macro |
If this bit is set, carriage return characters ('\r') are
discarded on input. Discarding carriage return may be useful on
terminals that send both carriage return and linefeed when you type the
<RET> key.
|
| tcflag_t ICRNL | Macro |
If this bit is set and IGNCR is not set, carriage return characters
('\r') received as input are passed to the application as newline
characters ('\n').
|
| tcflag_t INLCR | Macro |
If this bit is set, newline characters ('\n') received as input
are passed to the application as carriage return characters ('\r').
|
| tcflag_t IXOFF | Macro |
| If this bit is set, start/stop control on input is enabled. In other words, the computer sends STOP and START characters as necessary to prevent input from coming in faster than programs are reading it. The idea is that the actual terminal hardware that is generating the input data responds to a STOP character by suspending transmission, and to a START character by resuming transmission. See Start/Stop Characters. |
| tcflag_t IXON | Macro |
| If this bit is set, start/stop control on output is enabled. In other words, if the computer receives a STOP character, it suspends output until a START character is received. In this case, the STOP and START characters are never passed to the application program. If this bit is not set, then START and STOP can be read as ordinary characters. See Start/Stop Characters. |
| tcflag_t IXANY | Macro |
|
If this bit is set, any input character restarts output when output has
been suspended with the STOP character. Otherwise, only the START
character restarts output.
This is a BSD extension; it exists only on BSD systems and the GNU system. |
| tcflag_t IMAXBEL | Macro |
If this bit is set, then filling up the terminal input buffer sends a
BEL character (code 007) to the terminal to ring the bell.
This is a BSD extension. |
This section describes the terminal flags and fields that control how
output characters are translated and padded for display. All of these
are contained in the c_oflag member of the struct termios
structure.
The c_oflag member itself is an integer, and you change the flags
and fields using the operators &, |, and ^. Don't
try to specify the entire value for c_oflag--instead, change
only specific flags and leave the rest untouched (see Setting Modes).
| tcflag_t OPOST | Macro |
If this bit is set, output data is processed in some unspecified way so
that it is displayed appropriately on the terminal device. This
typically includes mapping newline characters ('\n') onto
carriage return and linefeed pairs.
If this bit isn't set, the characters are transmitted as-is. |
The following three bits are BSD features, and they exist only BSD
systems and the GNU system. They are effective only if OPOST is
set.
| tcflag_t ONLCR | Macro |
| If this bit is set, convert the newline character on output into a pair of characters, carriage return followed by linefeed. |
| tcflag_t OXTABS | Macro |
| If this bit is set, convert tab characters on output into the appropriate number of spaces to emulate a tab stop every eight columns. |
| tcflag_t ONOEOT | Macro |
If this bit is set, discard C-d characters (code 004) on
output. These characters cause many dial-up terminals to disconnect.
|
This section describes the terminal flags and fields that control
parameters usually associated with asynchronous serial data
transmission. These flags may not make sense for other kinds of
terminal ports (such as a network connection pseudo-terminal). All of
these are contained in the c_cflag member of the struct
termios structure.
The c_cflag member itself is an integer, and you change the flags
and fields using the operators &, |, and ^. Don't
try to specify the entire value for c_cflag--instead, change
only specific flags and leave the rest untouched (see Setting Modes).
| tcflag_t CLOCAL | Macro |
|
If this bit is set, it indicates that the terminal is connected
"locally" and that the modem status lines (such as carrier detect)
should be ignored.
On many systems if this bit is not set and you call If this bit is not set and a modem disconnect is detected, a
|
| tcflag_t HUPCL | Macro |
| If this bit is set, a modem disconnect is generated when all processes that have the terminal device open have either closed the file or exited. |
| tcflag_t CREAD | Macro |
| If this bit is set, input can be read from the terminal. Otherwise, input is discarded when it arrives. |
| tcflag_t CSTOPB | Macro |
| If this bit is set, two stop bits are used. Otherwise, only one stop bit is used. |
| tcflag_t PARENB | Macro |
|
If this bit is set, generation and detection of a parity bit are enabled.
See Input Modes, for information on how input parity errors are handled.
If this bit is not set, no parity bit is added to output characters, and input characters are not checked for correct parity. |
| tcflag_t PARODD | Macro |
This bit is only useful if PARENB is set. If PARODD is set,
odd parity is used, otherwise even parity is used.
|
The control mode flags also includes a field for the number of bits per
character. You can use the CSIZE macro as a mask to extract the
value, like this: settings.c_cflag & CSIZE.
| tcflag_t CSIZE | Macro |
| This is a mask for the number of bits per character. |
| tcflag_t CS5 | Macro |
| This specifies five bits per byte. |
| tcflag_t CS6 | Macro |
| This specifies six bits per byte. |
| tcflag_t CS7 | Macro |
| This specifies seven bits per byte. |
| tcflag_t CS8 | Macro |
| This specifies eight bits per byte. |
The following four bits are BSD extensions; this exist only on BSD systems and the GNU system.
| tcflag_t CCTS_OFLOW | Macro |
| If this bit is set, enable flow control of output based on the CTS wire (RS232 protocol). |
| tcflag_t CRTS_IFLOW | Macro |
| If this bit is set, enable flow control of input based on the RTS wire (RS232 protocol). |
| tcflag_t MDMBUF | Macro |
| If this bit is set, enable carrier-based flow control of output. |
| tcflag_t CIGNORE | Macro |
If this bit is set, it says to ignore the control modes and line speed
values entirely. This is only meaningful in a call to tcsetattr.
The This bit is never set in the structure filled in by |
This section describes the flags for the c_lflag member of the
struct termios structure. These flags generally control
higher-level aspects of input processing than the input modes flags
described in Input Modes, such as echoing, signals, and the choice
of canonical or noncanonical input.
The c_lflag member itself is an integer, and you change the flags
and fields using the operators &, |, and ^. Don't
try to specify the entire value for c_lflag--instead, change
only specific flags and leave the rest untouched (see Setting Modes).
| tcflag_t ICANON | Macro |
| This bit, if set, enables canonical input processing mode. Otherwise, input is processed in noncanonical mode. See Canonical or Not. |
| tcflag_t ECHO | Macro |
| If this bit is set, echoing of input characters back to the terminal is enabled. |
| tcflag_t ECHOE | Macro |
|
If this bit is set, echoing indicates erasure of input with the ERASE
character by erasing the last character in the current line from the
screen. Otherwise, the character erased is re-echoed to show what has
happened (suitable for a printing terminal).
This bit only controls the display behavior; the |
| tcflag_t ECHOPRT | Macro |
This bit is like ECHOE, enables display of the ERASE character in
a way that is geared to a hardcopy terminal. When you type the ERASE
character, a \ character is printed followed by the first
character erased. Typing the ERASE character again just prints the next
character erased. Then, the next time you type a normal character, a
/ character is printed before the character echoes.
This is a BSD extension, and exists only in BSD systems and the GNU system. |
| tcflag_t ECHOK | Macro |
This bit enables special display of the KILL character by moving to a
new line after echoing the KILL character normally. The behavior of
ECHOKE (below) is nicer to look at.
If this bit is not set, the KILL character echoes just as it would if it were not the KILL character. Then it is up to the user to remember that the KILL character has erased the preceding input; there is no indication of this on the screen. This bit only controls the display behavior; the |
| tcflag_t ECHOKE | Macro |
This bit is similar to ECHOK. It enables special display of the
KILL character by erasing on the screen the entire line that has been
killed. This is a BSD extension, and exists only in BSD systems and the
GNU system.
|
| tcflag_t ECHONL | Macro |
If this bit is set and the ICANON bit is also set, then the
newline ('\n') character is echoed even if the ECHO bit
is not set.
|
| tcflag_t ECHOCTL | Macro |
If this bit is set and the ECHO bit is also set, echo control
characters with ^ followed by the corresponding text character.
Thus, control-A echoes as ^A. This is usually the preferred mode
for interactive input, because echoing a control character back to the
terminal could have some undesired effect on the terminal.
This is a BSD extension, and exists only in BSD systems and the GNU system. |
| tcflag_t ISIG | Macro |
|
This bit controls whether the INTR, QUIT, and SUSP characters are
recognized. The functions associated with these characters are performed
if and only if this bit is set. Being in canonical or noncanonical
input mode has no affect on the interpretation of these characters.
You should use caution when disabling recognition of these characters. Programs that cannot be interrupted interactively are very user-unfriendly. If you clear this bit, your program should provide some alternate interface that allows the user to interactively send the signals associated with these characters, or to escape from the program. See Signal Characters. |
| tcflag_t IEXTEN | Macro |
POSIX.1 gives IEXTEN implementation-defined meaning,
so you cannot rely on this interpretation on all systems.
On BSD systems and the GNU system, it enables the LNEXT and DISCARD characters. See Other Special. |
| tcflag_t NOFLSH | Macro |
| Normally, the INTR, QUIT, and SUSP characters cause input and output queues for the terminal to be cleared. If this bit is set, the queues are not cleared. |
| tcflag_t TOSTOP | Macro |
If this bit is set and the system supports job control, then
SIGTTOU signals are generated by background processes that
attempt to write to the terminal. See Access to the Terminal.
|
The following bits are BSD extensions; they exist only in BSD systems and the GNU system.
| tcflag_t ALTWERASE | Macro |
|
This bit determines how far the WERASE character should erase. The
WERASE character erases back to the beginning of a word; the question
is, where do words begin?
If this bit is clear, then the beginning of a word is a nonwhitespace character following a whitespace character. If the bit is set, then the beginning of a word is an alphanumeric character or underscore following a character which is none of those. See Editing Characters, for more information about the WERASE character. |
| tcflag_t FLUSHO | Macro |
| This is the bit that toggles when the user types the DISCARD character. While this bit is set, all output is discarded. See Other Special. |
| tcflag_t NOKERNINFO | Macro |
| Setting this bit disables handling of the STATUS character. See Other Special. |
| tcflag_t PENDIN | Macro |
| If this bit is set, it indicates that there is a line of input that needs to be reprinted. Typing the REPRINT character sets this bit; the bit remains set until reprinting is finished. See Editing Characters. |
The terminal line speed tells the computer how fast to read and write data on the terminal.
If the terminal is connected to a real serial line, the terminal speed you specify actually controls the line--if it doesn't match the terminal's own idea of the speed, communication does not work. Real serial ports accept only certain standard speeds. Also, particular hardware may not support even all the standard speeds. Specifying a speed of zero hangs up a dialup connection and turns off modem control signals.
If the terminal is not a real serial line (for example, if it is a network connection), then the line speed won't really affect data transmission speed, but some programs will use it to determine the amount of padding needed. It's best to specify a line speed value that matches the actual speed of the actual terminal, but you can safely experiment with different values to vary the amount of padding.
There are actually two line speeds for each terminal, one for input and one for output. You can set them independently, but most often terminals use the same speed for both directions.
The speed values are stored in the struct termios structure, but
don't try to access them in the struct termios structure
directly. Instead, you should use the following functions to read and
store them:
| speed_t cfgetospeed (const struct termios *termios-p) | Function |
This function returns the output line speed stored in the structure
*termios-p.
|
| speed_t cfgetispeed (const struct termios *termios-p) | Function |
This function returns the input line speed stored in the structure
*termios-p.
|
| int cfsetospeed (struct termios *termios-p, speed_t speed) | Function |
This function stores speed in *termios-p as the output
speed. The normal return value is 0; a value of -1
indicates an error. If speed is not a speed, cfsetospeed
returns -1.
|
| int cfsetispeed (struct termios *termios-p, speed_t speed) | Function |
This function stores speed in *termios-p as the input
speed. The normal return value is 0; a value of -1
indicates an error. If speed is not a speed, cfsetospeed
returns -1.
|
| int cfsetspeed (struct termios *termios-p, speed_t speed) | Function |
This function stores speed in *termios-p as both the
input and output speeds. The normal return value is 0; a value
of -1 indicates an error. If speed is not a speed,
cfsetspeed returns -1. This function is an extension in
4.4 BSD.
|
| speed_t | Data Type |
The speed_t type is an unsigned integer data type used to
represent line speeds.
|
The functions cfsetospeed and cfsetispeed report errors
only for speed values that the system simply cannot handle. If you
specify a speed value that is basically acceptable, then those functions
will succeed. But they do not check that a particular hardware device
can actually support the specified speeds--in fact, they don't know
which device you plan to set the speed for. If you use tcsetattr
to set the speed of a particular device to a value that it cannot
handle, tcsetattr returns -1.
Portability note: In the GNU library, the functions above
accept speeds measured in bits per second as input, and return speed
values measured in bits per second. Other libraries require speeds to
be indicated by special codes. For POSIX.1 portability, you must use
one of the following symbols to represent the speed; their precise
numeric values are system-dependent, but each name has a fixed meaning:
B110 stands for 110 bps, B300 for 300 bps, and so on.
There is no portable way to represent any speed but these, but these are
the only speeds that typical serial lines can support.
B0 B50 B75 B110 B134 B150 B200 B300 B600 B1200 B1800 B2400 B4800 B9600 B19200 B38400 B57600 B115200 B230400 B460800
BSD defines two additional speed symbols as aliases: EXTA is an
alias for B19200 and EXTB is an alias for B38400.
These aliases are obsolete.
In canonical input, the terminal driver recognizes a number of special
characters which perform various control functions. These include the
ERASE character (usually <DEL>) for editing input, and other editing
characters. The INTR character (normally C-c) for sending a
SIGINT signal, and other signal-raising characters, may be
available in either canonical or noncanonical input mode. All these
characters are described in this section.
The particular characters used are specified in the c_cc member
of the struct termios structure. This member is an array; each
element specifies the character for a particular role. Each element has
a symbolic constant that stands for the index of that element--for
example, VINTR is the index of the element that specifies the INTR
character, so storing '=' in termios.c_cc[VINTR]
specifies = as the INTR character.
On some systems, you can disable a particular special character function
by specifying the value _POSIX_VDISABLE for that role. This
value is unequal to any possible character code. See Options for Files, for more information about how to tell whether the operating
system you are using supports _POSIX_VDISABLE.
These special characters are active only in canonical input mode. See Canonical or Not.
| int VEOF | Macro |
This is the subscript for the EOF character in the special control
character array. termios.c_cc[VEOF] holds the character
itself.
The EOF character is recognized only in canonical input mode. It acts
as a line terminator in the same way as a newline character, but if the
EOF character is typed at the beginning of a line it causes Usually, the EOF character is C-d. |
| int VEOL | Macro |
This is the subscript for the EOL character in the special control
character array. termios.c_cc[VEOL] holds the character
itself.
The EOL character is recognized only in canonical input mode. It acts as a line terminator, just like a newline character. The EOL character is not discarded; it is read as the last character in the input line. You don't need to use the EOL character to make <RET> end a line. Just set the ICRNL flag. In fact, this is the default state of affairs. |
| int VEOL2 | Macro |
This is the subscript for the EOL2 character in the special control
character array. termios.c_cc[VEOL2] holds the character
itself.
The EOL2 character works just like the EOL character (see above), but it can be a different character. Thus, you can specify two characters to terminate an input line, by setting EOL to one of them and EOL2 to the other. The EOL2 character is a BSD extension; it exists only on BSD systems and the GNU system. |
| int VERASE | Macro |
This is the subscript for the ERASE character in the special control
character array. termios.c_cc[VERASE] holds the
character itself.
The ERASE character is recognized only in canonical input mode. When the user types the erase character, the previous character typed is discarded. (If the terminal generates multibyte character sequences, this may cause more than one byte of input to be discarded.) This cannot be used to erase past the beginning of the current line of text. The ERASE character itself is discarded. Usually, the ERASE character is <DEL>. |
| int VWERASE | Macro |
This is the subscript for the WERASE character in the special control
character array. termios.c_cc[VWERASE] holds the character
itself.
The WERASE character is recognized only in canonical mode. It erases an entire word of prior input, and any whitespace after it; whitespace characters before the word are not erased. The definition of a "word" depends on the setting of the
If the If the The WERASE character is usually C-w. This is a BSD extension. |
| int VKILL | Macro |
This is the subscript for the KILL character in the special control
character array. termios.c_cc[VKILL] holds the character
itself.
The KILL character is recognized only in canonical input mode. When the user types the kill character, the entire contents of the current line of input are discarded. The kill character itself is discarded too. The KILL character is usually C-u. |
| int VREPRINT | Macro |
This is the subscript for the REPRINT character in the special control
character array. termios.c_cc[VREPRINT] holds the character
itself.
The REPRINT character is recognized only in canonical mode. It reprints the current input line. If some asynchronous output has come while you are typing, this lets you see the line you are typing clearly again. The REPRINT character is usually C-r. This is a BSD extension. |
These special characters may be active in either canonical or noncanonical
input mode, but only when the ISIG flag is set (see Local Modes).
| int VINTR | Macro |
This is the subscript for the INTR character in the special control
character array. termios.c_cc[VINTR] holds the character
itself.
The INTR (interrupt) character raises a Typically, the INTR character is C-c. |
| int VQUIT | Macro |
This is the subscript for the QUIT character in the special control
character array. termios.c_cc[VQUIT] holds the character
itself.
The QUIT character raises a Typically, the QUIT character is C-\. |
| int VSUSP | Macro |
This is the subscript for the SUSP character in the special control
character array. termios.c_cc[VSUSP] holds the character
itself.
The SUSP (suspend) character is recognized only if the implementation
supports job control (see Job Control). It causes a Typically, the SUSP character is C-z. |
Few applications disable the normal interpretation of the SUSP
character. If your program does this, it should provide some other
mechanism for the user to stop the job. When the user invokes this
mechanism, the program should send a SIGTSTP signal to the
process group of the process, not just to the process itself.
See Signaling Another Process.
| int VDSUSP | Macro |
This is the subscript for the DSUSP character in the special control
character array. termios.c_cc[VDSUSP] holds the character
itself.
The DSUSP (suspend) character is recognized only if the implementation
supports job control (see Job Control). It sends a See Signal Handling, for more information about signals. Typically, the DSUSP character is C-y. |
These special characters may be active in either canonical or noncanonical
input mode, but their use is controlled by the flags IXON and
IXOFF (see Input Modes).
| int VSTART | Macro |
This is the subscript for the START character in the special control
character array. termios.c_cc[VSTART] holds the
character itself.
The START character is used to support the The usual value for the START character is C-q. You may not be able to change this value--the hardware may insist on using C-q regardless of what you specify. |
| int VSTOP | Macro |
This is the subscript for the STOP character in the special control
character array. termios.c_cc[VSTOP] holds the character
itself.
The STOP character is used to support the The usual value for the STOP character is C-s. You may not be able to change this value--the hardware may insist on using C-s regardless of what you specify. |
These special characters exist only in BSD systems and the GNU system.
| int VLNEXT | Macro |
This is the subscript for the LNEXT character in the special control
character array. termios.c_cc[VLNEXT] holds the character
itself.
The LNEXT character is recognized only when The LNEXT character is usually C-v. |
| int VDISCARD | Macro |
This is the subscript for the DISCARD character in the special control
character array. termios.c_cc[VDISCARD] holds the character
itself.
The DISCARD character is recognized only when |
| int VSTATUS | Macro |
This is the subscript for the STATUS character in the special control
character array. termios.c_cc[VSTATUS] holds the character
itself.
The STATUS character's effect is to print out a status message about how the current process is running. The STATUS character is recognized only in canonical mode, and only if
|
In noncanonical input mode, the special editing characters such as ERASE and KILL are ignored. The system facilities for the user to edit input are disabled in noncanonical mode, so that all input characters (unless they are special for signal or flow-control purposes) are passed to the application program exactly as typed. It is up to the application program to give the user ways to edit the input, if appropriate.
Noncanonical mode offers special parameters called MIN and TIME for controlling whether and how long to wait for input to be available. You can even use them to avoid ever waiting--to return immediately with whatever input is available, or with no input.
The MIN and TIME are stored in elements of the c_cc array, which
is a member of the struct termios structure. Each element of
this array has a particular role, and each element has a symbolic
constant that stands for the index of that element. VMIN and
VMAX are the names for the indices in the array of the MIN and
TIME slots.
| int VMIN | Macro |
This is the subscript for the MIN slot in the c_cc array. Thus,
termios.c_cc[VMIN] is the value itself.
The MIN slot is only meaningful in noncanonical input mode; it
specifies the minimum number of bytes that must be available in the
input queue in order for |
| int VTIME | Macro |
This is the subscript for the TIME slot in the c_cc array. Thus,
termios.c_cc[VTIME] is the value itself.
The TIME slot is only meaningful in noncanonical input mode; it specifies how long to wait for input before returning, in units of 0.1 seconds. |
The MIN and TIME values interact to determine the criterion for when
read should return; their precise meanings depend on which of
them are nonzero. There are four possible cases:
In this case, TIME specifies how long to wait after each input character
to see if more input arrives. After the first character received,
read keeps waiting until either MIN bytes have arrived in all, or
TIME elapses with no further input.
read always blocks until the first character arrives, even if
TIME elapses first. read can return more than MIN characters if
more than MIN happen to be in the queue.
In this case, read always returns immediately with as many
characters as are available in the queue, up to the number requested.
If no input is immediately available, read returns a value of
zero.
In this case, read waits for time TIME for input to become
available; the availability of a single byte is enough to satisfy the
read request and cause read to return. When it returns, it
returns as many characters as are available, up to the number requested.
If no input is available before the timer expires, read returns a
value of zero.
In this case, read waits until at least MIN bytes are available
in the queue. At that time, read returns as many characters as
are available, up to the number requested. read can return more
than MIN characters if more than MIN happen to be in the queue.
What happens if MIN is 50 and you ask to read just 10 bytes?
Normally, read waits until there are 50 bytes in the buffer (or,
more generally, the wait condition described above is satisfied), and
then reads 10 of them, leaving the other 40 buffered in the operating
system for a subsequent call to read.
Portability note: On some systems, the MIN and TIME slots are actually the same as the EOF and EOL slots. This causes no serious problem because the MIN and TIME slots are used only in noncanonical input and the EOF and EOL slots are used only in canonical input, but it isn't very clean. The GNU library allocates separate slots for these uses.
| int cfmakeraw (struct termios *termios-p) | Function |
This function provides an easy way to set up *termios-p for
what has traditionally been called "raw mode" in BSD. This uses
noncanonical input, and turns off most processing to give an unmodified
channel to the terminal.
It does exactly this: termios-p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
termios-p->c_oflag &= ~OPOST;
termios-p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios-p->c_cflag &= ~(CSIZE|PARENB);
termios-p->c_cflag |= CS8;
|
These functions perform miscellaneous control actions on terminal
devices. As regards terminal access, they are treated like doing
output: if any of these functions is used by a background process on its
controlling terminal, normally all processes in the process group are
sent a SIGTTOU signal. The exception is if the calling process
itself is ignoring or blocking SIGTTOU signals, in which case the
operation is performed and no signal is sent. See Job Control.
| int tcsendbreak (int filedes, int duration) | Function |
|
This function generates a break condition by transmitting a stream of
zero bits on the terminal associated with the file descriptor
filedes. The duration of the break is controlled by the
duration argument. If zero, the duration is between 0.25 and 0.5
seconds. The meaning of a nonzero value depends on the operating system.
This function does nothing if the terminal is not an asynchronous serial data port. The return value is normally zero. In the event of an error, a value
of -1 is returned. The following
|
| int tcdrain (int filedes) | Function |
The tcdrain function waits until all queued
output to the terminal filedes has been transmitted.
This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The return value is normally zero. In the event of an error, a value
of -1 is returned. The following
|
| int tcflush (int filedes, int queue) | Function |
The tcflush function is used to clear the input and/or output
queues associated with the terminal file filedes. The queue
argument specifies which queue(s) to clear, and can be one of the
following values:
The return value is normally zero. In the event of an error, a value
of -1 is returned. The following
It is unfortunate that this function is named |
| int tcflow (int filedes, int action) | Function |
The tcflow function is used to perform operations relating to
XON/XOFF flow control on the terminal file specified by filedes.
The action argument specifies what operation to perform, and can be one of the following values:
For more information about the STOP and START characters, see Special Characters. The return value is normally zero. In the event of an error, a value
of -1 is returned. The following
|
Here is an example program that shows how you can set up a terminal device to read single characters in noncanonical input mode, without echo.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
/* Use this variable to remember original terminal attributes. */
struct termios saved_attributes;
void
reset_input_mode (void)
{
tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
}
void
set_input_mode (void)
{
struct termios tattr;
char *name;
/* Make sure stdin is a terminal. */
if (!isatty (STDIN_FILENO))
{
fprintf (stderr, "Not a terminal.\n");
exit (EXIT_FAILURE);
}
/* Save the terminal attributes so we can restore them later. */
tcgetattr (STDIN_FILENO, &saved_attributes);
atexit (reset_input_mode);
/* Set the funny terminal modes. */
tcgetattr (STDIN_FILENO, &tattr);
tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
tattr.c_cc[VMIN] = 1;
tattr.c_cc[VTIME] = 0;
tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
}
int
main (void)
{
char c;
set_input_mode ();
while (1)
{
read (STDIN_FILENO, &c, 1);
if (c == '\004') /* C-d */
break;
else
putchar (c);
}
return EXIT_SUCCESS;
}
This program is careful to restore the original terminal modes before
exiting or terminating with a signal. It uses the atexit
function (see Cleanups on Exit) to make sure this is done
by exit.
The shell is supposed to take care of resetting the terminal modes when a process is stopped or continued; see Job Control. But some existing shells do not actually do this, so you may wish to establish handlers for job control signals that reset terminal modes. The above example does so.
A pseudo-terminal is a special interprocess communication channel that acts like a terminal. One end of the channel is called the master side or master pseudo-terminal device, the other side is called the slave side. Data written to the master side is received by the slave side as if it was the result of a user typing at an ordinary terminal, and data written to the slave side is sent to the master side as if it was written on an ordinary terminal.
Pseudo terminals are the way programs like xterm and emacs
implement their terminal emulation functionality.
This subsection describes functions for allocating a pseudo-terminal,
and for making this pseudo-terminal available for actual use. These
functions are declared in the header file stdlib.h.
| int getpt (void) | Function |
The getpt function returns a new file descriptor for the next
available master pseudo-terminal. The normal return value from
getpt is a non-negative integer file descriptor. In the case of
an error, a value of -1 is returned instead. The following
errno conditions are defined for this function:
This function is a GNU extension. |
| int grantpt (int filedes) | Function |
The grantpt function changes the ownership and access permission
of the slave pseudo-terminal device corresponding to the master
pseudo-terminal device associated with the file descriptor
filedes. The owner is set from the real user ID of the calling
process (see Process Persona), and the group is set to a special
group (typically tty) or from the real group ID of the calling
process. The access permission is set such that the file is both
readable and writable by the owner and only writable by the group.
On some systems this function is implemented by invoking a special
The normal return value from
|
| int unlockpt (int filedes) | Function |
The unlockpt function unlocks the slave pseudo-terminal device
corresponding to the master pseudo-terminal device associated with the
file descriptor filedes. On many systems, the slave can only be
opened after unlocking, so portable applications should always call
unlockpt before trying to open the slave.
The normal return value from
|
| char * ptsname (int filedes) | Function |
If the file descriptor filedes is associated with a
master pseudo-terminal device, the ptsname function returns a
pointer to a statically-allocated, null-terminated string containing the
file name of the associated slave pseudo-terminal file. This string
might be overwritten by subsequent calls to ptsname.
|
| int ptsname_r (int filedes, char *buf, size_t len) | Function |
The ptsname_r function is similar to the ptsname function
except that it places its result into the user-specified buffer starting
at buf with length len.
This function is a GNU extension. |
Portability Note: On System V derived systems, the file
returned by the ptsname and ptsname_r functions may be
STREAMS-based, and therefore require additional processing after opening
before it actually behaves as a pseudo terminal.
Typical usage of these functions is illustrated by the following example:
int
open_pty_pair (int *amaster, int *aslave)
{
int master, slave;
char *name
master = getpt ();
if (master < 0)
return 0;
if (grantpt (master) < 0 || unlockpt (master) < 0)
goto close_master;
name = ptsname (master);
if (name == NULL)
goto close_master;
slave = open (name, O_RDWR);
if (slave == -1)
goto close_master;
if (isastream (slave))
{
if (ioctl (slave, I_PUSH, "ptem") < 0
|| ioctl (slave, I_PUSH, "ldterm") < 0)
goto close_slave;
}
*amaster = master;
*aslave = slave;
return 1;
close_slave:
close (slave);
close_master:
close (master);
return 0;
}
These functions, derived from BSD, are available in the separate
libutil library, and declared in pty.h.
| int openpty (int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) | Function |
This function allocates and opens a pseudo-terminal pair, returning the
file descriptor for the master in *amaster, and the file
descriptor for the slave in *aslave. If the argument name
is not a null pointer, the file name of the slave pseudo-terminal
device is stored in *name. If termp is not a null pointer,
the terminal attributes of the slave are set to the ones specified in
the structure that termp points to (see Terminal Modes).
Likewise, if the winp is not a null pointer, the screen size of
the slave is set to the values specified in the structure that
winp points to.
The normal return value from
Warning: Using the |
| int forkpty (int *amaster, char *name, struct termios *termp, struct winsize *winp) | Function |
This function is similar to the openpty function, but in
addition, forks a new process (see Creating a Process) and makes the
newly opened slave pseudo-terminal device the controlling terminal
(see Controlling Terminal) for the child process.
If the operation is successful, there are then both parent and child
processes and both see If the allocation of a pseudo-terminal pair or the process creation
failed, Warning: The |
This chapter contains information about functions for performing
mathematical computations, such as trigonometric functions. Most of
these functions have prototypes declared in the header file
math.h. The complex-valued functions are defined in
complex.h.
All mathematical functions which take a floating-point argument
have three variants, one each for double, float, and
long double arguments. The double versions are mostly
defined in ISO C 89. The float and long double
versions are from the numeric extensions to C included in ISO C 9X.
Which of the three versions of a function should be used depends on the
situation. For most calculations, the float functions are the
fastest. On the other hand, the long double functions have the
highest precision. double is somewhere in between. It is
usually wise to pick the narrowest type that can accommodate your data.
Not all machines have a distinct long double type; it may be the
same as double.
The header math.h defines several useful mathematical constants.
All values are defined as preprocessor macros starting with M_.
The values provided are:
M_E
M_LOG2E
2 of M_E.
M_LOG10E
10 of M_E.
M_LN2
2.
M_LN10
10.
M_PI
M_PI_2
M_PI_4
M_1_PI
M_2_PI
M_2_SQRTPI
M_SQRT2
M_SQRT1_2
These constants come from the Unix98 standard and were also available in
4.4BSD; therefore, they are only defined if _BSD_SOURCE or
_XOPEN_SOURCE=500, or a more general feature select macro, is
defined. The default set of features includes these constants.
See Feature Test Macros.
All values are of type double. As an extension, the GNU C
library also defines these constants with type long double. The
long double macros have a lowercase l appended to their
names: M_El, M_PIl, and so forth. These are only
available if _GNU_SOURCE is defined.
Note: Some programs use a constant named PI which has the
same value as M_PI. This constant is not standard; it may have
appeared in some old AT&T headers, and is mentioned in Stroustrup's book
on C++. It infringes on the user's name space, so the GNU C library
does not define it. Fixing programs written to expect it is simple:
replace PI with M_PI throughout, or put -DPI=M_PI
on the compiler command line.
These are the familiar sin, cos, and tan functions.
The arguments to all of these functions are in units of radians; recall
that pi radians equals 180 degrees.
The math library normally defines M_PI to a double
approximation of pi. If strict ISO and/or POSIX compliance
are requested this constant is not defined, but you can easily define it
yourself:
#define M_PI 3.14159265358979323846264338327
You can also compute the value of pi with the expression acos
(-1.0).
| double sin (double x) | Function |
| float sinf (float x) | Function |
| long double sinl (long double x) | Function |
These functions return the sine of x, where x is given in
radians. The return value is in the range -1 to 1.
|
| double cos (double x) | Function |
| float cosf (float x) | Function |
| long double cosl (long double x) | Function |
These functions return the cosine of x, where x is given in
radians. The return value is in the range -1 to 1.
|
| double tan (double x) | Function |
| float tanf (float x) | Function |
| long double tanl (long double x) | Function |
|
These functions return the tangent of x, where x is given in
radians.
Mathematically, the tangent function has singularities at odd multiples
of pi/2. If the argument x is too close to one of these
singularities, |
In many applications where sin and cos are used, the sine
and cosine of the same angle are needed at the same time. It is more
efficient to compute them simultaneously, so the library provides a
function to do that.
| void sincos (double x, double *sinx, double *cosx) | Function |
| void sincosf (float x, float *sinx, float *cosx) | Function |
| void sincosl (long double x, long double *sinx, long double *cosx) | Function |
These functions return the sine of x in *sinx and the
cosine of x in *cos, where x is given in
radians. Both values, *sinx and *cosx, are in
the range of -1 to 1.
This function is a GNU extension. Portable programs should be prepared to cope with its absence. |
ISO C 9x defines variants of the trig functions which work on complex numbers. The GNU C library provides these functions, but they are only useful if your compiler supports the new complex types defined by the standard. (As of this writing GCC supports complex numbers, but there are bugs in the implementation.)
| complex double csin (complex double z) | Function |
| complex float csinf (complex float z) | Function |
| complex long double csinl (complex long double z) | Function |
| These functions return the complex sine of z. The mathematical definition of the complex sine is |
| complex double ccos (complex double z) | Function |
| complex float ccosf (complex float z) | Function |
| complex long double ccosl (complex long double z) | Function |
| These functions return the complex cosine of z. The mathematical definition of the complex cosine is |
| complex double ctan (complex double z) | Function |
| complex float ctanf (complex float z) | Function |
| complex long double ctanl (complex long double z) | Function |
|
These functions return the complex tangent of z.
The mathematical definition of the complex tangent is
The complex tangent has poles at pi/2 + 2n, where n is an
integer. |
These are the usual arc sine, arc cosine and arc tangent functions, which are the inverses of the sine, cosine and tangent functions, respectively.
| double asin (double x) | Function |
| float asinf (float x) | Function |
| long double asinl (long double x) | Function |
These functions compute the arc sine of x--that is, the value whose
sine is x. The value is in units of radians. Mathematically,
there are infinitely many such values; the one actually returned is the
one between -pi/2 and pi/2 (inclusive).
The arc sine function is defined mathematically only
over the domain |
| double acos (double x) | Function |
| float acosf (float x) | Function |
| long double acosl (long double x) | Function |
These functions compute the arc cosine of x--that is, the value
whose cosine is x. The value is in units of radians.
Mathematically, there are infinitely many such values; the one actually
returned is the one between 0 and pi (inclusive).
The arc cosine function is defined mathematically only
over the domain |
| double atan (double x) | Function |
| float atanf (float x) | Function |
| long double atanl (long double x) | Function |
These functions compute the arc tangent of x--that is, the value
whose tangent is x. The value is in units of radians.
Mathematically, there are infinitely many such values; the one actually
returned is the one between -pi/2 and pi/2 (inclusive).
|
| double atan2 (double y, double x) | Function |
| float atan2f (float y, float x) | Function |
| long double atan2l (long double y, long double x) | Function |
This function computes the arc tangent of y/x, but the signs
of both arguments are used to determine the quadrant of the result, and
x is permitted to be zero. The return value is given in radians
and is in the range -pi to pi, inclusive.
If x and y are coordinates of a point in the plane,
If both x and y are zero, |
ISO C 9x defines complex versions of the inverse trig functions.
| complex double casin (complex double z) | Function |
| complex float casinf (complex float z) | Function |
| complex long double casinl (complex long double z) | Function |
|
These functions compute the complex arc sine of z--that is, the
value whose sine is z. The value returned is in radians.
Unlike the real-valued functions, |
| complex double cacos (complex double z) | Function |
| complex float cacosf (complex float z) | Function |
| complex long double cacosl (complex long double z) | Function |
|
These functions compute the complex arc cosine of z--that is, the
value whose cosine is z. The value returned is in radians.
Unlike the real-valued functions, |
| complex double catan (complex double z) | Function |
| complex float catanf (complex float z) | Function |
| complex long double catanl (complex long double z) | Function |
| These functions compute the complex arc tangent of z--that is, the value whose tangent is z. The value is in units of radians. |
| double exp (double x) | Function |
| float expf (float x) | Function |
| long double expl (long double x) | Function |
These functions compute e (the base of natural logarithms) raised
to the power x.
If the magnitude of the result is too large to be representable,
|
| double exp2 (double x) | Function |
| float exp2f (float x) | Function |
| long double exp2l (long double x) | Function |
These functions compute 2 raised to the power x.
Mathematically, exp2 (x) is the same as exp (x * log (2)).
|
| double exp10 (double x) | Function |
| float exp10f (float x) | Function |
| long double exp10l (long double x) | Function |
| double pow10 (double x) | Function |
| float pow10f (float x) | Function |
| long double pow10l (long double x) | Function |
These functions compute 10 raised to the power x.
Mathematically, exp10 (x) is the same as exp (x * log (10)).
These functions are GNU extensions. The name |
| double log (double x) | Function |
| float logf (float x) | Function |
| long double logl (long double x) | Function |
These functions compute the natural logarithm of x. exp (log
(x)) equals x, exactly in mathematics and approximately in
C.
If x is negative, |
| double log10 (double x) | Function |
| float log10f (float x) | Function |
| long double log10l (long double x) | Function |
These functions return the base-10 logarithm of x.
log10 (x) equals log (x) / log (10).
|
| double log2 (double x) | Function |
| float log2f (float x) | Function |
| long double log2l (long double x) | Function |
These functions return the base-2 logarithm of x.
log2 (x) equals log (x) / log (2).
|
| double logb (double x) | Function |
| float logbf (float x) | Function |
| long double logbl (long double x) | Function |
These functions extract the exponent of x and return it as a
floating-point value. If FLT_RADIX is two, logb is equal
to floor (log2 (x)), except it's probably faster.
If x is denormalized, |
| int ilogb (double x) | Function |
| int ilogbf (float x) | Function |
| int ilogbl (long double x) | Function |
These functions are equivalent to the corresponding logb
functions except that they return signed integer values.
|
Since integers cannot represent infinity and NaN, ilogb instead
returns an integer that can't be the exponent of a normal floating-point
number. math.h defines constants so you can check for this.
| int FP_ILOGB0 | Macro |
ilogb returns this value if its argument is 0. The
numeric value is either INT_MIN or -INT_MAX.
This macro is defined in ISO C 9X. |
| int FP_ILOGBNAN | Macro |
ilogb returns this value if its argument is NaN. The
numeric value is either INT_MIN or INT_MAX.
This macro is defined in ISO C 9X. |
These values are system specific. They might even be the same. The
proper way to test the result of ilogb is as follows:
i = ilogb (f);
if (i == FP_ILOGB0 || i == FP_ILOGBNAN)
{
if (isnan (f))
{
/* Handle NaN. */
}
else if (f == 0.0)
{
/* Handle 0.0. */
}
else
{
/* Some other value with large exponent,
perhaps +Inf. */
}
}
| double pow (double base, double power) | Function |
| float powf (float base, float power) | Function |
| long double powl (long double base, long double power) | Function |
|
These are general exponentiation functions, returning base raised
to power.
Mathematically, |
| double sqrt (double x) | Function |
| float sqrtf (float x) | Function |
| long double sqrtl (long double x) | Function |
|
These functions return the nonnegative square root of x.
If x is negative, |
| double cbrt (double x) | Function |
| float cbrtf (float x) | Function |
| long double cbrtl (long double x) | Function |
| These functions return the cube root of x. They cannot fail; every representable real value has a representable real cube root. |
| double hypot (double x, double y) | Function |
| float hypotf (float x, float y) | Function |
| long double hypotl (long double x, long double y) | Function |
These functions return sqrt (x*x +
y*y). This is the length of the hypotenuse of a right
triangle with sides of length x and y, or the distance
of the point (x, y) from the origin. Using this function
instead of the direct formula is wise, since the error is
much smaller. See also the function cabs in Absolute Value.
|
| double expm1 (double x) | Function |
| float expm1f (float x) | Function |
| long double expm1l (long double x) | Function |
These functions return a value equivalent to exp (x) - 1.
They are computed in a way that is accurate even if x is
near zero--a case where exp (x) - 1 would be inaccurate due
to subtraction of two numbers that are nearly equal.
|
| double log1p (double x) | Function |
| float log1pf (float x) | Function |
| long double log1pl (long double x) | Function |
These functions returns a value equivalent to log (1 + x).
They are computed in a way that is accurate even if x is
near zero.
|
ISO C 9X defines complex variants of some of the exponentiation and logarithm functions.
| complex double cexp (complex double z) | Function |
| complex float cexpf (complex float z) | Function |
| complex long double cexpl (complex long double z) | Function |
These functions return e (the base of natural
logarithms) raised to the power of z.
Mathematically this corresponds to the value
|
| complex double clog (complex double z) | Function |
| complex float clogf (complex float z) | Function |
| complex long double clogl (complex long double z) | Function |
|
These functions return the natural logarithm of z.
Mathematically this corresponds to the value
|
| complex double clog10 (complex double z) | Function |
| complex float clog10f (complex float z) | Function |
| complex long double clog10l (complex long double z) | Function |
|
These functions return the base 10 logarithm of the complex value
z. Mathematically this corresponds to the value
These functions are GNU extensions. |
| complex double csqrt (complex double z) | Function |
| complex float csqrtf (complex float z) | Function |
| complex long double csqrtl (complex long double z) | Function |
| These functions return the complex square root of the argument z. Unlike the real-valued functions, they are defined for all values of z. |
| complex double cpow (complex double base, complex double power) | Function |
| complex float cpowf (complex float base, complex float power) | Function |
| complex long double cpowl (complex long double base, complex long double power) | Function |
These functions return base raised to the power of
power. This is equivalent to cexp (y * clog (x))
|
The functions in this section are related to the exponential functions; see Exponents and Logarithms.
| double sinh (double x) | Function |
| float sinhf (float x) | Function |
| long double sinhl (long double x) | Function |
These functions return the hyperbolic sine of x, defined
mathematically as (exp (x) - exp (-x)) / 2. They
may signal overflow if x is too large.
|
| double cosh (double x) | Function |
| float coshf (float x) | Function |
| long double coshl (long double x) | Function |
These function return the hyperbolic cosine of x,
defined mathematically as (exp (x) + exp (-x)) / 2.
They may signal overflow if x is too large.
|
| double tanh (double x) | Function |
| float tanhf (float x) | Function |
| long double tanhl (long double x) | Function |
These functions return the hyperbolic tangent of x,
defined mathematically as sinh (x) / cosh (x).
They may signal overflow if x is too large.
|
There are counterparts for the hyperbolic functions which take complex arguments.
| complex double csinh (complex double z) | Function |
| complex float csinhf (complex float z) | Function |
| complex long double csinhl (complex long double z) | Function |
These functions return the complex hyperbolic sine of z, defined
mathematically as (exp (z) - exp (-z)) / 2.
|
| complex double ccosh (complex double z) | Function |
| complex float ccoshf (complex float z) | Function |
| complex long double ccoshl (complex long double z) | Function |
These functions return the complex hyperbolic cosine of z, defined
mathematically as (exp (z) + exp (-z)) / 2.
|
| complex double ctanh (complex double z) | Function |
| complex float ctanhf (complex float z) | Function |
| complex long double ctanhl (complex long double z) | Function |
These functions return the complex hyperbolic tangent of z,
defined mathematically as csinh (z) / ccosh (z).
|
| double asinh (double x) | Function |
| float asinhf (float x) | Function |
| long double asinhl (long double x) | Function |
| These functions return the inverse hyperbolic sine of x--the value whose hyperbolic sine is x. |
| double acosh (double x) | Function |
| float acoshf (float x) | Function |
| long double acoshl (long double x) | Function |
These functions return the inverse hyperbolic cosine of x--the
value whose hyperbolic cosine is x. If x is less than
1, acosh signals a domain error.
|
| double atanh (double x) | Function |
| float atanhf (float x) | Function |
| long double atanhl (long double x) | Function |
These functions return the inverse hyperbolic tangent of x--the
value whose hyperbolic tangent is x. If the absolute value of
x is greater than 1, atanh signals a domain error;
if it is equal to 1, atanh returns infinity.
|
| complex double casinh (complex double z) | Function |
| complex float casinhf (complex float z) | Function |
| complex long double casinhl (complex long double z) | Function |
| These functions return the inverse complex hyperbolic sine of z--the value whose complex hyperbolic sine is z. |
| complex double cacosh (complex double z) | Function |
| complex float cacoshf (complex float z) | Function |
| complex long double cacoshl (complex long double z) | Function |
| These functions return the inverse complex hyperbolic cosine of z--the value whose complex hyperbolic cosine is z. Unlike the real-valued functions, there are no restrictions on the value of z. |
| complex double catanh (complex double z) | Function |
| complex float catanhf (complex float z) | Function |
| complex long double catanhl (complex long double z) | Function |
| These functions return the inverse complex hyperbolic tangent of z--the value whose complex hyperbolic tangent is z. Unlike the real-valued functions, there are no restrictions on the value of z. |
These are some more exotic mathematical functions, which are sometimes useful. Currently they only have real-valued versions.
| double erf (double x) | Function |
| float erff (float x) | Function |
| long double erfl (long double x) | Function |
erf returns the error function of x. The error
function is defined as
erf (x) = 2/sqrt(pi) * integral from 0 to x of exp(-t^2) dt |
| double erfc (double x) | Function |
| float erfcf (float x) | Function |
| long double erfcl (long double x) | Function |
erfc returns 1.0 - erf(x), but computed in a
fashion that avoids round-off error when x is large.
|
| double lgamma (double x) | Function |
| float lgammaf (float x) | Function |
| long double lgammal (long double x) | Function |
lgamma returns the natural logarithm of the absolute value of
the gamma function of x. The gamma function is defined as
gamma (x) = integral from 0 to ∞ of t^(x-1) e^-t dt The sign of the gamma function is stored in the global variable
signgam, which is declared in To compute the real gamma function you can use the lgam = lgamma(x); gam = signgam*exp(lgam); The gamma function has singularities at the nonpositive integers.
|
| double lgamma_r (double x, int *signp) | Function |
| float lgammaf_r (float x, int *signp) | Function |
| long double lgammal_r (long double x, int *signp) | Function |
lgamma_r is just like lgamma, but it stores the sign of
the intermediate result in the variable pointed to by signp
instead of in the signgam global.
|
| double gamma (double x) | Function |
| float gammaf (float x) | Function |
| long double gammal (long double x) | Function |
These functions exist for compatibility reasons. They are equivalent to
lgamma etc. It is better to use lgamma since for one the
name reflects better the actual computation and lgamma is also
standardized in ISO C 9x while gamma is not.
|
| double tgamma (double x) | Function |
| float tgammaf (float x) | Function |
| long double tgammal (long double x) | Function |
tgamma applies the gamma function to x. The gamma
function is defined as
gamma (x) = integral from 0 to ∞ of t^(x-1) e^-t dt This function was introduced in ISO C 9x. |
| double j0 (double x) | Function |
| float j0f (float x) | Function |
| long double j0l (long double x) | Function |
j0 returns the Bessel function of the first kind of order 0 of
x. It may signal underflow if x is too large.
|
| double j1 (double x) | Function |
| float j1f (float x) | Function |
| long double j1l (long double x) | Function |
j1 returns the Bessel function of the first kind of order 1 of
x. It may signal underflow if x is too large.
|
| double jn (int n, double x) | Function |
| float jnf (int n, float x) | Function |
| long double jnl (int n, long double x) | Function |
jn returns the Bessel function of the first kind of order
n of x. It may signal underflow if x is too large.
|
| double y0 (double x) | Function |
| float y0f (float x) | Function |
| long double y0l (long double x) | Function |
y0 returns the Bessel function of the second kind of order 0 of
x. It may signal underflow if x is too large. If x
is negative, y0 signals a domain error; if it is zero,
y0 signals overflow and returns -∞.
|
| double y1 (double x) | Function |
| float y1f (float x) | Function |
| long double y1l (long double x) | Function |
y1 returns the Bessel function of the second kind of order 1 of
x. It may signal underflow if x is too large. If x
is negative, y1 signals a domain error; if it is zero,
y1 signals overflow and returns -∞.
|
| double yn (int n, double x) | Function |
| float ynf (int n, float x) | Function |
| long double ynl (int n, long double x) | Function |
yn returns the Bessel function of the second kind of order n of
x. It may signal underflow if x is too large. If x
is negative, yn signals a domain error; if it is zero,
yn signals overflow and returns -∞.
|
This section describes the GNU facilities for generating a series of pseudo-random numbers. The numbers generated are not truly random; typically, they form a sequence that repeats periodically, with a period so large that you can ignore it for ordinary purposes. The random number generator works by remembering a seed value which it uses to compute the next random number and also to compute a new seed.
Although the generated numbers look unpredictable within one run of a program, the sequence of numbers is exactly the same from one run to the next. This is because the initial seed is always the same. This is convenient when you are debugging a program, but it is unhelpful if you want the program to behave unpredictably. If you want a different pseudo-random series each time your program runs, you must specify a different seed each time. For ordinary purposes, basing the seed on the current time works well.
You can get repeatable sequences of numbers on a particular machine type by specifying the same initial seed value for the random number generator. There is no standard meaning for a particular seed value; the same seed, used in different C libraries or on different CPU types, will give you different random numbers.
The GNU library supports the standard ISO C random number functions
plus two other sets derived from BSD and SVID. The BSD and ISO C
functions provide identical, somewhat limited functionality. If only a
small number of random bits are required, we recommend you use the
ISO C interface, rand and srand. The SVID functions
provide a more flexible interface, which allows better random number
generator algorithms, provides more random bits (up to 48) per call, and
can provide random floating-point numbers. These functions are required
by the XPG standard and therefore will be present in all modern Unix
systems.
rand and friends.
random and friends.
drand48 and friends.
This section describes the random number functions that are part of the ISO C standard.
To use these facilities, you should include the header file
stdlib.h in your program.
| int RAND_MAX | Macro |
The value of this macro is an integer constant representing the largest
value the rand function can return. In the GNU library, it is
2147483647, which is the largest signed integer representable in
32 bits. In other libraries, it may be as low as 32767.
|
| int rand (void) | Function |
The rand function returns the next pseudo-random number in the
series. The value ranges from 0 to RAND_MAX.
|
| void srand (unsigned int seed) | Function |
This function establishes seed as the seed for a new series of
pseudo-random numbers. If you call rand before a seed has been
established with srand, it uses the value 1 as a default
seed.
To produce a different pseudo-random series each time your program is
run, do |
POSIX.1 extended the C standard functions to support reproducible random numbers in multi-threaded programs. However, the extension is badly designed and unsuitable for serious work.
| int rand_r (unsigned int *seed) | Function |
This function returns a random number in the range 0 to RAND_MAX
just as rand does. However, all its state is stored in the
seed argument. This means the RNG's state can only have as many
bits as the type unsigned int has. This is far too few to
provide a good RNG.
If your program requires a reentrant RNG, we recommend you use the reentrant GNU extensions to the SVID random number generator. The POSIX.1 interface should only be used when the GNU extensions are not available. |
This section describes a set of random number generation functions that are derived from BSD. There is no advantage to using these functions with the GNU C library; we support them for BSD compatibility only.
The prototypes for these functions are in stdlib.h.
| int32_t random (void) | Function |
This function returns the next pseudo-random number in the sequence.
The value returned ranges from 0 to RAND_MAX.
Note: Historically this function returned a |
| void srandom (unsigned int seed) | Function |
The srandom function sets the state of the random number
generator based on the integer seed. If you supply a seed value
of 1, this will cause random to reproduce the default set
of random numbers.
To produce a different set of pseudo-random numbers each time your
program runs, do |
| void * initstate (unsigned int seed, void *state, size_t size) | Function |
The initstate function is used to initialize the random number
generator state. The argument state is an array of size
bytes, used to hold the state information. It is initialized based on
seed. The size must be between 8 and 256 bytes, and should be a
power of two. The bigger the state array, the better.
The return value is the previous value of the state information array.
You can use this value later as an argument to |
| void * setstate (void *state) | Function |
The setstate function restores the random number state
information state. The argument must have been the result of
a previous call to initstate or setstate.
The return value is the previous value of the state information array.
You can use this value later as an argument to |
The C library on SVID systems contains yet another kind of random number generator functions. They use a state of 48 bits of data. The user can choose among a collection of functions which return the random bits in different forms.
Generally there are two kinds of functions: those which use a state of the random number generator which is shared among several functions and by all threads of the process. The second group of functions require the user to handle the state.
All functions have in common that they use the same congruential formula with the same constants. The formula is
Y = (a * X + c) mod m
where X is the state of the generator at the beginning and
Y the state at the end. a and c are constants
determining the way the generator work. By default they are
a = 0x5DEECE66D = 25214903917 c = 0xb = 11
but they can also be changed by the user. m is of course 2^48
since the state consists of a 48 bit array.
| double drand48 (void) | Function |
This function returns a double value in the range of 0.0
to 1.0 (exclusive). The random bits are determined by the global
state of the random number generator in the C library.
Since the |
| double erand48 (unsigned short int xsubi[3]) | Function |
This function returns a double value in the range of 0.0
to 1.0 (exclusive), similar to drand48. The argument is
an array describing the state of the random number generator.
This function can be called subsequently since it updates the array to guarantee random numbers. The array should have been initialized before using to get reproducible results. |
| long int lrand48 (void) | Function |
The lrand48 functions return an integer value in the range of
0 to 2^31 (exclusive). Even if the size of the long
int type can take more than 32 bits no higher numbers are returned.
The random bits are determined by the global state of the random number
generator in the C library.
|
| long int nrand48 (unsigned short int xsubi[3]) | Function |
This function is similar to the lrand48 function in that it
returns a number in the range of 0 to 2^31 (exclusive) but
the state of the random number generator used to produce the random bits
is determined by the array provided as the parameter to the function.
The numbers in the array are afterwards updated so that subsequent calls to this function yield to different results (as it is expected by a random number generator). The array should have been initialized before the first call to get reproducible results. |
| long int mrand48 (void) | Function |
The mrand48 function is similar to lrand48. The only
difference is that the numbers returned are in the range -2^31 to
2^31 (exclusive).
|
| long int jrand48 (unsigned short int xsubi[3]) | Function |
The jrand48 function is similar to nrand48. The only
difference is that the numbers returned are in the range -2^31 to
2^31 (exclusive). For the xsubi parameter the same
requirements are necessary.
|
The internal state of the random number generator can be initialized in several ways. The functions differ in the completeness of the information provided.
| void srand48 (long int seedval)) | Function |
The srand48 function sets the most significant 32 bits of the
state internal state of the random number generator to the least
significant 32 bits of the seedval parameter. The lower 16 bits
are initialized to the value 0x330E. Even if the long
int type contains more the 32 bits only the lower 32 bits are used.
Due to this limitation the initialization of the state using this
function of not very useful. But it makes it easy to use a construct
like A side-effect of this function is that the values |
| unsigned short int * seed48 (unsigned short int seed16v[3]) | Function |
The seed48 function initializes all 48 bits of the state of the
internal random number generator from the content of the parameter
seed16v. Here the lower 16 bits of the first element of
see16v initialize the least significant 16 bits of the internal
state, the lower 16 bits of seed16v[1] initialize the mid-order
16 bits of the state and the 16 lower bits of seed16v[2]
initialize the most significant 16 bits of the state.
Unlike The value returned by As for |
There is one more function to initialize the random number generator which allows to specify even more information by allowing to change the parameters in the congruential formula.
| void lcong48 (unsigned short int param[7]) | Function |
The lcong48 function allows the user to change the complete state
of the random number generator. Unlike srand48 and
seed48, this function also changes the constants in the
congruential formula.
From the seven elements in the array param the least significant
16 bits of the entries |
All the above functions have in common that they use the global parameters for the congruential formula. In multi-threaded programs it might sometimes be useful to have different parameters in different threads. For this reason all the above functions have a counterpart which works on a description of the random number generator in the user-supplied buffer instead of the global state.
Please note that it is no problem if several threads use the global state if all threads use the functions which take a pointer to an array containing the state. The random numbers are computed following the same loop but if the state in the array is different all threads will get an individual random number generator.
The user supplied buffer must be of type struct drand48_data.
This type should be regarded as opaque and no member should be used
directly.
| int drand48_r (struct drand48_data *buffer, double *result) | Function |
This function is equivalent to the drand48 function with the
difference it does not modify the global random number generator
parameters but instead the parameters is the buffer supplied by the
buffer through the pointer buffer. The random number is return in
the variable pointed to by result.
The return value of the function indicate whether the call succeeded.
If the value is less than This function is a GNU extension and should not be used in portable programs. |
| int erand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, double *result) | Function |
The erand48_r function works like the erand48 and it takes
an argument buffer which describes the random number generator.
The state of the random number generator is taken from the xsubi
array, the parameters for the congruential formula from the global
random number generator data. The random number is return in the
variable pointed to by result.
The return value is non-negative is the call succeeded. This function is a GNU extension and should not be used in portable programs. |
| int lrand48_r (struct drand48_data *buffer, double *result) | Function |
This function is similar to lrand48 and it takes a pointer to a
buffer describing the state of the random number generator as a
parameter just like drand48.
If the return value of the function is non-negative the variable pointed to by result contains the result. Otherwise an error occurred. This function is a GNU extension and should not be used in portable programs. |
| int nrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result) | Function |
The nrand48_r function works like nrand48 in that it
produces a random number in range 0 to 2^31. But instead
of using the global parameters for the congruential formula it uses the
information from the buffer pointed to by buffer. The state is
described by the values in xsubi.
If the return value is non-negative the variable pointed to by result contains the result. This function is a GNU extension and should not be used in portable programs. |
| int mrand48_r (struct drand48_data *buffer, double *result) | Function |
This function is similar to mrand48 but as the other reentrant
function it uses the random number generator described by the value in
the buffer pointed to by buffer.
If the return value is non-negative the variable pointed to by result contains the result. This function is a GNU extension and should not be used in portable programs. |
| int jrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer, long int *result) | Function |
The jrand48_r function is similar to jrand48. But as the
other reentrant functions of this function family it uses the
congruential formula parameters from the buffer pointed to by
buffer.
If the return value is non-negative the variable pointed to by result contains the result. This function is a GNU extension and should not be used in portable programs. |
Before any of the above functions should be used the buffer of type
struct drand48_data should initialized. The easiest way is to
fill the whole buffer with null bytes, e.g., using
memset (buffer, '\0', sizeof (struct drand48_data));
Using any of the reentrant functions of this family now will automatically initialize the random number generator to the default values for the state and the parameters of the congruential formula.
The other possibility is too use any of the functions which explicitly initialize the buffer. Though it might be obvious how to initialize the buffer from the data given as parameter from the function it is highly recommended to use these functions since the result might not always be what you expect.
| int srand48_r (long int seedval, struct drand48_data *buffer) | Function |
The description of the random number generator represented by the
information in buffer is initialized similar to what the function
srand48 does. The state is initialized from the parameter
seedval and the parameters for the congruential formula are
initialized to the default values.
If the return value is non-negative the function call succeeded. This function is a GNU extension and should not be used in portable programs. |
| int seed48_r (unsigned short int seed16v[3], struct drand48_data *buffer) | Function |
This function is similar to srand48_r but like seed48 it
initializes all 48 bits of the state from the parameter seed16v.
If the return value is non-negative the function call succeeded. It
does not return a pointer to the previous state of the random number
generator like the This function is a GNU extension and should not be used in portable programs. |
| int lcong48_r (unsigned short int param[7], struct drand48_data *buffer) | Function |
|
This function initializes all aspects of the random number generator
described in buffer by the data in param. Here it is
especially true the function does more than just copying the contents of
param of buffer. Some more actions are required and
therefore it is important to use this function and not initialized the
random number generator directly.
If the return value is non-negative the function call succeeded. This function is a GNU extension and should not be used in portable programs. |
If an application uses many floating point functions, it is often the case that the costs of the function calls themselves are not negligible. Modern processor implementation often can execute the operation itself very fast but the call means a disturbance of the control flow.
For this reason the GNU C Library provides optimizations for many of the frequently used math functions. When the GNU CC is used and the user activates the optimizer several new inline functions and macros get defined. These new functions and macros have the same names as the library function and so get used instead of the latter. In case of inline functions the compiler will decide whether it is reasonable to use the inline function and this decision is usually correct.
For the generated code this means that no calls to the library functions are necessary. This increases the speed significantly. But the drawback is that the code size increases and this increase is not always negligible.
The speed increase has one drawback: the inline functions might not set
errno and might not have the same precision as the library
functions.
In cases where the inline functions and macros are not wanted the symbol
__NO_MATH_INLINES should be defined before any system header is
included. This will make sure only library functions are used. Of
course it can be determined for each single file in the project whether
giving this option is preferred or not.
Not all hardware implements the entire IEEE 754 standard, or if it does, there may be a substantial performance penalty for using some of its features. For example, enabling traps on some processors forces the FPU to run unpipelined, which more than doubles calculation time.
This chapter contains information about functions for doing basic
arithmetic operations, such as splitting a float into its integer and
fractional parts or retrieving the imaginary part of a complex value.
These functions are declared in the header files math.h and
complex.h.
Most computer hardware has support for two different kinds of numbers: integers (...-3, -2, -1, 0, 1, 2, 3...) and floating-point numbers. Floating-point numbers have three parts: the mantissa, the exponent, and the sign bit. The real number represented by a floating-point value is given by (s ? -1 : 1) · 2^e · M where s is the sign bit, e the exponent, and M the mantissa. See Floating Point Concepts, for details. (It is possible to have a different base for the exponent, but all modern hardware uses 2.)
Floating-point numbers can represent a finite subset of the real numbers. While this subset is large enough for most purposes, it is important to remember that the only reals that can be represented exactly are rational numbers that have a terminating binary expansion shorter than the width of the mantissa. Even simple fractions such as 1/5 can only be approximated by floating point.
Mathematical operations and functions frequently need to produce values that are not representable. Often these values can be approximated closely enough for practical purposes, but sometimes they can't. Historically there was no way to tell when the results of a calculation were inaccurate. Modern computers implement the IEEE 754 standard for numerical computations, which defines a framework for indicating to the program when the results of calculation are not trustworthy. This framework consists of a set of exceptions that indicate why a result could not be represented, and the special values infinity and not a number (NaN).
ISO C 9x defines macros that let you determine what sort of floating-point number a variable holds.
| int fpclassify (float-type x) | Macro |
This is a generic macro which works on all floating-point types and
which returns a value of type int. The possible values are:
|
fpclassify is most useful if more than one property of a number
must be tested. There are more specific macros which only test one
property at a time. Generally these macros execute faster than
fpclassify, since there is special hardware support for them.
You should therefore use the specific macros whenever possible.
| int isfinite (float-type x) | Macro |
This macro returns a nonzero value if x is finite: not plus or
minus infinity, and not NaN. It is equivalent to
(fpclassify (x) != FP_NAN && fpclassify (x) != FP_INFINITE)
|
| int isnormal (float-type x) | Macro |
This macro returns a nonzero value if x is finite and normalized.
It is equivalent to
(fpclassify (x) == FP_NORMAL) |
| int isnan (float-type x) | Macro |
This macro returns a nonzero value if x is NaN. It is equivalent
to
(fpclassify (x) == FP_NAN) |
Another set of floating-point classification functions was provided by BSD. The GNU C library also supports these functions; however, we recommend that you use the C9x macros in new code. Those are standard and will be available more widely. Also, since they are macros, you do not have to worry about the type of their argument.
| int isinf (double x) | Function |
| int isinff (float x) | Function |
| int isinfl (long double x) | Function |
This function returns -1 if x represents negative infinity,
1 if x represents positive infinity, and 0 otherwise.
|
| int isnan (double x) | Function |
| int isnanf (float x) | Function |
| int isnanl (long double x) | Function |
|
This function returns a nonzero value if x is a "not a number"
value, and zero otherwise.
Note: The (isnan) (x) |
| int finite (double x) | Function |
| int finitef (float x) | Function |
| int finitel (long double x) | Function |
| This function returns a nonzero value if x is finite or a "not a number" value, and zero otherwise. |
| double infnan (int error) | Function |
This function is provided for compatibility with BSD. Its argument is
an error code, EDOM or ERANGE; infnan returns the
value that a math function would return if it set errno to that
value. See Math Error Reporting. -ERANGE is also acceptable
as an argument, and corresponds to -HUGE_VAL as a value.
In the BSD library, on certain machines, |
Portability Note: The functions listed in this section are BSD extensions.
The IEEE 754 standard defines five exceptions that can occur during a calculation. Each corresponds to a particular sort of error, such as overflow.
When exceptions occur (when exceptions are raised, in the language of the standard), one of two things can happen. By default the exception is simply noted in the floating-point status word, and the program continues as if nothing had happened. The operation produces a default value, which depends on the exception (see the table below). Your program can check the status word to find out which exceptions happened.
Alternatively, you can enable traps for exceptions. In that case,
when an exception is raised, your program will receive the SIGFPE
signal. The default action for this signal is to terminate the
program. See Signal Handling, for how you can change the effect of
the signal.
In the System V math library, the user-defined function matherr
is called when certain exceptions occur inside math library functions.
However, the Unix98 standard deprecates this interface. We support it
for historical compatibility, but recommend that you do not use it in
new programs.
The exceptions defined in IEEE 754 are:
Invalid Operation
If the exception does not trap, the result of the operation is NaN.
Division by Zero
Overflow
Whenever the overflow exception is raised, the inexact exception is also
raised.
Underflow
When no trap is installed for the underflow exception, underflow is
signaled (via the underflow flag) only when both tininess and loss of
accuracy have been detected. If no trap handler is installed the
operation continues with an imprecise small value, or zero if the
destination precision cannot hold the small exact result.
Inexact
IEEE 754 floating point numbers can represent positive or negative infinity, and NaN (not a number). These three values arise from calculations whose result is undefined or cannot be represented accurately. You can also deliberately set a floating-point variable to any of them, which is sometimes useful. Some examples of calculations that produce infinity or NaN:
1/0 = ∞ log (0) = -∞ sqrt (-1) = NaN
When a calculation produces any of these values, an exception also occurs; see FP Exceptions.
The basic operations and math functions all accept infinity and NaN and produce sensible output. Infinities propagate through calculations as one would expect: for example, 2 + ∞ = ∞, 4/∞ = 0, atan (∞) = π/2. NaN, on the other hand, infects any calculation that involves it. Unless the calculation would produce the same result no matter what real value replaced NaN, the result is NaN.
In comparison operations, positive infinity is larger than all values
except itself and NaN, and negative infinity is smaller than all values
except itself and NaN. NaN is unordered: it is not equal to,
greater than, or less than anything, including itself. x ==
x is false if the value of x is NaN. You can use this to test
whether a value is NaN or not, but the recommended way to test for NaN
is with the isnan function (see Floating Point Classes). In
addition, <, >, <=, and >= will raise an
exception when applied to NaNs.
math.h defines macros that allow you to explicitly set a variable
to infinity or NaN.
| float INFINITY | Macro |
An expression representing positive infinity. It is equal to the value
produced by mathematical operations like 1.0 / 0.0.
-INFINITY represents negative infinity.
You can test whether a floating-point value is infinite by comparing it
to this macro. However, this is not recommended; you should use the
This macro was introduced in the ISO C 9X standard. |
| float NAN | Macro |
|
An expression representing a value which is "not a number". This
macro is a GNU extension, available only on machines that support the
"not a number" value--that is to say, on all machines that support
IEEE floating point.
You can use |
IEEE 754 also allows for another unusual value: negative zero. This
value is produced when you divide a positive number by negative
infinity, or when a negative result is smaller than the limits of
representation. Negative zero behaves identically to zero in all
calculations, unless you explicitly test the sign bit with
signbit or copysign.
ISO C 9x defines functions to query and manipulate the floating-point status word. You can use these functions to check for untrapped exceptions when it's convenient, rather than worrying about them in the middle of a calculation.
These constants represent the various IEEE 754 exceptions. Not all
FPUs report all the different exceptions. Each constant is defined if
and only if the FPU you are compiling for supports that exception, so
you can test for FPU support with #ifdef. They are defined in
fenv.h.
FE_INEXACT
FE_DIVBYZERO
FE_UNDERFLOW
FE_OVERFLOW
FE_INVALID
The macro FE_ALL_EXCEPT is the bitwise OR of all exception macros
which are supported by the FP implementation.
These functions allow you to clear exception flags, test for exceptions, and save and restore the set of exceptions flagged.
| void feclearexcept (int excepts) | Function |
| This function clears all of the supported exception flags indicated by excepts. |
| int fetestexcept (int excepts) | Function |
| Test whether the exception flags indicated by the parameter except are currently set. If any of them are, a nonzero value is returned which specifies which exceptions are set. Otherwise the result is zero. |
To understand these functions, imagine that the status word is an
integer variable named status. feclearexcept is then
equivalent to status &= ~excepts and fetestexcept is
equivalent to (status & excepts). The actual implementation may
be very different, of course.
Exception flags are only cleared when the program explicitly requests it,
by calling feclearexcept. If you want to check for exceptions
from a set of calculations, you should clear all the flags first. Here
is a simple example of the way to use fetestexcept:
{
double f;
int raised;
feclearexcept (FE_ALL_EXCEPT);
f = compute ();
raised = fetestexcept (FE_OVERFLOW | FE_INVALID);
if (raised & FE_OVERFLOW) { /* ... */ }
if (raised & FE_INVALID) { /* ... */ }
/* ... */
}
You cannot explicitly set bits in the status word. You can, however, save the entire status word and restore it later. This is done with the following functions:
| void fegetexceptflag (fexcept_t *flagp, int excepts) | Function |
| This function stores in the variable pointed to by flagp an implementation-defined value representing the current setting of the exception flags indicated by excepts. |
| void fesetexceptflag (const fexcept_t *flagp, int | Function |
| excepts) This function restores the flags for the exceptions indicated by excepts to the values stored in the variable pointed to by flagp. |
Note that the value stored in fexcept_t bears no resemblance to
the bit mask returned by fetestexcept. The type may not even be
an integer. Do not attempt to modify an fexcept_t variable.
Many of the math functions are defined only over a subset of the real or complex numbers. Even if they are mathematically defined, their result may be larger or smaller than the range representable by their return type. These are known as domain errors, overflows, and underflows, respectively. Math functions do several things when one of these errors occurs. In this manual we will refer to the complete response as signalling a domain error, overflow, or underflow.
When a math function suffers a domain error, it raises the invalid
exception and returns NaN. It also sets errno to EDOM;
this is for compatibility with old systems that do not support IEEE 754 exception handling. Likewise, when overflow occurs, math
functions raise the overflow exception and return ∞ or
-∞ as appropriate. They also set errno to
ERANGE. When underflow occurs, the underflow exception is
raised, and zero (appropriately signed) is returned. errno may be
set to ERANGE, but this is not guaranteed.
Some of the math functions are defined mathematically to result in a
complex value over parts of their domains. The most familiar example of
this is taking the square root of a negative number. The complex math
functions, such as csqrt, will return the appropriate complex value
in this case. The real-valued functions, such as sqrt, will
signal a domain error.
Some older hardware does not support infinities. On that hardware,
overflows instead return a particular very large number (usually the
largest representable number). math.h defines macros you can use
to test for overflow on both old and new hardware.
| double HUGE_VAL | Macro |
| float HUGE_VALF | Macro |
| long double HUGE_VALL | Macro |
An expression representing a particular very large number. On machines
that use IEEE 754 floating point format, HUGE_VAL is infinity.
On other machines, it's typically the largest positive number that can
be represented.
Mathematical functions return the appropriately typed version of
|
Floating-point calculations are carried out internally with extra precision, and then rounded to fit into the destination type. This ensures that results are as precise as the input data. IEEE 754 defines four possible rounding modes:
FLT_EPSILON.
fenv.h defines constants which you can use to refer to the
various rounding modes. Each one will be defined if and only if the FPU
supports the corresponding rounding mode.
FE_TONEAREST
FE_UPWARD
FE_DOWNWARD
FE_TOWARDZERO
Underflow is an unusual case. Normally, IEEE 754 floating point
numbers are always normalized (see Floating Point Concepts).
Numbers smaller than 2^r (where r is the minimum exponent,
FLT_MIN_RADIX-1 for float) cannot be represented as
normalized numbers. Rounding all such numbers to zero or 2^r
would cause some algorithms to fail at 0. Therefore, they are left in
denormalized form. That produces loss of precision, since some bits of
the mantissa are stolen to indicate the decimal point.
If a result is too small to be represented as a denormalized number, it
is rounded to zero. However, the sign of the result is preserved; if
the calculation was negative, the result is negative zero.
Negative zero can also result from some operations on infinity, such as
4/-∞. Negative zero behaves identically to zero except
when the copysign or signbit functions are used to check
the sign bit directly.
At any time one of the above four rounding modes is selected. You can find out which one with this function:
| int fegetround (void) | Function |
| Returns the currently selected rounding mode, represented by one of the values of the defined rounding mode macros. |
To change the rounding mode, use this function:
| int fesetround (int round) | Function |
Changes the currently selected rounding mode to round. If
round does not correspond to one of the supported rounding modes
nothing is changed. fesetround returns a nonzero value if it
changed the rounding mode, zero if the mode is not supported.
|
You should avoid changing the rounding mode if possible. It can be an expensive operation; also, some hardware requires you to compile your program differently for it to work. The resulting code may run slower. See your compiler documentation for details.
IEEE 754 floating-point implementations allow the programmer to
decide whether traps will occur for each of the exceptions, by setting
bits in the control word. In C, traps result in the program
receiving the SIGFPE signal; see Signal Handling.
Note: IEEE 754 says that trap handlers are given details of the exceptional situation, and can set the result value. C signals do not provide any mechanism to pass this information back and forth. Trapping exceptions in C is therefore not very useful.
It is sometimes necessary to save the state of the floating-point unit while you perform some calculation. The library provides functions which save and restore the exception flags, the set of exceptions that generate traps, and the rounding mode. This information is known as the floating-point environment.
The functions to save and restore the floating-point environment all use
a variable of type fenv_t to store information. This type is
defined in fenv.h. Its size and contents are
implementation-defined. You should not attempt to manipulate a variable
of this type directly.
To save the state of the FPU, use one of these functions:
| void fegetenv (fenv_t *envp) | Function |
| Store the floating-point environment in the variable pointed to by envp. |
| int feholdexcept (fenv_t *envp) | Function |
Store the current floating-point environment in the object pointed to by
envp. Then clear all exception flags, and set the FPU to trap no
exceptions. Not all FPUs support trapping no exceptions; if
feholdexcept cannot set this mode, it returns zero. If it
succeeds, it returns a nonzero value.
|
The functions which restore the floating-point environment can take two kinds of arguments:
fenv_t objects, which were initialized previously by a
call to fegetenv or feholdexcept.
FE_DFL_ENV which represents the floating-point
environment as it was available at program start.
FE_.
If possible, the GNU C Library defines a macro FE_NOMASK_ENV
which represents an environment where every exception raised causes a
trap to occur. You can test for this macro using #ifdef. It is
only defined if _GNU_SOURCE is defined.
Some platforms might define other predefined environments.
To set the floating-point environment, you can use either of these functions:
| void fesetenv (const fenv_t *envp) | Function |
| Set the floating-point environment to that described by envp. |
| void feupdateenv (const fenv_t *envp) | Function |
Like fesetenv, this function sets the floating-point environment
to that described by envp. However, if any exceptions were
flagged in the status word before feupdateenv was called, they
remain flagged after the call. In other words, after feupdateenv
is called, the status word is the bitwise OR of the previous status word
and the one saved in envp.
|
The C library provides functions to do basic operations on floating-point numbers. These include absolute value, maximum and minimum, normalization, bit twiddling, rounding, and a few others.
These functions are provided for obtaining the absolute value (or
magnitude) of a number. The absolute value of a real number
x is x if x is positive, -x if x is
negative. For a complex number z, whose real part is x and
whose imaginary part is y, the absolute value is sqrt (x*x + y*y).
Prototypes for abs, labs and llabs are in stdlib.h;
imaxabs is declared in inttypes.h;
fabs, fabsf and fabsl are declared in math.h.
cabs, cabsf and cabsl are declared in complex.h.
| int abs (int number) | Function |
| long int labs (long int number) | Function |
| long long int llabs (long long int number) | Function |
| intmax_t imaxabs (intmax_t number) | Function |
|
These functions return the absolute value of number.
Most computers use a two's complement integer representation, in which
the absolute value of
|
| double fabs (double number) | Function |
| float fabsf (float number) | Function |
| long double fabsl (long double number) | Function |
| This function returns the absolute value of the floating-point number number. |
| double cabs (complex double z) | Function |
| float cabsf (complex float z) | Function |
| long double cabsl (complex long double z) | Function |
These functions return the absolute value of the complex number z
(see Complex Numbers). The absolute value of a complex number is:
sqrt (creal (z) * creal (z) + cimag (z) * cimag (z)) This function should always be used instead of the direct formula
because it takes special care to avoid losing precision. It may also
take advantage of hardware support for this operation. See |
The functions described in this section are primarily provided as a way to efficiently perform certain low-level manipulations on floating point numbers that are represented internally using a binary radix; see Floating Point Concepts. These functions are required to have equivalent behavior even if the representation does not use a radix of 2, but of course they are unlikely to be particularly efficient in those cases.
All these functions are declared in math.h.
| double frexp (double value, int *exponent) | Function |
| float frexpf (float value, int *exponent) | Function |
| long double frexpl (long double value, int *exponent) | Function |
|
These functions are used to split the number value
into a normalized fraction and an exponent.
If the argument value is not zero, the return value is value
times a power of two, and is always in the range 1/2 (inclusive) to 1
(exclusive). The corresponding exponent is stored in
For example, If value is zero, then the return value is zero and
zero is stored in |
| double ldexp (double value, int exponent) | Function |
| float ldexpf (float value, int exponent) | Function |
| long double ldexpl (long double value, int exponent) | Function |
These functions return the result of multiplying the floating-point
number value by 2 raised to the power exponent. (It can
be used to reassemble floating-point numbers that were taken apart
by frexp.)
For example, |
The following functions, which come from BSD, provide facilities
equivalent to those of ldexp and frexp.
| double logb (double x) | Function |
| float logbf (float x) | Function |
| long double logbl (long double x) | Function |
These functions return the integer part of the base-2 logarithm of
x, an integer value represented in type double. This is
the highest integer power of 2 contained in x. The sign of
x is ignored. For example, logb (3.5) is 1.0 and
logb (4.0) is 2.0.
When If x is zero, the return value is minus infinity if the machine supports infinities, and a very small number if it does not. If x is infinity, the return value is infinity. For finite x, the value returned by |
| double scalb (double value, int exponent) | Function |
| float scalbf (float value, int exponent) | Function |
| long double scalbl (long double value, int exponent) | Function |
The scalb function is the BSD name for ldexp.
|
| long long int scalbn (double x, int n) | Function |
| long long int scalbnf (float x, int n) | Function |
| long long int scalbnl (long double x, int n) | Function |
scalbn is identical to scalb, except that the exponent
n is an int instead of a floating-point number.
|
| long long int scalbln (double x, long int n) | Function |
| long long int scalblnf (float x, long int n) | Function |
| long long int scalblnl (long double x, long int n) | Function |
scalbln is identical to scalb, except that the exponent
n is a long int instead of a floating-point number.
|
| long long int significand (double x) | Function |
| long long int significandf (float x) | Function |
| long long int significandl (long double x) | Function |
significand returns the mantissa of x scaled to the range
[1, 2).
It is equivalent to scalb (x, (double) -ilogb (x)).
This function exists mainly for use in certain standardized tests of IEEE 754 conformance. |
The functions listed here perform operations such as rounding and
truncation of floating-point values. Some of these functions convert
floating point numbers to integer values. They are all declared in
math.h.
You can also convert floating-point numbers to integers simply by
casting them to int. This discards the fractional part,
effectively rounding towards zero. However, this only works if the
result can actually be represented as an int--for very large
numbers, this is impossible. The functions listed here return the
result as a double instead to get around this problem.
| double ceil (double x) | Function |
| float ceilf (float x) | Function |
| long double ceill (long double x) | Function |
These functions round x upwards to the nearest integer,
returning that value as a double. Thus, ceil (1.5)
is 2.0.
|
| double floor (double x) | Function |
| float floorf (float x) | Function |
| long double floorl (long double x) | Function |
These functions round x downwards to the nearest
integer, returning that value as a double. Thus, floor
(1.5) is 1.0 and floor (-1.5) is -2.0.
|
| double trunc (double x) | Function |
| float truncf (float x) | Function |
| long double truncl (long double x) | Function |
trunc is another name for floor
|
| double rint (double x) | Function |
| float rintf (float x) | Function |
| long double rintl (long double x) | Function |
|
These functions round x to an integer value according to the
current rounding mode. See Floating Point Parameters, for
information about the various rounding modes. The default
rounding mode is to round to the nearest integer; some machines
support other modes, but round-to-nearest is always used unless
you explicitly select another.
If x was not initially an integer, these functions raise the inexact exception. |
| double nearbyint (double x) | Function |
| float nearbyintf (float x) | Function |
| long double nearbyintl (long double x) | Function |
These functions return the same value as the rint functions, but
do not raise the inexact exception if x is not an integer.
|
| double round (double x) | Function |
| float roundf (float x) | Function |
| long double roundl (long double x) | Function |
These functions are similar to rint, but they round halfway
cases away from zero instead of to the nearest even integer.
|
| long int lrint (double x) | Function |
| long int lrintf (float x) | Function |
| long int lrintl (long double x) | Function |
These functions are just like rint, but they return a
long int instead of a floating-point number.
|
| long long int llrint (double x) | Function |
| long long int llrintf (float x) | Function |
| long long int llrintl (long double x) | Function |
These functions are just like rint, but they return a
long long int instead of a floating-point number.
|
| long int lround (double x) | Function |
| long int lroundf (float x) | Function |
| long int lroundl (long double x) | Function |
These functions are just like round, but they return a
long int instead of a floating-point number.
|
| long long int llround (double x) | Function |
| long long int llroundf (float x) | Function |
| long long int llroundl (long double x) | Function |
These functions are just like round, but they return a
long long int instead of a floating-point number.
|
| double modf (double value, double *integer-part) | Function |
| float modff (float value, float *integer-part) | Function |
| long double modfl (long double value, long double *integer-part) | Function |
These functions break the argument value into an integer part and a
fractional part (between -1 and 1, exclusive). Their sum
equals value. Each of the parts has the same sign as value,
and the integer part is always rounded toward zero.
|
The functions in this section compute the remainder on division of two floating-point numbers. Each is a little different; pick the one that suits your problem.
| double fmod (double numerator, double denominator) | Function |
| float fmodf (float numerator, float denominator) | Function |
| long double fmodl (long double numerator, long double denominator) | Function |
These functions compute the remainder from the division of
numerator by denominator. Specifically, the return value is
numerator - n * denominator, where n
is the quotient of numerator divided by denominator, rounded
towards zero to an integer. Thus, fmod (6.5, 2.3) returns
1.9, which is 6.5 minus 4.6.
The result has the same sign as the numerator and has magnitude less than the magnitude of the denominator. If denominator is zero, |
| double drem (double numerator, double denominator) | Function |
| float dremf (float numerator, float denominator) | Function |
| long double dreml (long double numerator, long double denominator) | Function |
These functions are like fmod except that they rounds the
internal quotient n to the nearest integer instead of towards zero
to an integer. For example, drem (6.5, 2.3) returns -0.4,
which is 6.5 minus 6.9.
The absolute value of the result is less than or equal to half the
absolute value of the denominator. The difference between
If denominator is zero, |
| double remainder (double numerator, double denominator) | Function |
| float remainderf (float numerator, float denominator) | Function |
| long double remainderl (long double numerator, long double denominator) | Function |
This function is another name for drem.
|
There are some operations that are too complicated or expensive to perform by hand on floating-point numbers. ISO C 9x defines functions to do these operations, which mostly involve changing single bits.
| double copysign (double x, double y) | Function |
| float copysignf (float x, float y) | Function |
| long double copysignl (long double x, long double y) | Function |
|
These functions return x but with the sign of y. They work
even if x or y are NaN or zero. Both of these can carry a
sign (although not all implementations support it) and this is one of
the few operations that can tell the difference.
This function is defined in IEC 559 (and the appendix with recommended functions in IEEE 754/IEEE 854). |
| int signbit (float-type x) | Function |
signbit is a generic macro which can work on all floating-point
types. It returns a nonzero value if the value of x has its sign
bit set.
This is not the same as |
| double nextafter (double x, double y) | Function |
| float nextafterf (float x, float y) | Function |
| long double nextafterl (long double x, long double y) | Function |
The nextafter function returns the next representable neighbor of
x in the direction towards y. The size of the step between
x and the result depends on the type of the result. If
x = y the function simply returns x. If either
value is NaN, NaN is returned. Otherwise
a value corresponding to the value of the least significant bit in the
mantissa is added or subtracted, depending on the direction.
nextafter will signal overflow or underflow if the result goes
outside of the range of normalized numbers.
This function is defined in IEC 559 (and the appendix with recommended functions in IEEE 754/IEEE 854). |
| double nexttoward (double x, long double y) | Function |
| float nexttowardf (float x, long double y) | Function |
| long double nexttowardl (long double x, long double y) | Function |
These functions are identical to the corresponding versions of
nextafter except that their second argument is a long
double.
|
| double nan (const char *tagp) | Function |
| float nanf (const char *tagp) | Function |
| long double nanl (const char *tagp) | Function |
The nan function returns a representation of NaN, provided that
NaN is supported by the target platform.
nan ("n-char-sequence") is equivalent to
strtod ("NAN(n-char-sequence)").
The argument tagp is used in an unspecified manner. On IEEE 754 systems, there are many representations of NaN, and tagp selects one. On other systems it may do nothing. |
The standard C comparison operators provoke exceptions when one or other of the operands is NaN. For example,
int v = a < 1.0;
will raise an exception if a is NaN. (This does not
happen with == and !=; those merely return false and true,
respectively, when NaN is examined.) Frequently this exception is
undesirable. ISO C 9x therefore defines comparison functions that
do not raise exceptions when NaN is examined. All of the functions are
implemented as macros which allow their arguments to be of any
floating-point type. The macros are guaranteed to evaluate their
arguments only once.
| int isgreater (real-floating x, real-floating y) | Macro |
This macro determines whether the argument x is greater than
y. It is equivalent to (x) > (y), but no
exception is raised if x or y are NaN.
|
| int isgreaterequal (real-floating x, real-floating y) | Macro |
This macro determines whether the argument x is greater than or
equal to y. It is equivalent to (x) >= (y), but no
exception is raised if x or y are NaN.
|
| int isless (real-floating x, real-floating y) | Macro |
This macro determines whether the argument x is less than y.
It is equivalent to (x) < (y), but no exception is
raised if x or y are NaN.
|
| int islessequal (real-floating x, real-floating y) | Macro |
This macro determines whether the argument x is less than or equal
to y. It is equivalent to (x) <= (y), but no
exception is raised if x or y are NaN.
|
| int islessgreater (real-floating x, real-floating y) | Macro |
This macro determines whether the argument x is less or greater
than y. It is equivalent to (x) < (y) ||
(x) > (y) (although it only evaluates x and y
once), but no exception is raised if x or y are NaN.
This macro is not equivalent to |
| int isunordered (real-floating x, real-floating y) | Macro |
| This macro determines whether its arguments are unordered. In other words, it is true if x or y are NaN, and false otherwise. |
Not all machines provide hardware support for these operations. On machines that don't, the macros can be very slow. Therefore, you should not use these functions when NaN is not a concern.
Note: There are no macros isequal or isunequal.
They are unnecessary, because the == and != operators do
not throw an exception if one or both of the operands are NaN.
The functions in this section perform miscellaneous but common operations that are awkward to express with C operators. On some processors these functions can use special machine instructions to perform these operations faster than the equivalent C code.
| double fmin (double x, double y) | Function |
| float fminf (float x, float y) | Function |
| long double fminl (long double x, long double y) | Function |
The fmin function returns the lesser of the two values x
and y. It is similar to the expression
((x) < (y) ? (x) : (y))except that x and y are only evaluated once. If an argument is NaN, the other argument is returned. If both arguments are NaN, NaN is returned. |
| double fmax (double x, double y) | Function |
| float fmaxf (float x, float y) | Function |
| long double fmaxl (long double x, long double y) | Function |
The fmax function returns the greater of the two values x
and y.
If an argument is NaN, the other argument is returned. If both arguments are NaN, NaN is returned. |
| double fdim (double x, double y) | Function |
| float fdimf (float x, float y) | Function |
| long double fdiml (long double x, long double y) | Function |
The fdim function returns the positive difference between
x and y. The positive difference is x -
y if x is greater than y, and 0 otherwise.
If x, y, or both are NaN, NaN is returned. |
| double fma (double x, double y, double z) | Function |
| float fmaf (float x, float y, float z) | Function |
| long double fmal (long double x, long double y, long double z) | Function |
The fma function performs floating-point multiply-add. This is
the operation (x · y) + z, but the
intermediate result is not rounded to the destination type. This can
sometimes improve the precision of a calculation.
This function was introduced because some processors have a special
instruction to perform multiply-add. The C compiler cannot use it
directly, because the expression On processors which do not implement multiply-add in hardware,
|
ISO C 9x introduces support for complex numbers in C. This is done
with a new type qualifier, complex. It is a keyword if and only
if complex.h has been included. There are three complex types,
corresponding to the three real types: float complex,
double complex, and long double complex.
To construct complex numbers you need a way to indicate the imaginary
part of a number. There is no standard notation for an imaginary
floating point constant. Instead, complex.h defines two macros
that can be used to create complex numbers.
| const float complex _Complex_I | Macro |
This macro is a representation of the complex number "0+1i".
Multiplying a real floating-point value by _Complex_I gives a
complex number whose value is purely imaginary. You can use this to
construct complex constants:
3.0 + 4.0i =
Note that |
_Complex_I is a bit of a mouthful. complex.h also defines
a shorter name for the same constant.
| const float complex I | Macro |
This macro has exactly the same value as _Complex_I. Most of the
time it is preferable. However, it causes problems if you want to use
the identifier I for something else. You can safely write
#include <complex.h> #undef I if you need |
ISO C 9x also defines functions that perform basic operations on
complex numbers, such as decomposition and conjugation. The prototypes
for all these functions are in complex.h. All functions are
available in three variants, one for each of the three complex types.
| double creal (complex double z) | Function |
| float crealf (complex float z) | Function |
| long double creall (complex long double z) | Function |
| These functions return the real part of the complex number z. |
| double cimag (complex double z) | Function |
| float cimagf (complex float z) | Function |
| long double cimagl (complex long double z) | Function |
| These functions return the imaginary part of the complex number z. |
| complex double conj (complex double z) | Function |
| complex float conjf (complex float z) | Function |
| complex long double conjl (complex long double z) | Function |
These functions return the conjugate value of the complex number
z. The conjugate of a complex number has the same real part and a
negated imaginary part. In other words, conj(a + bi) = a + -bi.
|
| double carg (complex double z) | Function |
| float cargf (complex float z) | Function |
| long double cargl (complex long double z) | Function |
|
These functions return the argument of the complex number z.
The argument of a complex number is the angle in the complex plane
between the positive real axis and a line passing through zero and the
number. This angle is measured in the usual fashion and ranges from 0
to 2π.
|
| complex double cproj (complex double z) | Function |
| complex float cprojf (complex float z) | Function |
| complex long double cprojl (complex long double z) | Function |
These functions return the projection of the complex value z onto
the Riemann sphere. Values with a infinite imaginary part are projected
to positive infinity on the real axis, even if the real part is NaN. If
the real part is infinite, the result is equivalent to
INFINITY + I * copysign (0.0, cimag (z)) |
This section describes functions for performing integer division. These
functions are redundant when GNU CC is used, because in GNU C the
/ operator always rounds towards zero. But in other C
implementations, / may round differently with negative arguments.
div and ldiv are useful because they specify how to round
the quotient: towards zero. The remainder has the same sign as the
numerator.
These functions are specified to return a result r such that the value
r.quot*denominator + r.rem equals
numerator.
To use these facilities, you should include the header file
stdlib.h in your program.
| div_t | Data Type |
This is a structure type used to hold the result returned by the div
function. It has the following members:
|
| div_t div (int numerator, int denominator) | Function |
This function div computes the quotient and remainder from
the division of numerator by denominator, returning the
result in a structure of type div_t.
If the result cannot be represented (as in a division by zero), the behavior is undefined. Here is an example, albeit not a very useful one. div_t result; result = div (20, -6); Now |
| ldiv_t | Data Type |
This is a structure type used to hold the result returned by the ldiv
function. It has the following members:
(This is identical to |
| ldiv_t ldiv (long int numerator, long int denominator) | Function |
The ldiv function is similar to div, except that the
arguments are of type long int and the result is returned as a
structure of type ldiv_t.
|
| lldiv_t | Data Type |
This is a structure type used to hold the result returned by the lldiv
function. It has the following members:
(This is identical to |
| lldiv_t lldiv (long long int numerator, long long int denominator) | Function |
The lldiv function is like the div function, but the
arguments are of type long long int and the result is returned as
a structure of type lldiv_t.
The |
| imaxdiv_t | Data Type |
This is a structure type used to hold the result returned by the imaxdiv
function. It has the following members:
(This is identical to |
| imaxdiv_t imaxdiv (intmax_t numerator, intmax_t denominator) | Function |
The imaxdiv function is like the div function, but the
arguments are of type intmax_t and the result is returned as
a structure of type imaxdiv_t.
The |
This section describes functions for "reading" integer and
floating-point numbers from a string. It may be more convenient in some
cases to use sscanf or one of the related functions; see
Formatted Input. But often you can make a program more robust by
finding the tokens in the string by hand, then converting the numbers
one by one.
These functions are declared in stdlib.h.
| long int strtol (const char *string, char **tailptr, int base) | Function |
The strtol ("string-to-long") function converts the initial
part of string to a signed integer, which is returned as a value
of type long int.
This function attempts to decompose string as follows:
If the string is empty, contains only whitespace, or does not contain an
initial substring that has the expected syntax for an integer in the
specified base, no conversion is performed. In this case,
In a locale other than the standard If the string has valid syntax for an integer but the value is not
representable because of overflow, You should not check for errors by examining the return value of
There is an example at the end of this section. |
| unsigned long int strtoul (const char *string, char **tailptr, int base) | Function |
The strtoul ("string-to-unsigned-long") function is like
strtol except it returns an unsigned long int value. If
the number has a leading - sign, the return value is negated.
The syntax is the same as described above for strtol. The value
returned on overflow is ULONG_MAX (see Range of Type).
|
| long long int strtoll (const char *string, char **tailptr, int base) | Function |
The strtoll function is like strtol except that it returns
a long long int value, and accepts numbers with a correspondingly
larger range.
If the string has valid syntax for an integer but the value is not
representable because of overflow, The |
| long long int strtoq (const char *string, char **tailptr, int base) | Function |
strtoq ("string-to-quad-word") is the BSD name for strtoll.
|
| unsigned long long int strtoull (const char *string, char **tailptr, int base) | Function |
The strtoull function is like strtoul except that it
returns an unsigned long long int. The value returned on overflow
is ULONG_LONG_MAX (see Range of Type).
The |
| unsigned long long int strtouq (const char *string, char **tailptr, int base) | Function |
strtouq is the BSD name for strtoull.
|
| long int atol (const char *string) | Function |
This function is similar to the strtol function with a base
argument of 10, except that it need not detect overflow errors.
The atol function is provided mostly for compatibility with
existing code; using strtol is more robust.
|
| int atoi (const char *string) | Function |
This function is like atol, except that it returns an int.
The atoi function is also considered obsolete; use strtol
instead.
|
| long long int atoll (const char *string) | Function |
This function is similar to atol, except it returns a long
long int.
The |
Some locales specify a printed syntax for numbers other than the one
that these functions understand. If you need to read numbers formatted
in some other locale, you can use the strtoX_l functions. Each
of the strtoX functions has a counterpart with _l added to
its name. The _l counterparts take an additional argument: a
pointer to an locale_t structure, which describes how the numbers
to be read are formatted. See Locales.
Portability Note: These functions are all GNU extensions. You
can also use scanf or its relatives, which have the ' flag
for parsing numeric input according to the current locale
(see Numeric Input Conversions). This feature is standard.
Here is a function which parses a string as a sequence of integers and returns the sum of them:
int
sum_ints_from_string (char *string)
{
int sum = 0;
while (1) {
char *tail;
int next;
/* Skip whitespace by hand, to detect the end. */
while (isspace (*string)) string++;
if (*string == 0)
break;
/* There is more nonwhitespace, */
/* so it ought to be another number. */
errno = 0;
/* Parse it. */
next = strtol (string, &tail, 0);
/* Add it in, if not overflow. */
if (errno)
printf ("Overflow\n");
else
sum += next;
/* Advance past it. */
string = tail;
}
return sum;
}
These functions are declared in stdlib.h.
| double strtod (const char *string, char **tailptr) | Function |
The strtod ("string-to-double") function converts the initial
part of string to a floating-point number, which is returned as a
value of type double.
This function attempts to decompose string as follows:
If the string is empty, contains only whitespace, or does not contain an
initial substring that has the expected syntax for a floating-point
number, no conversion is performed. In this case, In a locale other than the standard If the string has valid syntax for a floating-point number but the value
is outside the range of a
The strings Since zero is a valid result as well as the value returned on error, you
should check for errors in the same way as for |
| float strtof (const char *string, char **tailptr) | Function |
| long double strtold (const char *string, char **tailptr) | Function |
These functions are analogous to strtod, but return float
and long double values respectively. They report errors in the
same way as strtod. strtof can be substantially faster
than strtod, but has less precision; conversely, strtold
can be much slower but has more precision (on systems where long
double is a separate type).
These functions are GNU extensions. |
| double atof (const char *string) | Function |
This function is similar to the strtod function, except that it
need not detect overflow and underflow errors. The atof function
is provided mostly for compatibility with existing code; using
strtod is more robust.
|
The GNU C library also provides _l versions of these functions,
which take an additional argument, the locale to use in conversion.
See Parsing of Integers.
The old System V C library provided three functions to convert numbers to strings, with unusual and hard-to-use semantics. The GNU C library also provides these functions and some natural extensions.
These functions are only available in glibc and on systems descended
from AT&T Unix. Therefore, unless these functions do precisely what you
need, it is better to use sprintf, which is standard.
All these functions are defined in stdlib.h.
| char * ecvt (double value, int ndigit, int *decpt, int *neg) | Function |
The function ecvt converts the floating-point number value
to a string with at most ndigit decimal digits. The
returned string contains no decimal point or sign. The first digit of
the string is non-zero (unless value is actually zero) and the
last digit is rounded to nearest. *decpt is set to the
index in the string of the first digit after the decimal point.
*neg is set to a nonzero value if value is negative,
zero otherwise.
If ndigit decimal digits would exceed the precision of a
The returned string is statically allocated and overwritten by each call
to If value is zero, it is implementation defined whether
For example: |
| char * fcvt (double value, int ndigit, int *decpt, int *neg) | Function |
The function fcvt is like ecvt, but ndigit specifies
the number of digits after the decimal point. If ndigit is less
than zero, value is rounded to the ndigit+1'th place to the
left of the decimal point. For example, if ndigit is -1,
value will be rounded to the nearest 10. If ndigit is
negative and larger than the number of digits to the left of the decimal
point in value, value will be rounded to one significant digit.
If ndigit decimal digits would exceed the precision of a
The returned string is statically allocated and overwritten by each call
to |
| char * gcvt (double value, int ndigit, char *buf) | Function |
gcvt is functionally equivalent to sprintf(buf, "%*g",
ndigit, value. It is provided only for compatibility's sake. It
returns buf.
If ndigit decimal digits would exceed the precision of a
|
As extensions, the GNU C library provides versions of these three
functions that take long double arguments.
| char * qecvt (long double value, int ndigit, int *decpt, int *neg) | Function |
This function is equivalent to ecvt except that it takes a
long double for the first parameter and that ndigit is
restricted by the precision of a long double.
|
| char * qfcvt (long double value, int ndigit, int *decpt, int *neg) | Function |
This function is equivalent to fcvt except that it
takes a long double for the first parameter and that ndigit is
restricted by the precision of a long double.
|
| char * qgcvt (long double value, int ndigit, char *buf) | Function |
This function is equivalent to gcvt except that it takes a
long double for the first parameter and that ndigit is
restricted by the precision of a long double.
|
The ecvt and fcvt functions, and their long double
equivalents, all return a string located in a static buffer which is
overwritten by the next call to the function. The GNU C library
provides another set of extended functions which write the converted
string into a user-supplied buffer. These have the conventional
_r suffix.
gcvt_r is not necessary, because gcvt already uses a
user-supplied buffer.
| char * ecvt_r (double value, int ndigit, int *decpt, int *neg, char *buf, size_t len) | Function |
The ecvt_r function is the same as ecvt, except
that it places its result into the user-specified buffer pointed to by
buf, with length len.
This function is a GNU extension. |
| char * fcvt_r (double value, int ndigit, int *decpt, int *neg, char *buf, size_t len) | Function |
The fcvt_r function is the same as fcvt, except
that it places its result into the user-specified buffer pointed to by
buf, with length len.
This function is a GNU extension. |
| char * qecvt_r (long double value, int ndigit, int *decpt, int *neg, char *buf, size_t len) | Function |
The qecvt_r function is the same as qecvt, except
that it places its result into the user-specified buffer pointed to by
buf, with length len.
This function is a GNU extension. |
| char * qfcvt_r (long double value, int ndigit, int *decpt, int *neg, char *buf, size_t len) | Function |
The qfcvt_r function is the same as qfcvt, except
that it places its result into the user-specified buffer pointed to by
buf, with length len.
This function is a GNU extension. |
This chapter describes functions for manipulating dates and times, including functions for determining what the current time is and conversion between different time representations.
The time functions fall into three main categories:
If you're trying to optimize your program or measure its efficiency, it's
very useful to be able to know how much processor time or CPU
time it has used at any given point. Processor time is different from
actual wall clock time because it doesn't include any time spent waiting
for I/O or when some other process is running. Processor time is
represented by the data type clock_t, and is given as a number of
clock ticks relative to an arbitrary base time marking the beginning
of a single program invocation.
clock function.
times function.
To get the elapsed CPU time used by a process, you can use the
clock function. This facility is declared in the header file
time.h.
In typical usage, you call the clock function at the beginning and
end of the interval you want to time, subtract the values, and then divide
by CLOCKS_PER_SEC (the number of clock ticks per second), like this:
#include <time.h> clock_t start, end; double elapsed; start = clock(); ... /* Do the work. */ end = clock(); elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
Different computers and operating systems vary wildly in how they keep track of processor time. It's common for the internal processor clock to have a resolution somewhere between hundredth and millionth of a second.
In the GNU system, clock_t is equivalent to long int and
CLOCKS_PER_SEC is an integer value. But in other systems, both
clock_t and the type of the macro CLOCKS_PER_SEC can be
either integer or floating-point types. Casting processor time values
to double, as in the example above, makes sure that operations
such as arithmetic and printing work properly and consistently no matter
what the underlying representation is.
Note that the clock can wrap around. On a 32bit system with
CLOCKS_PER_SEC set to one million a wrap around happens after
around 36 minutes.
| int CLOCKS_PER_SEC | Macro |
The value of this macro is the number of clock ticks per second measured
by the clock function. POSIX requires that this value is one
million independent of the actual resolution.
|
| int CLK_TCK | Macro |
This is an obsolete name for CLOCKS_PER_SEC.
|
| clock_t | Data Type |
This is the type of the value returned by the clock function.
Values of type clock_t are in units of clock ticks.
|
| clock_t clock (void) | Function |
This function returns the elapsed processor time. The base time is
arbitrary but doesn't change within a single process. If the processor
time is not available or cannot be represented, clock returns the
value (clock_t)(-1).
|
The times function returns more detailed information about
elapsed processor time in a struct tms object. You should
include the header file sys/times.h to use this facility.
| struct tms | Data Type |
The tms structure is used to return information about process
times. It contains at least the following members:
All of the times are given in clock ticks. These are absolute values; in a newly created process, they are all zero. See Creating a Process. |
| clock_t times (struct tms *buffer) | Function |
The times function stores the processor time information for
the calling process in buffer.
The return value is the same as the value of |
Portability Note: The clock function described in
Basic CPU Time, is specified by the ISO C standard. The
times function is a feature of POSIX.1. In the GNU system, the
value returned by the clock function is equivalent to the sum of
the tms_utime and tms_stime fields returned by
times.
This section describes facilities for keeping track of dates and times according to the Gregorian calendar.
There are three representations for date and time information:
time_t data type) is a compact
representation, typically giving the number of seconds elapsed since
some implementation-specific base time.
struct
timeval data type) that includes fractions of a second. Use this time
representation instead of ordinary calendar time when you need greater
precision.
struct
tm data type) represents the date and time as a set of components
specifying the year, month, and so on, for a specific time zone.
This time representation is usually used in conjunction with formatting
date and time values.
This section describes the time_t data type for representing
calendar time, and the functions which operate on calendar time objects.
These facilities are declared in the header file time.h.
| time_t | Data Type |
This is the data type used to represent calendar time.
When interpreted as an absolute time
value, it represents the number of seconds elapsed since 00:00:00 on
January 1, 1970, Coordinated Universal Time. (This date is sometimes
referred to as the epoch.) POSIX requires that this count
ignore leap seconds, but on some hosts this count includes leap seconds
if you set TZ to certain values (see TZ Variable).
In the GNU C library, |
| double difftime (time_t time1, time_t time0) | Function |
The difftime function returns the number of seconds elapsed
between time time1 and time time0, as a value of type
double. The difference ignores leap seconds unless leap
second support is enabled.
In the GNU system, you can simply subtract |
| time_t time (time_t *result) | Function |
The time function returns the current time as a value of type
time_t. If the argument result is not a null pointer, the
time value is also stored in *result. If the calendar
time is not available, the value (time_t)(-1) is returned.
|
The time_t data type used to represent calendar times has a
resolution of only one second. Some applications need more precision.
So, the GNU C library also contains functions which are capable of
representing calendar times to a higher resolution than one second. The
functions and the associated data types described in this section are
declared in sys/time.h.
| struct timeval | Data Type |
The struct timeval structure represents a calendar time. It
has the following members:
|
| struct timezone | Data Type |
The struct timezone structure is used to hold minimal information
about the local time zone. It has the following members:
The |
It is often necessary to subtract two values of type struct timeval. Here is the best way to do this. It works even on some
peculiar operating systems where the tv_sec member has an
unsigned type.
/* Subtract the `struct timeval' values X and Y,
storing the result in RESULT.
Return 1 if the difference is negative, otherwise 0. */
int
timeval_subtract (result, x, y)
struct timeval *result, *x, *y;
{
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait.
tv_usec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
| int gettimeofday (struct timeval *tp, struct timezone *tzp) | Function |
The gettimeofday function returns the current date and time in the
struct timeval structure indicated by tp. Information about the
time zone is returned in the structure pointed at tzp. If the tzp
argument is a null pointer, time zone information is ignored.
The return value is
|
| int settimeofday (const struct timeval *tp, const struct timezone *tzp) | Function |
The settimeofday function sets the current date and time
according to the arguments. As for gettimeofday, time zone
information is ignored if tzp is a null pointer.
You must be a privileged user in order to use The return value is
|
| int adjtime (const struct timeval *delta, struct timeval *olddelta) | Function |
|
This function speeds up or slows down the system clock in order to make
gradual adjustments in the current time. This ensures that the time
reported by the system clock is always monotonically increasing, which
might not happen if you simply set the current time.
The delta argument specifies a relative adjustment to be made to the current time. If negative, the system clock is slowed down for a while until it has lost this much time. If positive, the system clock is speeded up for a while. If the olddelta argument is not a null pointer, the This function is typically used to synchronize the clocks of computers
in a local network. You must be a privileged user to use it.
The return value is
|
Portability Note: The gettimeofday, settimeofday,
and adjtime functions are derived from BSD.
Calendar time is represented as a number of seconds. This is convenient for calculation, but has no resemblance to the way people normally represent dates and times. By contrast, broken-down time is a binary representation separated into year, month, day, and so on. Broken down time values are not useful for calculations, but they are useful for printing human readable time.
A broken-down time value is always relative to a choice of local time zone, and it also indicates which time zone was used.
The symbols in this section are declared in the header file time.h.
| struct tm | Data Type |
This is the data type used to represent a broken-down time. The structure
contains at least the following members, which can appear in any order:
|
| struct tm * localtime (const time_t *time) | Function |
The localtime function converts the calendar time pointed to by
time to broken-down time representation, expressed relative to the
user's specified time zone.
The return value is a pointer to a static broken-down time structure, which
might be overwritten by subsequent calls to The return value is the null pointer if time cannot be represented
as a broken-down time; typically this is because the year cannot fit into
an Calling |
Using the localtime function is a big problem in multi-threaded
programs. The result is returned in a static buffer and this is used in
all threads. POSIX.1c introduced a variant of this function.
| struct tm * localtime_r (const time_t *time, struct tm *resultp) | Function |
The localtime_r function works just like the localtime
function. It takes a pointer to a variable containing the calendar time
and converts it to the broken-down time format.
But the result is not placed in a static buffer. Instead it is placed
in the object of type If the conversion is successful the function returns a pointer to the object the result was written into, i.e., it returns resultp. |
| struct tm * gmtime (const time_t *time) | Function |
This function is similar to localtime, except that the broken-down
time is expressed as Coordinated Universal Time (UTC)--that is, as
Greenwich Mean Time (GMT)--rather than relative to the local time zone.
Recall that calendar times are always expressed in coordinated universal time. |
As for the localtime function we have the problem that the result
is placed in a static variable. POSIX.1c also provides a replacement for
gmtime.
| struct tm * gmtime_r (const time_t *time, struct tm *resultp) | Function |
This function is similar to localtime_r, except that it converts
just like gmtime the given time as Coordinated Universal Time.
If the conversion is successful the function returns a pointer to the object the result was written into, i.e., it returns resultp. |
| time_t mktime (struct tm *brokentime) | Function |
The mktime function is used to convert a broken-down time structure
to a calendar time representation. It also "normalizes" the contents of
the broken-down time structure, by filling in the day of week and day of
year based on the other date and time components.
The If the specified broken-down time cannot be represented as a calendar time,
Calling |
The functions described in this section format time values as strings.
These functions are declared in the header file time.h.
| char * asctime (const struct tm *brokentime) | Function |
The asctime function converts the broken-down time value that
brokentime points to into a string in a standard format:
"Tue May 21 13:46:22 1991\n" The abbreviations for the days of week are: The abbreviations for the months are: The return value points to a statically allocated string, which might be
overwritten by subsequent calls to |
| char * asctime_r (const struct tm *brokentime, char *buffer) | Function |
This function is similar to asctime but instead of placing the
result in a static buffer it writes the string in the buffer pointed to
by the parameter buffer. This buffer should have at least room
for 16 bytes.
If no error occurred the function returns a pointer to the string the
result was written into, i.e., it returns buffer. Otherwise
return |
| char * ctime (const time_t *time) | Function |
The ctime function is similar to asctime, except that the
time value is specified as a time_t calendar time value rather
than in broken-down local time format. It is equivalent to
asctime (localtime (time))
|
| char * ctime_r (const time_t *time, char *buffer) | Function |
This function is similar to ctime, only that it places the result
in the string pointed to by buffer. It is equivalent to (written
using gcc extensions, see Statement Exprs):
({ struct tm tm; asctime_r (localtime_r (time, &tm), buf); })
If no error occurred the function returns a pointer to the string the
result was written into, i.e., it returns buffer. Otherwise
return |
| size_t strftime (char *s, size_t size, const char *template, const struct tm *brokentime) | Function |
This function is similar to the sprintf function (see Formatted Input), but the conversion specifications that can appear in the format
template template are specialized for printing components of the date
and time brokentime according to the locale currently specified for
time conversion (see Locales).
Ordinary characters appearing in the template are copied to the
output string s; this can include multibyte character sequences.
Conversion specifiers are introduced by a
The default action is to pad the number with zeros to keep it a constant width. Numbers that do not have a range indicated below are never padded, since there is no natural width for them. Following the flag an optional specification of the width is possible. This is specified in decimal notation. If the natural size of the output is of the field has less than the specified number of characters, the result is written right adjusted and space padded to the given size. An optional modifier can follow the optional flag and width specification. The modifiers, which are POSIX.2 extensions, are:
If the format supports the modifier but no alternate representation is available, it is ignored. The conversion specifier ends with a format specifier taken from the
following list. The whole
The size parameter can be used to specify the maximum number of
characters to be stored in the array s, including the terminating
null character. If the formatted time requires more than size
characters, Warning: This convention for the return value which is prescribed
in ISO C can lead to problems in some situations. For certain
format strings and certain locales the output really can be the empty
string and this cannot be discovered by testing the return value only.
E.g., in most locales the AM/PM time format is not supported (most of
the world uses the 24 hour time representation). In such locales
buf[0] = '\1';
len = strftime (buf, bufsize, format, tp);
if (len == 0 && buf[0] != '\0')
{
/* Something went wrong in the strftime call. */
...
}
If s is a null pointer, According to POSIX.1 every call to For an example of |
The ISO C standard does not specify any functions which can convert
the output of the strftime function back into a binary format.
This lead to variety of more or less successful implementations with
different interfaces over the years. Then the Unix standard got
extended by two functions: strptime and getdate. Both
have kind of strange interfaces but at least they are widely available.
The first function is a rather low-level interface. It is nevertheless
frequently used in user programs since it is better known. Its
implementation and the interface though is heavily influenced by the
getdate function which is defined and implemented in terms of
calls to strptime.
| char * strptime (const char *s, const char *fmt, struct tm *tp) | Function |
The strptime function parses the input string s according
to the format string fmt and stores the found values in the
structure tp.
The input string can be retrieved in any way. It does not matter
whether it was generated by a The format string consists of the same components as the format string
for the The modifiers The formats are:
All other characters in the format string must have a matching character in the input string. Exceptions are white spaces in the input string which can match zero or more white space characters in the input string. The The return value of the function is a pointer to the first character not
processed in this function call. In case the input string contains more
characters than required by the format string the return value points
right after the last consumed input character. In case the whole input
string is consumed the return value points to the NUL byte at the end of
the string. If |
The specification of the function in the XPG standard is rather vague. It leaves out a few important pieces of information. Most important it does not specify what happens to those elements of tm which are not directly initialized by the different formats. Various implementations on different Unix systems vary here.
The GNU libc implementation does not touch those fields which are not
directly initialized. Exceptions are the tm_wday and
tm_yday elements which are recomputed if any of the year, month,
or date elements changed. This has two implications:
strptime function for a new input string one
has to prepare the structure passed in as the tm. Normally this
will mean that all values are initialized to zero. Alternatively one
can use all fields to values like INT_MAX which allows to
determine which elements were set by the function call. Zero does not
work here since it is a valid value for many of the fields.
Careful initialization is necessary if one wants to find out whether a certain field in tm was initialized by the function call.
struct tm value in several strptime
calls in a row. A useful application of this is for example the parsing
of two separate strings, one containing the date information, the other
the time information. By parsing both one after the other without
clearing the structure in between one can construct a complete
broken-down time.
The following example shows a function which parses a string which is supposed to contain the date information in either US style or ISO 8601 form.
const char *
parse_date (const char *input, struct tm *tm)
{
const char *cp;
/* First clear the result structure. */
memset (tm, '\0', sizeof (*tm));
/* Try the ISO format first. */
cp = strptime (input, "%F", tm);
if (cp == NULL)
{
/* Does not match. Try the US form. */
cp = strptime (input, "%D", tm);
}
return cp;
}
The Unix standard defines another function to parse date strings. The interface is, mildly said, weird. But if this function fits into the application to be written it is just fine. It is a problem when using this function in multi-threaded programs or in libraries since it returns a pointer to a static variable, uses a global variable, and a global state (an environment variable).
| getdate_err | Variable |
This variable of type int will contain the error code of the last
unsuccessful call of the getdate function. Defined values are:
|
| struct tm * getdate (const char *string) | Function |
The interface of the getdate function is the simplest possible
for a function to parse a string and return the value. string is
the input string and the result is passed to the user in a statically
allocated variable.
The details about how the string is processed is hidden from the user.
In fact, it can be outside the control of the program. Which formats
are recognized is controlled by the file named by the environment
variable The Elements which were not initialized through the format string get
assigned the values of the time the The format elements recognized by
It should be noted that the format in the template file need not only contain format elements. The following is a list of possible format strings (taken from the Unix standard): %m %A %B %d, %Y %H:%M:%S %A %B %m/%d/%y %I %p %d,%m,%Y %H:%M at %A the %dst of %B in %Y run job at %I %p,%B %dnd %A den %d. %B %Y %H.%M Uhr As one can see the template list can contain very specific strings like
The return value of the function is a pointer to a static variable of
type The Warning: The |
| int getdate_r (const char *string, struct tm *tp) | Function |
The getdate_r function is the reentrant counterpart of
getdate. It does not use the global variable getdate_err
to signal the error but instead the return value now is this error code.
The same error codes as described in the getdate_err
documentation above are used.
This function is not defined in the Unix standard. Nevertheless it is available on some other Unix systems as well. As for |
TZIn POSIX systems, a user can specify the time zone by means of the
TZ environment variable. For information about how to set
environment variables, see Environment Variables. The functions
for accessing the time zone are declared in time.h.
You should not normally need to set TZ. If the system is
configured properly, the default time zone will be correct. You might
set TZ if you are using a computer over the network from a
different time zone, and would like times reported to you in the time zone
that local for you, rather than what is local for the computer.
In POSIX.1 systems the value of the TZ variable can be of one of
three formats. With the GNU C library, the most common format is the
last one, which can specify a selection from a large database of time
zone information for many regions of the world. The first two formats
are used to describe the time zone information directly, which is both
more cumbersome and less precise. But the POSIX.1 standard only
specifies the details of the first two formats, so it is good to be
familiar with them in case you come across a POSIX.1 system that doesn't
support a time zone information database.
The first format is used when there is no Daylight Saving Time (or summer time) in the local time zone:
std offset
The std string specifies the name of the time zone. It must be three or more characters long and must not contain a leading colon or embedded digits, commas, or plus or minus signs. There is no space character separating the time zone name from the offset, so these restrictions are necessary to parse the specification correctly.
The offset specifies the time value one must add to the local time
to get a Coordinated Universal Time value. It has syntax like
[+|-]hh[:mm[:ss]]. This
is positive if the local time zone is west of the Prime Meridian and
negative if it is east. The hour must be between 0 and
23, and the minute and seconds between 0 and 59.
For example, here is how we would specify Eastern Standard Time, but without any daylight saving time alternative:
EST+5
The second format is used when there is Daylight Saving Time:
std offset dst [offset],start[/time],end[/time]
The initial std and offset specify the standard time zone, as described above. The dst string and offset specify the name and offset for the corresponding daylight saving time zone; if the offset is omitted, it defaults to one hour ahead of standard time.
The remainder of the specification describes when daylight saving time is in effect. The start field is when daylight saving time goes into effect and the end field is when the change is made back to standard time. The following formats are recognized for these fields:
Jn
1 and 365.
February 29 is never counted, even in leap years.
n
0 and 365.
February 29 is counted in leap years.
Mm.w.d
0 (Sunday) and 6. The week
w must be between 1 and 5; week 1 is the
first week in which day d occurs, and week 5 specifies the
last d day in the month. The month m should be
between 1 and 12.
The time fields specify when, in the local time currently in
effect, the change to the other time occurs. If omitted, the default is
02:00:00.
For example, here is how one would specify the Eastern time zone in the United States, including the appropriate daylight saving time and its dates of applicability. The normal offset from UTC is 5 hours; since this is west of the prime meridian, the sign is positive. Summer time begins on the first Sunday in April at 2:00am, and ends on the last Sunday in October at 2:00am.
EST+5EDT,M4.1.0/2,M10.5.0/2
The schedule of daylight saving time in any particular jurisdiction has changed over the years. To be strictly correct, the conversion of dates and times in the past should be based on the schedule that was in effect then. However, this format has no facilities to let you specify how the schedule has changed from year to year. The most you can do is specify one particular schedule--usually the present day schedule--and this is used to convert any date, no matter when. For precise time zone specifications, it is best to use the time zone information database (see below).
The third format looks like this:
:characters
Each operating system interprets this format differently; in the GNU C library, characters is the name of a file which describes the time zone.
If the TZ environment variable does not have a value, the
operation chooses a time zone by default. In the GNU C library, the
default time zone is like the specification TZ=:/etc/localtime
(or TZ=:/usr/local/etc/localtime, depending on how GNU C library
was configured; see Installation). Other C libraries use their own
rule for choosing the default time zone, so there is little we can say
about them.
If characters begins with a slash, it is an absolute file name;
otherwise the library looks for the file
/share/lib/zoneinfo/characters. The zoneinfo
directory contains data files describing local time zones in many
different parts of the world. The names represent major cities, with
subdirectories for geographical areas; for example,
America/New_York, Europe/London, Asia/Hong_Kong.
These data files are installed by the system administrator, who also
sets /etc/localtime to point to the data file for the local time
zone. The GNU C library comes with a large database of time zone
information for most regions of the world, which is maintained by a
community of volunteers and put in the public domain.
| char * tzname [2] | Variable |
The array tzname contains two strings, which are the standard
names of the pair of time zones (standard and daylight
saving) that the user has selected. tzname[0] is the name of
the standard time zone (for example, "EST"), and tzname[1]
is the name for the time zone when daylight saving time is in use (for
example, "EDT"). These correspond to the std and dst
strings (respectively) from the TZ environment variable. If
daylight saving time is never used, tzname[1] is the empty string.
The The Though the strings are declared as |
| void tzset (void) | Function |
The tzset function initializes the tzname variable from
the value of the TZ environment variable. It is not usually
necessary for your program to call this function, because it is called
automatically when you use the other time conversion functions that
depend on the time zone.
|
The following variables are defined for compatibility with System V
Unix. Like tzname, these variables are set by calling
tzset or the other time conversion functions.
| long int timezone | Variable |
This contains the difference between UTC and the latest local standard
time, in seconds west of UTC. For example, in the U.S. Eastern time
zone, the value is 5*60*60. Unlike the tm_gmtoff member
of the broken-down time structure, this value is not adjusted for
daylight saving, and its sign is reversed. In GNU programs it is better
to use tm_gmtoff, since it contains the correct offset even when
it is not the latest one.
|
| int daylight | Variable |
| This variable has a nonzero value if daylight savings time rules apply. A nonzero value does not necessarily mean that daylight savings time is now in effect; it means only that daylight savings time is sometimes in effect. |
Here is an example program showing the use of some of the local time and calendar time functions.
#include <time.h>
#include <stdio.h>
#define SIZE 256
int
main (void)
{
char buffer[SIZE];
time_t curtime;
struct tm *loctime;
/* Get the current time. */
curtime = time (NULL);
/* Convert it to local time representation. */
loctime = localtime (&curtime);
/* Print out the date and time in the standard format. */
fputs (asctime (loctime), stdout);
/* Print it out in a nice format. */
strftime (buffer, SIZE, "Today is %A, %B %d.\n", loctime);
fputs (buffer, stdout);
strftime (buffer, SIZE, "The time is %I:%M %p.\n", loctime);
fputs (buffer, stdout);
return 0;
}
It produces output like this:
Wed Jul 31 13:02:36 1991 Today is Wednesday, July 31. The time is 01:02 PM.
The net_gettime and ntp_adjtime functions provide an
interface to monitor and manipulate high precision time. These
functions are declared in sys/timex.h.
| struct ntptimeval | Data Type |
This structure is used to monitor kernel time. It contains the
following members:
|
| int ntp_gettime (struct ntptimeval *tptr) | Function |
The ntp_gettime function sets the structure pointed to by
tptr to current values. The elements of the structure afterwards
contain the values the timer implementation in the kernel assumes. They
might or might not be correct. If they are not a ntp_adjtime
call is necessary.
The return value is
|
| struct timex | Data Type |
This structure is used to control and monitor kernel time in a greater
level of detail. It contains the following members:
|
| int ntp_adjtime (struct timex *tptr) | Function |
The ntp_adjtime function sets the structure specified by
tptr to current values. In addition, values passed in tptr
can be used to replace existing settings. To do this the modes
element of the struct timex must be set appropriately. Setting
it to zero selects reading the current state.
The return value is
For more details see RFC1305 (Network Time Protocol, Version 3) and related documents. |
The alarm and setitimer functions provide a mechanism for a
process to interrupt itself at some future time. They do this by setting a
timer; when the timer expires, the process receives a signal.
Each process has three independent interval timers available:
SIGALRM signal to the process when it expires.
SIGVTALRM signal to the process when it expires.
SIGPROF signal to the process when it expires.
This timer is useful for profiling in interpreters. The interval timer mechanism does not have the fine granularity necessary for profiling native code.
You can only have one timer of each kind set at any given time. If you set a timer that has not yet expired, that timer is simply reset to the new value.
You should establish a handler for the appropriate alarm signal using
signal or sigaction before issuing a call to setitimer
or alarm. Otherwise, an unusual chain of events could cause the
timer to expire before your program establishes the handler, and in that
case it would be terminated, since that is the default action for the alarm
signals. See Signal Handling.
The setitimer function is the primary means for setting an alarm.
This facility is declared in the header file sys/time.h. The
alarm function, declared in unistd.h, provides a somewhat
simpler interface for setting the real-time timer.
| struct itimerval | Data Type |
This structure is used to specify when a timer should expire. It contains
the following members:
The |
| int setitimer (int which, struct itimerval *new, struct itimerval *old) | Function |
The setitimer function sets the timer specified by which
according to new. The which argument can have a value of
ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF.
If old is not a null pointer, The return value is
|
| int getitimer (int which, struct itimerval *old) | Function |
The getitimer function stores information about the timer specified
by which in the structure pointed at by old.
The return value and error conditions are the same as for |
ITIMER_REAL
setitimer and getitimer functions to specify the real-time
timer.
ITIMER_VIRTUAL
setitimer and getitimer functions to specify the virtual
timer.
ITIMER_PROF
setitimer and getitimer functions to specify the profiling
timer.
| unsigned int alarm (unsigned int seconds) | Function |
The alarm function sets the real-time timer to expire in
seconds seconds. If you want to cancel any existing alarm, you
can do this by calling alarm with a seconds argument of
zero.
The return value indicates how many seconds remain before the previous
alarm would have been sent. If there is no previous alarm, |
The alarm function could be defined in terms of setitimer
like this:
unsigned int
alarm (unsigned int seconds)
{
struct itimerval old, new;
new.it_interval.tv_usec = 0;
new.it_interval.tv_sec = 0;
new.it_value.tv_usec = 0;
new.it_value.tv_sec = (long int) seconds;
if (setitimer (ITIMER_REAL, &new, &old) < 0)
return 0;
else
return old.it_value.tv_sec;
}
There is an example showing the use of the alarm function in
Handler Returns.
If you simply want your process to wait for a given number of seconds,
you should use the sleep function. See Sleeping.
You shouldn't count on the signal arriving precisely when the timer expires. In a multiprocessing environment there is typically some amount of delay involved.
Portability Note: The setitimer and getitimer
functions are derived from BSD Unix, while the alarm function is
specified by the POSIX.1 standard. setitimer is more powerful than
alarm, but alarm is more widely used.
The function sleep gives a simple way to make the program wait
for short periods of time. If your program doesn't use signals (except
to terminate), then you can expect sleep to wait reliably for
the specified amount of time. Otherwise, sleep can return sooner
if a signal arrives; if you want to wait for a given period regardless
of signals, use select (see Waiting for I/O) and don't
specify any descriptors to wait for.
| unsigned int sleep (unsigned int seconds) | Function |
The sleep function waits for seconds or until a signal
is delivered, whichever happens first.
If The |
Resist the temptation to implement a sleep for a fixed amount of time by
using the return value of sleep, when nonzero, to call
sleep again. This will work with a certain amount of accuracy as
long as signals arrive infrequently. But each signal can cause the
eventual wakeup time to be off by an additional second or so. Suppose a
few signals happen to arrive in rapid succession by bad luck--there is
no limit on how much this could shorten or lengthen the wait.
Instead, compute the time at which the program should stop waiting, and
keep trying to wait until that time. This won't be off by more than a
second. With just a little more work, you can use select and
make the waiting period quite accurate. (Of course, heavy system load
can cause unavoidable additional delays--unless the machine is
dedicated to one application, there is no way you can avoid this.)
On some systems, sleep can do strange things if your program uses
SIGALRM explicitly. Even if SIGALRM signals are being
ignored or blocked when sleep is called, sleep might
return prematurely on delivery of a SIGALRM signal. If you have
established a handler for SIGALRM signals and a SIGALRM
signal is delivered while the process is sleeping, the action taken
might be just to cause sleep to return instead of invoking your
handler. And, if sleep is interrupted by delivery of a signal
whose handler requests an alarm or alters the handling of SIGALRM,
this handler and sleep will interfere.
On the GNU system, it is safe to use sleep and SIGALRM in
the same program, because sleep does not work by means of
SIGALRM.
| int nanosleep (const struct timespec *requested_time, struct timespec *remaining) | Function |
If the resolution of seconds is not enough the nanosleep function
can be used. As the name suggests the sleeping period can be specified
in nanoseconds. The actual period of waiting time might be longer since
the requested time in the requested_time parameter is rounded up
to the next integer multiple of the actual resolution of the system.
If the function returns because the time has elapsed the return value is zero. If the function return -1 the global variable errno is set to the following values:
This function is a cancelation point in multi-threaded programs. This
is a problem if the thread allocates some resources (like memory, file
descriptors, semaphores or whatever) at the time The |
The function getrusage and the data type struct rusage
are used for examining the usage figures of a process. They are declared
in sys/resource.h.
| int getrusage (int processes, struct rusage *rusage) | Function |
This function reports the usage totals for processes specified by
processes, storing the information in *rusage.
In most systems, processes has only two valid values:
In the GNU system, you can also inquire about a particular child process by specifying its process ID. The return value of
|
One way of getting usage figures for a particular child process is with
the function wait4, which returns totals for a child when it
terminates. See BSD Wait Functions.
| struct rusage | Data Type |
This data type records a collection usage amounts for various sorts of
resources. It has the following members, and possibly others:
|
An additional historical function for examining usage figures,
vtimes, is supported but not documented here. It is declared in
sys/vtimes.h.
You can specify limits for the resource usage of a process. When the process tries to exceed a limit, it may get a signal, or the system call by which it tried to do so may fail, depending on the limit. Each process initially inherits its limit values from its parent, but it can subsequently change them.
The symbols in this section are defined in sys/resource.h.
| int getrlimit (int resource, struct rlimit *rlp) | Function |
Read the current value and the maximum value of resource resource
and store them in *rlp.
The return value is When the sources are compiled with |
| int getrlimit64 (int resource, struct rlimit64 *rlp) | Function |
This function is similar to the getrlimit but its second
parameter is a pointer to a variable of type struct rlimit64
which allows this function to read values which wouldn't fit in the
member of a struct rlimit.
If the sources are compiled with |
| int setrlimit (int resource, const struct rlimit *rlp) | Function |
Store the current value and the maximum value of resource resource
in *rlp.
The return value is
When the sources are compiled with |
| int setrlimit64 (int resource, const struct rlimit64 *rlp) | Function |
This function is similar to the setrlimit but its second
parameter is a pointer to a variable of type struct rlimit64
which allows this function to set values which wouldn't fit in the
member of a struct rlimit.
If the sources are compiled with |
| struct rlimit | Data Type |
This structure is used with getrlimit to receive limit values,
and with setrlimit to specify limit values. It has two fields:
In |
For the LFS functions a similar type is defined in sys/resource.h.
| struct rlimit64 | Data Type |
This structure is used with getrlimit64 to receive limit values,
and with setrlimit64 to specify limit values. It has two fields:
In |
Here is a list of resources that you can specify a limit for. Those that are sizes are measured in bytes.
RLIMIT_CPU
SIGXCPU. The value is
measured in seconds. See Operation Error Signals.
RLIMIT_FSIZE
SIGXFSZ. See Operation Error Signals.
RLIMIT_DATA
RLIMIT_STACK
SIGSEGV signal.
See Program Error Signals.
RLIMIT_CORE
RLIMIT_RSS
RLIMIT_MEMLOCK
RLIMIT_NPROC
fork will fail
with EAGAIN. See Creating a Process.
RLIMIT_NOFILE
RLIMIT_OFILE
EMFILE.
See Error Codes. Not all systems support this limit; GNU does, and
4.4 BSD does.
RLIM_NLIMITS
RLIM_NLIMITS.
| int RLIM_INFINITY | Constant |
This constant stands for a value of "infinity" when supplied as
the limit value in setrlimit.
|
Two historical functions for setting resource limits, ulimit and
vlimit, are not documented here. The latter is declared in
sys/vlimit.h and comes from BSD.
When several processes try to run, their respective priorities determine
what share of the CPU each process gets. This section describes how you
can read and set the priority of a process. All these functions and
macros are declared in sys/resource.h.
The range of valid priority values depends on the operating system, but
typically it runs from -20 to 20. A lower priority value
means the process runs more often. These constants describe the range of
priority values:
PRIO_MIN
PRIO_MAX
| int getpriority (int class, int id) | Function |
|
Read the priority of a class of processes; class and id
specify which ones (see below). If the processes specified do not all
have the same priority, this returns the smallest value that any of them
has.
The return value is the priority value on success, and
When the return value is |
| int setpriority (int class, int id, int priority) | Function |
|
Set the priority of a class of processes to priority; class
and id specify which ones (see below).
The return value is
|
The arguments class and id together specify a set of processes you are interested in. These are the possible values for class:
PRIO_PROCESS
PRIO_PGRP
PRIO_USER
If the argument id is 0, it stands for the current process, current process group, or the current user, according to class.
| int nice (int increment) | Function |
Increment the priority of the current process by increment.
The return value is the same as for setpriority.
Here is an equivalent definition for int
nice (int increment)
{
int old = getpriority (PRIO_PROCESS, 0);
return setpriority (PRIO_PROCESS, 0, old + increment);
}
|
Sometimes when your program detects an unusual situation inside a deeply
nested set of function calls, you would like to be able to immediately
return to an outer level of control. This section describes how you can
do such non-local exits using the setjmp and longjmp
functions.
As an example of a situation where a non-local exit can be useful, suppose you have an interactive program that has a "main loop" that prompts for and executes commands. Suppose the "read" command reads input from a file, doing some lexical analysis and parsing of the input while processing it. If a low-level input error is detected, it would be useful to be able to return immediately to the "main loop" instead of having to make each of the lexical analysis, parsing, and processing phases all have to explicitly deal with error situations initially detected by nested calls.
(On the other hand, if each of these phases has to do a substantial amount of cleanup when it exits--such as closing files, deallocating buffers or other data structures, and the like--then it can be more appropriate to do a normal return and have each phase do its own cleanup, because a non-local exit would bypass the intervening phases and their associated cleanup code entirely. Alternatively, you could use a non-local exit but do the cleanup explicitly either before or after returning to the "main loop".)
In some ways, a non-local exit is similar to using the return
statement to return from a function. But while return abandons
only a single function call, transferring control back to the point at
which it was called, a non-local exit can potentially abandon many
levels of nested function calls.
You identify return points for non-local exits calling the function
setjmp. This function saves information about the execution
environment in which the call to setjmp appears in an object of
type jmp_buf. Execution of the program continues normally after
the call to setjmp, but if a exit is later made to this return
point by calling longjmp with the corresponding jmp_buf
object, control is transferred back to the point where setjmp was
called. The return value from setjmp is used to distinguish
between an ordinary return and a return made by a call to
longjmp, so calls to setjmp usually appear in an if
statement.
Here is how the example program described above might be set up:
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
jmp_buf main_loop;
void
abort_to_main_loop (int status)
{
longjmp (main_loop, status);
}
int
main (void)
{
while (1)
if (setjmp (main_loop))
puts ("Back at main loop....");
else
do_command ();
}
void
do_command (void)
{
char buffer[128];
if (fgets (buffer, 128, stdin) == NULL)
abort_to_main_loop (-1);
else
exit (EXIT_SUCCESS);
}
The function abort_to_main_loop causes an immediate transfer of
control back to the main loop of the program, no matter where it is
called from.
The flow of control inside the main function may appear a little
mysterious at first, but it is actually a common idiom with
setjmp. A normal call to setjmp returns zero, so the
"else" clause of the conditional is executed. If
abort_to_main_loop is called somewhere within the execution of
do_command, then it actually appears as if the same call
to setjmp in main were returning a second time with a value
of -1.
So, the general pattern for using setjmp looks something like:
if (setjmp (buffer)) /* Code to clean up after premature return. */ ... else /* Code to be executed normally after setting up the return point. */ ...
Here are the details on the functions and data structures used for
performing non-local exits. These facilities are declared in
setjmp.h.
| jmp_buf | Data Type |
Objects of type jmp_buf hold the state information to
be restored by a non-local exit. The contents of a jmp_buf
identify a specific place to return to.
|
| int setjmp (jmp_buf state) | Macro |
When called normally, setjmp stores information about the
execution state of the program in state and returns zero. If
longjmp is later used to perform a non-local exit to this
state, setjmp returns a nonzero value.
|
| void longjmp (jmp_buf state, int value) | Function |
This function restores current execution to the state saved in
state, and continues execution from the call to setjmp that
established that return point. Returning from setjmp by means of
longjmp returns the value argument that was passed to
longjmp, rather than 0. (But if value is given as
0, setjmp returns 1).
|
There are a lot of obscure but important restrictions on the use of
setjmp and longjmp. Most of these restrictions are
present because non-local exits require a fair amount of magic on the
part of the C compiler and can interact with other parts of the language
in strange ways.
The setjmp function is actually a macro without an actual
function definition, so you shouldn't try to #undef it or take
its address. In addition, calls to setjmp are safe in only the
following contexts:
if, switch, or while).
! operator, that appears as the
test expression of a selection or iteration statement.
Return points are valid only during the dynamic extent of the function
that called setjmp to establish them. If you longjmp to
a return point that was established in a function that has already
returned, unpredictable and disastrous things are likely to happen.
You should use a nonzero value argument to longjmp. While
longjmp refuses to pass back a zero argument as the return value
from setjmp, this is intended as a safety net against accidental
misuse and is not really good programming style.
When you perform a non-local exit, accessible objects generally retain
whatever values they had at the time longjmp was called. The
exception is that the values of automatic variables local to the
function containing the setjmp call that have been changed since
the call to setjmp are indeterminate, unless you have declared
them volatile.
In BSD Unix systems, setjmp and longjmp also save and
restore the set of blocked signals; see Blocking Signals. However,
the POSIX.1 standard requires setjmp and longjmp not to
change the set of blocked signals, and provides an additional pair of
functions (sigsetjmp and siglongjmp) to get the BSD
behavior.
The behavior of setjmp and longjmp in the GNU library is
controlled by feature test macros; see Feature Test Macros. The
default in the GNU system is the POSIX.1 behavior rather than the BSD
behavior.
The facilities in this section are declared in the header file
setjmp.h.
| sigjmp_buf | Data Type |
This is similar to jmp_buf, except that it can also store state
information about the set of blocked signals.
|
| int sigsetjmp (sigjmp_buf state, int savesigs) | Function |
This is similar to setjmp. If savesigs is nonzero, the set
of blocked signals is saved in state and will be restored if a
siglongjmp is later performed with this state.
|
| void siglongjmp (sigjmp_buf state, int value) | Function |
This is similar to longjmp except for the type of its state
argument. If the sigsetjmp call that set this state used a
nonzero savesigs flag, siglongjmp also restores the set of
blocked signals.
|
A signal is a software interrupt delivered to a process. The operating system uses signals to report exceptional situations to an executing program. Some signals report errors such as references to invalid memory addresses; others report asynchronous events, such as disconnection of a phone line.
The GNU C library defines a variety of signal types, each for a particular kind of event. Some kinds of events make it inadvisable or impossible for the program to proceed as usual, and the corresponding signals normally abort the program. Other kinds of signals that report harmless events are ignored by default.
If you anticipate an event that causes signals, you can define a handler function and tell the operating system to run it when that particular type of signal arrives.
Finally, one process can send a signal to another process; this allows a parent process to abort a child, or two related processes to communicate and synchronize.
open,
read, write and other functions.
This section explains basic concepts of how signals are generated, what happens after a signal is delivered, and how programs can handle signals.
A signal reports the occurrence of an exceptional event. These are some of the events that can cause (or generate, or raise) a signal:
kill or raise by the same process.
kill from another process. Signals are a limited but
useful form of interprocess communication.
Each of these kinds of events (excepting explicit calls to kill
and raise) generates its own particular kind of signal. The
various kinds of signals are listed and described in detail in
Standard Signals.
In general, the events that generate signals fall into three major categories: errors, external events, and explicit requests.
An error means that a program has done something invalid and cannot
continue execution. But not all kinds of errors generate signals--in
fact, most do not. For example, opening a nonexistent file is an error,
but it does not raise a signal; instead, open returns -1.
In general, errors that are necessarily associated with certain library
functions are reported by returning a value that indicates an error.
The errors which raise signals are those which can happen anywhere in
the program, not just in library calls. These include division by zero
and invalid memory addresses.
An external event generally has to do with I/O or other processes. These include the arrival of input, the expiration of a timer, and the termination of a child process.
An explicit request means the use of a library function such as
kill whose purpose is specifically to generate a signal.
Signals may be generated synchronously or asynchronously. A synchronous signal pertains to a specific action in the program, and is delivered (unless blocked) during that action. Most errors generate signals synchronously, and so do explicit requests by a process to generate a signal for that same process. On some machines, certain kinds of hardware errors (usually floating-point exceptions) are not reported completely synchronously, but may arrive a few instructions later.
Asynchronous signals are generated by events outside the control of the process that receives them. These signals arrive at unpredictable times during execution. External events generate signals asynchronously, and so do explicit requests that apply to some other process.
A given type of signal is either typically synchronous or typically asynchronous. For example, signals for errors are typically synchronous because errors generate signals synchronously. But any type of signal can be generated synchronously or asynchronously with an explicit request.
When a signal is generated, it becomes pending. Normally it remains pending for just a short period of time and then is delivered to the process that was signaled. However, if that kind of signal is currently blocked, it may remain pending indefinitely--until signals of that kind are unblocked. Once unblocked, it will be delivered immediately. See Blocking Signals.
When the signal is delivered, whether right away or after a long delay,
the specified action for that signal is taken. For certain
signals, such as SIGKILL and SIGSTOP, the action is fixed,
but for most signals, the program has a choice: ignore the signal,
specify a handler function, or accept the default action for
that kind of signal. The program specifies its choice using functions
such as signal or sigaction (see Signal Actions). We
sometimes say that a handler catches the signal. While the
handler is running, that particular signal is normally blocked.
If the specified action for a kind of signal is to ignore it, then any such signal which is generated is discarded immediately. This happens even if the signal is also blocked at the time. A signal discarded in this way will never be delivered, not even if the program subsequently specifies a different action for that kind of signal and then unblocks it.
If a signal arrives which the program has neither handled nor ignored, its default action takes place. Each kind of signal has its own default action, documented below (see Standard Signals). For most kinds of signals, the default action is to terminate the process. For certain kinds of signals that represent "harmless" events, the default action is to do nothing.
When a signal terminates a process, its parent process can determine the
cause of termination by examining the termination status code reported
by the wait or waitpid functions. (This is discussed in
more detail in Process Completion.) The information it can get
includes the fact that termination was due to a signal, and the kind of
signal involved. If a program you run from a shell is terminated by a
signal, the shell typically prints some kind of error message.
The signals that normally represent program errors have a special property: when one of these signals terminates the process, it also writes a core dump file which records the state of the process at the time of termination. You can examine the core dump with a debugger to investigate what caused the error.
If you raise a "program error" signal by explicit request, and this terminates the process, it makes a core dump file just as if the signal had been due directly to an error.
This section lists the names for various standard kinds of signals and describes what kind of event they mean. Each signal name is a macro which stands for a positive integer--the signal number for that kind of signal. Your programs should never make assumptions about the numeric code for a particular kind of signal, but rather refer to them always by the names defined here. This is because the number for a given kind of signal can vary from system to system, but the meanings of the names are standardized and fairly uniform.
The signal names are defined in the header file signal.h.
| int NSIG | Macro |
The value of this symbolic constant is the total number of signals
defined. Since the signal numbers are allocated consecutively,
NSIG is also one greater than the largest defined signal number.
|
The following signals are generated when a serious program error is detected by the operating system or the computer itself. In general, all of these signals are indications that your program is seriously broken in some way, and there's usually no way to continue the computation which encountered the error.
Some programs handle program error signals in order to tidy up before terminating; for example, programs that turn off echoing of terminal input should handle program error signals in order to turn echoing back on. The handler should end by specifying the default action for the signal that happened and then reraising it; this will cause the program to terminate with that signal, as if it had not had a handler. (See Termination in Handler.)
Termination is the sensible ultimate outcome from a program error in
most programs. However, programming systems such as Lisp that can load
compiled user programs might need to keep executing even if a user
program incurs an error. These programs have handlers which use
longjmp to return control to the command level.
The default action for all of these signals is to cause the process to
terminate. If you block or ignore these signals or establish handlers
for them that return normally, your program will probably break horribly
when such signals happen, unless they are generated by raise or
kill instead of a real error.
When one of these program error signals terminates a process, it also
writes a core dump file which records the state of the process at
the time of termination. The core dump file is named core and is
written in whichever directory is current in the process at the time.
(On the GNU system, you can specify the file name for core dumps with
the environment variable COREFILE.) The purpose of core dump
files is so that you can examine them with a debugger to investigate
what caused the error.
| int SIGFPE | Macro |
The SIGFPE signal reports a fatal arithmetic error. Although the
name is derived from "floating-point exception", this signal actually
covers all arithmetic errors, including division by zero and overflow.
If a program stores integer data in a location which is then used in a
floating-point operation, this often causes an "invalid operation"
exception, because the processor cannot recognize the data as a
floating-point number.
Actual floating-point exceptions are a complicated subject because there
are many types of exceptions with subtly different meanings, and the
|
BSD systems provide the SIGFPE handler with an extra argument
that distinguishes various causes of the exception. In order to access
this argument, you must define the handler to accept two arguments,
which means you must cast it to a one-argument function type in order to
establish the handler. The GNU library does provide this extra
argument, but the value is meaningful only on operating systems that
provide the information (BSD systems and GNU systems).
FPE_INTOVF_TRAP
FPE_INTDIV_TRAP
FPE_SUBRNG_TRAP
FPE_FLTOVF_TRAP
FPE_FLTDIV_TRAP
FPE_FLTUND_TRAP
FPE_DECOVF_TRAP
| int SIGILL | Macro |
The name of this signal is derived from "illegal instruction"; it
usually means your program is trying to execute garbage or a privileged
instruction. Since the C compiler generates only valid instructions,
SIGILL typically indicates that the executable file is corrupted,
or that you are trying to execute data. Some common ways of getting
into the latter situation are by passing an invalid object where a
pointer to a function was expected, or by writing past the end of an
automatic array (or similar problems with pointers to automatic
variables) and corrupting other data on the stack such as the return
address of a stack frame.
|
| int SIGSEGV | Macro |
|
This signal is generated when a program tries to read or write outside
the memory that is allocated for it, or to write memory that can only be
read. (Actually, the signals only occur when the program goes far
enough outside to be detected by the system's memory protection
mechanism.) The name is an abbreviation for "segmentation violation".
Common ways of getting a |
| int SIGBUS | Macro |
This signal is generated when an invalid pointer is dereferenced. Like
SIGSEGV, this signal is typically the result of dereferencing an
uninitialized pointer. The difference between the two is that
SIGSEGV indicates an invalid access to valid memory, while
SIGBUS indicates an access to an invalid address. In particular,
SIGBUS signals often result from dereferencing a misaligned
pointer, such as referring to a four-word integer at an address not
divisible by four. (Each kind of computer has its own requirements for
address alignment.)
The name of this signal is an abbreviation for "bus error". |
| int SIGABRT | Macro |
This signal indicates an error detected by the program itself and
reported by calling abort. See Aborting a Program.
|
| int SIGIOT | Macro |
Generated by the PDP-11 "iot" instruction. On most machines, this is
just another name for SIGABRT.
|
| int SIGTRAP | Macro |
Generated by the machine's breakpoint instruction, and possibly other
trap instructions. This signal is used by debuggers. Your program will
probably only see SIGTRAP if it is somehow executing bad
instructions.
|
| int SIGEMT | Macro |
| Emulator trap; this results from certain unimplemented instructions which might be emulated in software, or the operating system's failure to properly emulate them. |
| int SIGSYS | Macro |
| Bad system call; that is to say, the instruction to trap to the operating system was executed, but the code number for the system call to perform was invalid. |
These signals are all used to tell a process to terminate, in one way or another. They have different names because they're used for slightly different purposes, and programs might want to handle them differently.
The reason for handling these signals is usually so your program can tidy up as appropriate before actually terminating. For example, you might want to save state information, delete temporary files, or restore the previous terminal modes. Such a handler should end by specifying the default action for the signal that happened and then reraising it; this will cause the program to terminate with that signal, as if it had not had a handler. (See Termination in Handler.)
The (obvious) default action for all of these signals is to cause the process to terminate.
| int SIGTERM | Macro |
The SIGTERM signal is a generic signal used to cause program
termination. Unlike SIGKILL, this signal can be blocked,
handled, and ignored. It is the normal way to politely ask a program to
terminate.
The shell command |
| int SIGINT | Macro |
The SIGINT ("program interrupt") signal is sent when the user
types the INTR character (normally C-c). See Special Characters, for information about terminal driver support for
C-c.
|
| int SIGQUIT | Macro |
The SIGQUIT signal is similar to SIGINT, except that it's
controlled by a different key--the QUIT character, usually
C-\--and produces a core dump when it terminates the process,
just like a program error signal. You can think of this as a
program error condition "detected" by the user.
See Program Error Signals, for information about core dumps. See Special Characters, for information about terminal driver support. Certain kinds of cleanups are best omitted in handling |
| int SIGKILL | Macro |
The SIGKILL signal is used to cause immediate program termination.
It cannot be handled or ignored, and is therefore always fatal. It is
also not possible to block this signal.
This signal is usually generated only by explicit request. Since it
cannot be handled, you should generate it only as a last resort, after
first trying a less drastic method such as C-c or In fact, if The system will generate |
| int SIGHUP | Macro |
The SIGHUP ("hang-up") signal is used to report that the user's
terminal is disconnected, perhaps because a network or telephone
connection was broken. For more information about this, see Control Modes.
This signal is also used to report the termination of the controlling process on a terminal to jobs associated with that session; this termination effectively disconnects all processes in the session from the controlling terminal. For more information, see Termination Internals. |
These signals are used to indicate the expiration of timers. See Setting an Alarm, for information about functions that cause these signals to be sent.
The default behavior for these signals is to cause program termination. This default is rarely useful, but no other default would be useful; most of the ways of using these signals would require handler functions in any case.
| int SIGALRM | Macro |
This signal typically indicates expiration of a timer that measures real
or clock time. It is used by the alarm function, for example.
|
| int SIGVTALRM | Macro |
| This signal typically indicates expiration of a timer that measures CPU time used by the current process. The name is an abbreviation for "virtual time alarm". |
| int SIGPROF | Macro |
| This signal is typically indicates expiration of a timer that measures both CPU time used by the current process, and CPU time expended on behalf of the process by the system. Such a timer is used to implement code profiling facilities, hence the name of this signal. |
The signals listed in this section are used in conjunction with
asynchronous I/O facilities. You have to take explicit action by
calling fcntl to enable a particular file descriptor to generate
these signals (see Interrupt Input). The default action for these
signals is to ignore them.
| int SIGIO | Macro |
|
This signal is sent when a file descriptor is ready to perform input
or output.
On most operating systems, terminals and sockets are the only kinds of
files that can generate In the GNU system |
| int SIGURG | Macro |
| This signal is sent when "urgent" or out-of-band data arrives on a socket. See Out-of-Band Data. |
| int SIGPOLL | Macro |
This is a System V signal name, more or less similar to SIGIO.
It is defined only for compatibility.
|
These signals are used to support job control. If your system doesn't support job control, then these macros are defined but the signals themselves can't be raised or handled.
You should generally leave these signals alone unless you really understand how job control works. See Job Control.
| int SIGCHLD | Macro |
|
This signal is sent to a parent process whenever one of its child
processes terminates or stops.
The default action for this signal is to ignore it. If you establish a
handler for this signal while there are child processes that have
terminated but not reported their status via |
| int SIGCLD | Macro |
This is an obsolete name for SIGCHLD.
|
| int SIGCONT | Macro |
You can send a SIGCONT signal to a process to make it continue.
This signal is special--it always makes the process continue if it is
stopped, before the signal is delivered. The default behavior is to do
nothing else. You cannot block this signal. You can set a handler, but
SIGCONT always makes the process continue regardless.
Most programs have no reason to handle |
| int SIGSTOP | Macro |
The SIGSTOP signal stops the process. It cannot be handled,
ignored, or blocked.
|
| int SIGTSTP | Macro |
The SIGTSTP signal is an interactive stop signal. Unlike
SIGSTOP, this signal can be handled and ignored.
Your program should handle this signal if you have a special need to
leave files or system tables in a secure state when a process is
stopped. For example, programs that turn off echoing should handle
This signal is generated when the user types the SUSP character (normally C-z). For more information about terminal driver support, see Special Characters. |
| int SIGTTIN | Macro |
A process cannot read from the user's terminal while it is running
as a background job. When any process in a background job tries to
read from the terminal, all of the processes in the job are sent a
SIGTTIN signal. The default action for this signal is to
stop the process. For more information about how this interacts with
the terminal driver, see Access to the Terminal.
|
| int SIGTTOU | Macro |
This is similar to SIGTTIN, but is generated when a process in a
background job attempts to write to the terminal or set its modes.
Again, the default action is to stop the process. SIGTTOU is
only generated for an attempt to write to the terminal if the
TOSTOP output mode is set; see Output Modes.
|
While a process is stopped, no more signals can be delivered to it until
it is continued, except SIGKILL signals and (obviously)
SIGCONT signals. The signals are marked as pending, but not
delivered until the process is continued. The SIGKILL signal
always causes termination of the process and can't be blocked, handled
or ignored. You can ignore SIGCONT, but it always causes the
process to be continued anyway if it is stopped. Sending a
SIGCONT signal to a process causes any pending stop signals for
that process to be discarded. Likewise, any pending SIGCONT
signals for a process are discarded when it receives a stop signal.
When a process in an orphaned process group (see Orphaned Process Groups) receives a SIGTSTP, SIGTTIN, or SIGTTOU
signal and does not handle it, the process does not stop. Stopping the
process would probably not be very useful, since there is no shell
program that will notice it stop and allow the user to continue it.
What happens instead depends on the operating system you are using.
Some systems may do nothing; others may deliver another signal instead,
such as SIGKILL or SIGHUP. In the GNU system, the process
dies with SIGKILL; this avoids the problem of many stopped,
orphaned processes lying around the system.
These signals are used to report various errors generated by an operation done by the program. They do not necessarily indicate a programming error in the program, but an error that prevents an operating system call from completing. The default action for all of them is to cause the process to terminate.
| int SIGPIPE | Macro |
Broken pipe. If you use pipes or FIFOs, you have to design your
application so that one process opens the pipe for reading before
another starts writing. If the reading process never starts, or
terminates unexpectedly, writing to the pipe or FIFO raises a
SIGPIPE signal. If SIGPIPE is blocked, handled or
ignored, the offending call fails with EPIPE instead.
Pipes and FIFO special files are discussed in more detail in Pipes and FIFOs. Another cause of |
| int SIGLOST | Macro |
|
Resource lost. This signal is generated when you have an advisory lock
on an NFS file, and the NFS server reboots and forgets about your lock.
In the GNU system, |
| int SIGXCPU | Macro |
| CPU time limit exceeded. This signal is generated when the process exceeds its soft resource limit on CPU time. See Limits on Resources. |
| int SIGXFSZ | Macro |
| File size limit exceeded. This signal is generated when the process attempts to extend a file so it exceeds the process's soft resource limit on file size. See Limits on Resources. |
These signals are used for various other purposes. In general, they will not affect your program unless it explicitly uses them for something.
| int SIGUSR1 | Macro |
| int SIGUSR2 | Macro |
The SIGUSR1 and SIGUSR2 signals are set aside for you to
use any way you want. They're useful for simple interprocess
communication, if you write a signal handler for them in the program
that receives the signal.
There is an example showing the use of The default action is to terminate the process. |
| int SIGWINCH | Macro |
|
Window size change. This is generated on some systems (including GNU)
when the terminal driver's record of the number of rows and columns on
the screen is changed. The default action is to ignore it.
If a program does full-screen display, it should handle |
| int SIGINFO | Macro |
|
Information request. In 4.4 BSD and the GNU system, this signal is sent
to all the processes in the foreground process group of the controlling
terminal when the user types the STATUS character in canonical mode;
see Signal Characters.
If the process is the leader of the process group, the default action is to print some status information about the system and what the process is doing. Otherwise the default is to do nothing. |
We mentioned above that the shell prints a message describing the signal
that terminated a child process. The clean way to print a message
describing a signal is to use the functions strsignal and
psignal. These functions use a signal number to specify which
kind of signal to describe. The signal number may come from the
termination status of a child process (see Process Completion) or it
may come from a signal handler in the same process.
| char * strsignal (int signum) | Function |
|
This function returns a pointer to a statically-allocated string
containing a message describing the signal signum. You
should not modify the contents of this string; and, since it can be
rewritten on subsequent calls, you should save a copy of it if you need
to reference it later.
This function is a GNU extension, declared in the header file
|
| void psignal (int signum, const char *message) | Function |
This function prints a message describing the signal signum to the
standard error output stream stderr; see Standard Streams.
If you call If you supply a non-null message argument, then This function is a BSD feature, declared in the header file |
There is also an array sys_siglist which contains the messages
for the various signal codes. This array exists on BSD systems, unlike
strsignal.
The simplest way to change the action for a signal is to use the
signal function. You can specify a built-in action (such as to
ignore the signal), or you can establish a handler.
The GNU library also implements the more versatile sigaction
facility. This section describes both facilities and gives suggestions
on which to use when.
signal function.
sigaction function.
The signal function provides a simple interface for establishing
an action for a particular signal. The function and associated macros
are declared in the header file signal.h.
| sighandler_t | Data Type |
This is the type of signal handler functions. Signal handlers take one
integer argument specifying the signal number, and have return type
void. So, you should define handler functions like this:
void handler (int
The name |
| sighandler_t signal (int signum, sighandler_t action) | Function |
The signal function establishes action as the action for
the signal signum.
The first argument, signum, identifies the signal whose behavior you want to control, and should be a signal number. The proper way to specify a signal number is with one of the symbolic signal names (see Standard Signals)--don't use an explicit number, because the numerical code for a given kind of signal may vary from operating system to operating system. The second argument, action, specifies the action to use for the signal signum. This can be one of the following:
If you set the action for a signal to The If
|
Compatibility Note: A problem when working with the
signal function is that it has a different semantic on BSD and
SVID system. The difference is that on SVID systems the signal handler
is deinstalled after an signal was delivered. On BSD systems the
handler must be explicitly deinstalled. In the GNU C Library we use the
BSD version by default. To use the SVID version you can either use the
function sysv_signal (see below) or use the _XOPEN_SOURCE
feature select macro (see Feature Test Macros). Generally it should
be avoided to use this functions due to the compatibility problems. It
is better to use sigaction if it is available since the results
are much more reliable.
Here is a simple example of setting up a handler to delete temporary files when certain fatal signals happen:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
if (signal (SIGINT, termination_handler) == SIG_IGN)
signal (SIGINT, SIG_IGN);
if (signal (SIGHUP, termination_handler) == SIG_IGN)
signal (SIGHUP, SIG_IGN);
if (signal (SIGTERM, termination_handler) == SIG_IGN)
signal (SIGTERM, SIG_IGN);
...
}
Note how if a given signal was previously set to be ignored, this code avoids altering that setting. This is because non-job-control shells often ignore certain signals when starting children, and it is important for the children to respect this.
We do not handle SIGQUIT or the program error signals in this
example because these are designed to provide information for debugging
(a core dump), and the temporary files may give useful information.
| sighandler_t sysv_signal (int signum, sighandler_t action) | Function |
The sysv_signal implements the behaviour of the standard
signal function as found on SVID systems. The difference to BSD
systems is that the handler is deinstalled after a delivery of a signal.
Compatibility Note: As said above for |
| sighandler_t ssignal (int signum, sighandler_t action) | Function |
The ssignal function does the same thing as signal; it is
provided only for compatibility with SVID.
|
| sighandler_t SIG_ERR | Macro |
The value of this macro is used as the return value from signal
to indicate an error.
|
The sigaction function has the same basic effect as
signal: to specify how a signal should be handled by the process.
However, sigaction offers more control, at the expense of more
complexity. In particular, sigaction allows you to specify
additional flags to control when the signal is generated and how the
handler is invoked.
The sigaction function is declared in signal.h.
| struct sigaction | Data Type |
Structures of type struct sigaction are used in the
sigaction function to specify all the information about how to
handle a particular signal. This structure contains at least the
following members:
|
| int sigaction (int signum, const struct sigaction *action, struct sigaction *old-action) | Function |
The action argument is used to set up a new action for the signal
signum, while the old-action argument is used to return
information about the action previously associated with this symbol.
(In other words, old-action has the same purpose as the
signal function's return value--you can check to see what the
old action in effect for the signal was, and restore it later if you
want.)
Either action or old-action can be a null pointer. If old-action is a null pointer, this simply suppresses the return of information about the old action. If action is a null pointer, the action associated with the signal signum is unchanged; this allows you to inquire about how a signal is being handled without changing that handling. The return value from
|
signal and sigactionIt's possible to use both the signal and sigaction
functions within a single program, but you have to be careful because
they can interact in slightly strange ways.
The sigaction function specifies more information than the
signal function, so the return value from signal cannot
express the full range of sigaction possibilities. Therefore, if
you use signal to save and later reestablish an action, it may
not be able to reestablish properly a handler that was established with
sigaction.
To avoid having problems as a result, always use sigaction to
save and restore a handler if your program uses sigaction at all.
Since sigaction is more general, it can properly save and
reestablish any action, regardless of whether it was established
originally with signal or sigaction.
On some systems if you establish an action with signal and then
examine it with sigaction, the handler address that you get may
not be the same as what you specified with signal. It may not
even be suitable for use as an action argument with signal. But
you can rely on using it as an argument to sigaction. This
problem never happens on the GNU system.
So, you're better off using one or the other of the mechanisms consistently within a single program.
Portability Note: The basic signal function is a feature
of ISO C, while sigaction is part of the POSIX.1 standard. If
you are concerned about portability to non-POSIX systems, then you
should use the signal function instead.
sigaction Function ExampleIn Basic Signal Handling, we gave an example of establishing a
simple handler for termination signals using signal. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags is interpreted as a bit mask. Thus, you
should choose the flags you want to set, OR those flags together,
and store the result in the sa_flags member of your
sigaction structure.
Each signal number has its own set of flags. Each call to
sigaction affects one particular signal number, and the flags
that you specify apply only to that particular signal.
In the GNU C library, establishing a handler with signal sets all
the flags to zero except for SA_RESTART, whose value depends on
the settings you have made with siginterrupt. See Interrupted Primitives, to see what this is about.
These macros are defined in the header file signal.h.
| int SA_NOCLDSTOP | Macro |
This flag is meaningful only for the SIGCHLD signal. When the
flag is set, the system delivers the signal for a terminated child
process but not for one that is stopped. By default, SIGCHLD is
delivered for both terminated children and stopped children.
Setting this flag for a signal other than |
| int SA_ONSTACK | Macro |
If this flag is set for a particular signal number, the system uses the
signal stack when delivering that kind of signal. See Signal Stack.
If a signal with this flag arrives and you have not set a signal stack,
the system terminates the program with SIGILL.
|
| int SA_RESTART | Macro |
This flag controls what happens when a signal is delivered during
certain primitives (such as open, read or write),
and the signal handler returns normally. There are two alternatives:
the library function can resume, or it can return failure with error
code EINTR.
The choice is controlled by the |
When a new process is created (see Creating a Process), it inherits
handling of signals from its parent process. However, when you load a
new process image using the exec function (see Executing a File), any signals that you've defined your own handlers for revert to
their SIG_DFL handling. (If you think about it a little, this
makes sense; the handler functions from the old program are specific to
that program, and aren't even present in the address space of the new
program image.) Of course, the new program can establish its own
handlers.
When a program is run by a shell, the shell normally sets the initial
actions for the child process to SIG_DFL or SIG_IGN, as
appropriate. It's a good idea to check to make sure that the shell has
not set up an initial action of SIG_IGN before you establish your
own signal handlers.
Here is an example of how to establish a handler for SIGHUP, but
not if SIGHUP is currently ignored:
...
struct sigaction temp;
sigaction (SIGHUP, NULL, &temp);
if (temp.sa_handler != SIG_IGN)
{
temp.sa_handler = handle_sighup;
sigemptyset (&temp.sa_mask);
sigaction (SIGHUP, &temp, NULL);
}
This section describes how to write a signal handler function that can
be established with the signal or sigaction functions.
A signal handler is just a function that you compile together with the
rest of the program. Instead of directly invoking the function, you use
signal or sigaction to tell the operating system to call
it when a signal arrives. This is known as establishing the
handler. See Signal Actions.
There are two basic strategies you can use in signal handler functions:
You need to take special care in a name="/code>. Here is an
equivalent example using sigaction:
#include <signal.h>
void
termination_handler (int signum)
{
struct temp_file *p;
for (p = temp_file_list; p; p = p->next)
unlink (p->name);
}
int
main (void)
{
...
struct sigaction new_action, old_action;
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGHUP, &new_action, NULL);
sigaction (SIGTERM, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGTERM, &new_action, NULL);
...
}
The program just loads the new_action structure with the desired
parameters and passes it in the sigaction call. The usage of
sigemptyset is described later; see Blocking Signals.
As in the example using signal, we avoid handling signals
previously set to be ignored. Here we can avoid altering the signal
handler even momentarily, by using the feature of sigaction that
lets us examine the current action without specifying a new one.
Here is another example. It retrieves information about the current
action for SIGINT without changing that action.
struct sigaction query_action; if (sigaction (SIGINT, NULL, &query_action) < 0) /*sigactionreturns -1 in case of error. */ else if (query_action.sa_handler == SIG_DFL) /*SIGINTis handled in the default, fatal manner. */ else if (query_action.sa_handler == SIG_IGN) /*SIGINTis ignored. */ else /* A programmer-defined signal handler is in effect. */
sigactionThe sa_flags member of the sigaction structure is a
catch-all for special features. Most of the time, SA_RESTART is
a good value to use for this field.
The value of sa_flags