diff options
Diffstat (limited to 'manual')
-rw-r--r-- | manual/examples/swapcontext.c | 99 | ||||
-rw-r--r-- | manual/filesys.texi | 85 | ||||
-rw-r--r-- | manual/install.texi | 1 | ||||
-rw-r--r-- | manual/setjmp.texi | 239 | ||||
-rw-r--r-- | manual/signal.texi | 12 |
5 files changed, 427 insertions, 9 deletions
diff --git a/manual/examples/swapcontext.c b/manual/examples/swapcontext.c new file mode 100644 index 0000000000..f733510f88 --- /dev/null +++ b/manual/examples/swapcontext.c @@ -0,0 +1,99 @@ +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <ucontext.h> +#include <sys/time.h> + +/* Set by the signal handler. */ +static volatile int expired; + +/* The contexts. */ +static ucontext_t uc[3]; + +/* We do only a certain number of switches. */ +static int switches; + + +/* This is the function doing the work. It is just a + skeleton, real code has to be filled in. */ +static void +f (int n) +{ + int m = 0; + while (1) + { + /* This is where the work would be done. */ + if (++m % 100 == 0) + { + putchar ('.'); + fflush (stdout); + } + + /* Regularly the @var{expire} variable must be checked. */ + if (expired) + { + /* We do not want the program to run forever. */ + if (++switches == 20) + return; + + printf ("\nswitching from %d to %d\n", n, 3 - n); + expired = 0; + /* Switch to the other context, saving the current one. */ + swapcontext (&uc[n], &uc[3 - n]); + } + } +} + +/* This is the signal handler which simply set the variable. */ +void +handler (int signal) +{ + expired = 1; +} + + +int +main (void) +{ + struct sigaction sa; + struct itimerval it; + char st1[8192]; + char st2[8192]; + + /* Initialize the data structures for the interval timer. */ + sa.sa_flags = SA_RESTART; + sigfillset (&sa.sa_mask); + sa.sa_handler = handler; + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 1; + it.it_value = it.it_interval; + + /* Install the timer and get the context we can manipulate. */ + if (sigaction (SIGPROF, &sa, NULL) < 0 + || setitimer (ITIMER_PROF, &it, NULL) < 0 + || getcontext (&uc[1]) == -1 + || getcontext (&uc[2]) == -1) + abort (); + + /* Create a context with a separate stack which causes the + function @code{f} to be call with the parameter @code{1}. + Note that the @code{uc_link} points to the main context + which will cause the program to terminate once the function + return. */ + uc[1].uc_link = &uc[0]; + uc[1].uc_stack.ss_sp = st1; + uc[1].uc_stack.ss_size = sizeof st1; + makecontext (&uc[1], (void (*) (void)) f, 1, 1); + + /* Similarly, but @code{2} is passed as the parameter to @code{f}. */ + uc[2].uc_link = &uc[0]; + uc[2].uc_stack.ss_sp = st2; + uc[2].uc_stack.ss_size = sizeof st2; + makecontext (&uc[2], (void (*) (void)) f, 1, 2); + + /* Start running. */ + swapcontext (&uc[0], &uc[1]); + putchar ('\n'); + + return 0; +} diff --git a/manual/filesys.texi b/manual/filesys.texi index e54f63dfc5..d7ab4e4a7f 100644 --- a/manual/filesys.texi +++ b/manual/filesys.texi @@ -1065,7 +1065,23 @@ purpose is to obtain information about the link. @code{link}, the function that makes a hard link, does too. It makes a hard link to the symbolic link, which one rarely wants. -Prototypes for the functions listed in this section are in +Some systems have for some functions operating on files have a limit on +how many symbolic links are followed when resolving a path name. The +limit if it exists is published in the @file{sys/param.h} header file. + +@comment sys/param.h +@comment BSD +@deftypevr Macro int MAXSYMLINKS + +The macro @code{MAXSYMLINKS} specifies how many symlinks some function +will follow before returning @code{ELOOP}. Not all functions behave the +same and this value is not the same a that returned for +@code{_SC_SYMLOOP} by @code{sysconf}. In fact, the @code{sysconf} +result can indicate that there is no fixed limit although +@code{MAXSYMLINKS} exists and has a finite value. +@end deftypevr + +Prototypes for most of the functions listed in this section are in @file{unistd.h}. @pindex unistd.h @@ -1153,6 +1169,73 @@ A hardware error occurred while reading or writing data on the disk. @c @end group @end deftypefun +In some situations it is desirable to resolve all the to get the real +name of a file where no prefix names a symbolic link which is followed +and no filename in the path is @code{.} or @code{..}. This is for +instance desirable if files have to be compare in which case different +names can refer to the same inode. + +@comment stdlib.h +@comment GNU +@deftypefun {char *} canonicalize_file_name (const char *@var{name}) + +The @code{canonicalize_file_name} function returns the absolute name of +the file named by @var{name} which contains no @code{.}, @code{..} +components nor any repeated path separators (@code{/}) or symlinks. The +result is passed back as the return value of the function in a block of +memory allocated with @code{malloc}. If the result is not used anymore +the memory should be freed with a call to @code{free}. + +In any of the path components except the last one is missing the +function returns a NULL pointer. This is also what is returned if the +length of the path reaches or exceeds @code{PATH_MAX} characters. In +any case @code{errno} is set accordingly. + +@table @code +@item ENAMETOOLONG +The resulting path is too long. This error only occurs on systems which +have a limit on the file name length. + +@item EACCES +At least one of the path components is not readable. + +@item ENOENT +The input file name is empty. + +@item ENOENT +At least one of the path components does not exist. + +@item ELOOP +More than @code{MAXSYMLINKS} many symlinks have been followed. +@end table + +This function is a GNU extension and is declared in @file{stdlib.h}. +@end deftypefun + +The Unix standard includes a similar function which differs from +@code{canonicalize_file_name} in that the user has to provide the buffer +where the result is placed in. + +@comment stdlib.h +@comment XPG +@deftypefun {char *} realpath (const char *restrict @var{name}, char *restrict @var{resolved}) + +The @code{realpath} function behaves just like +@code{canonicalize_file_name} but instead of allocating a buffer for the +result it is placed in the buffer pointed to by @var{resolved}. + +One other difference is that the buffer @var{resolved} will contain the +part of the path component which does not exist or is not readable if +the function returns @code{NULL} and @code{errno} is set to +@code{EACCES} or @code{ENOENT}. + +This function is declared in @file{stdlib.h}. +@end deftypefun + +The advantage of using this function is that it is more widely +available. The drawback is that it reports failures for long path on +systems which have no limits on the file name length. + @node Deleting Files @section Deleting Files @cindex deleting a file diff --git a/manual/install.texi b/manual/install.texi index 1d6b39498b..fa8b6183e9 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -424,6 +424,7 @@ following patterns: @smallexample alpha@var{*}-@var{*}-linux arm-@var{*}-linux +cris-@var{*}-linux hppa-@var{*}-linux i@var{x}86-@var{*}-gnu i@var{x}86-@var{*}-linux diff --git a/manual/setjmp.texi b/manual/setjmp.texi index 00e78a51e8..65d62da518 100644 --- a/manual/setjmp.texi +++ b/manual/setjmp.texi @@ -12,8 +12,9 @@ functions. @menu * Intro: Non-Local Intro. When and how to use these facilities. -* Details: Non-Local Details. Functions for non-local exits. +* Details: Non-Local Details. Functions for non-local exits. * Non-Local Exits and Signals:: Portability issues. +* System V contexts:: Complete context control a la System V. @end menu @node Non-Local Intro, Non-Local Details, , Non-Local Exits @@ -169,7 +170,7 @@ function containing the @code{setjmp} call that have been changed since the call to @code{setjmp} are indeterminate, unless you have declared them @code{volatile}. -@node Non-Local Exits and Signals,, Non-Local Details, Non-Local Exits +@node Non-Local Exits and Signals, System V contexts, Non-Local Details, Non-Local Exits @section Non-Local Exits and Signals In BSD Unix systems, @code{setjmp} and @code{longjmp} also save and @@ -211,3 +212,237 @@ argument. If the @code{sigsetjmp} call that set this @var{state} used a nonzero @var{savesigs} flag, @code{siglongjmp} also restores the set of blocked signals. @end deftypefun + +@node System V contexts,, Non-Local Exits and Signals, Non-Local Exits +@section Complete Context Control + +The Unix standard one more set of function to control the execution path +and these functions are more powerful than those discussed in this +chapter so far. These function were part of the original @w{System V} +API and by this route were added to the Unix API. Beside on branded +Unix implementations these interfaces are not widely available. Not all +platforms and/or architectures the GNU C Library is available on provide +this interface. Use @file{configure} to detect the availability. + +Similar to the @code{jmp_buf} and @code{sigjmp_buf} types used for the +variables to contain the state of the @code{longjmp} functions the +interfaces of interest here have an appropriate type as well. Objects +of this type are normally much larger since more information is +contained. The type is also used in a few more places as we will see. +The types and functions described in this section are all defined and +declared respectively in the @file{ucontext.h} header file. + +@comment ucontext.h +@comment SVID +@deftp {Data Type} ucontext_t + +The @code{ucontext_t} type is defined as a structure with as least the +following elements: + +@table @code +@item ucontext_t *uc_link +This is a pointer to the next context structure which is used if the +context described in the current structure returns. + +@item sigset_t uc_sigmask +Set of signals which are blocked when this context is used. + +@item stack_t uc_stack +Stack used for this context. The value need not be (and normally is +not) the stack pointer. @xref{Signal Stack}. + +@item mcontext_t uc_mcontext +This element contains the actual state of the process. The +@code{mcontext_t} type is also defined in this header but the definition +should be treated as opaque. Any use of knowledge of the type makes +applications less portable. + +@end table +@end deftp + +Objects of this type have to be created by the user. The initialization +and modification happens through one of the following functions: + +@comment ucontext.h +@comment SVID +@deftypefun int getcontext (ucontext_t *@var{ucp}) +The @code{getcontext} function initializes the variable pointed to by +@var{ucp} with the context of the calling thread. The context contains +the content of the registers, the signal mask, and the current stack. +Executing the contents would start at the point where the +@code{getcontext} call just returned. + +The function returns @code{0} if succesful. Otherwise it returns +@code{-1} and sets @var{errno} accordingly. +@end deftypefun + +The @code{getcontext} function is similar to @code{setjmp} but it does +not provide an indication of whether the function returns for the first +time or whether the initialized context was used and the execution is +resumed at just that point. If this is necessary the user has to take +determine this herself. This must be done carefully since the context +contains registers which might contain register variables. This is a +good situation to define variables with @code{volatile}. + +Once the context variable is initialized it can be used as is or it can +be modified. The latter is normally done to implement co-routines or +similar constructs. The @code{makecontext} function is what has to be +used to do that. + +@comment ucontext.h +@comment SVID +@deftypefun void makecontext (ucontext_t *@var{ucp}, void (*@var{func}) (void), int @var{argc}, @dots{}) + +The @var{ucp} parameter passed to the @code{makecontext} shall be +initialized by a call to @code{getcontext}. The context will be +modified to in a way so that if the context is resumed it will start by +calling the function @code{func} which gets @var{argc} integer arguments +passed. The integer arguments which are to be passed should follow the +@var{argc} parameter in the call to @code{makecontext}. + +Before the call to this function the @code{uc_stack} and @code{uc_link} +element of the @var{ucp} structure should be initialized. The +@code{uc_stack} element describes the stack which is used for this +context. No two contexts which are used at the same time should use the +same memory region for a stack. + +The @code{uc_link} element of the object pointed to by @var{ucp} should +be a pointer to the context to be executed when the function @var{func} +returns or it should be a null pointer. See @code{setcontext} for more +information about the exact use. +@end deftypefun + +While allocating the memory for the stack one has to be careful. Most +modern processors keep track of whether a certain memory region is +allowed to contain code which is executed or not. Data segments and +heap memory is normally not tagged to allow this. The result is that +programs would fail. Examples for such code include the calling +sequences the GNU C compiler generates for calls to nested functions. +Safe ways to allocate stacks correctly include using memory on the +original threads stack or explicitly allocate memory tagged for +execution using (@pxref{Memory-mapped I/O}). + +@strong{Compatibility note}: The current Unix standard is very imprecise +about the way the stack is allocated. All implementations seem to agree +that the @code{uc_stack} element must be used but the values stored in +the elements of the @code{stack_t} value are unclear. The GNU C library +and most other Unix implementations require the @code{ss_sp} value of +the @code{uc_stack} element to point to the base of the memory region +allocated for the stack and the size of the memory region is stored in +@code{ss_size}. There are implements out there which require +@code{ss_sp} to be set to the value the stack pointer will have (which +can depending on the direction the stack grows be different). This +difference makes the @code{makecontext} function hard to use and it +requires detection of the platform at compile time. + +@comment ucontext.h +@comment SVID +@deftypefun int setcontext (const ucontext_t *@var{ucp}) + +The @code{setcontext} function restores the context described by +@var{ucp}. The context is not modified and can be reused as often as +wanted. + +If the context was created by @code{getcontext} execution resumes with +the registers filled with the same values and the same stack as if the +@code{getcontext} call just returned. + +If the context was modified with a call to @code{makecontext} execution +continues with the function passed to @code{makecontext} which gets the +specified parameters passed. If this function returns execution is +resumed in the context which was referenced by the @code{uc_link} +element of the context structure passed to @code{makecontext} at the +time of the call. If @code{uc_link} was a null pointer the application +terminates in this case. + +Since the context contains information about the stack no two threads +should use the same context at the same time. The result in most cases +would be disastrous. + +The @code{setcontext} function does not return unless an error occurred +in which case it returns @code{-1}. +@end deftypefun + +The @code{setcontext} function simply replaces the current context with +the one described by the @var{ucp} parameter. This is often useful but +there are situations where the current context has to be preserved. + +@comment ucontext.h +@comment SVID +@deftypefun int swapcontext (ucontext_t *restrict @var{oucp}, const ucontext_t *restrict @var{ucp}) + +The @code{swapcontext} function is similar to @code{setcontext} but +instead of just replacing the current context the latter is first saved +in the object pointed to by @var{oucp} as if this was a call to +@code{getcontext}. The saved context would resume after the call to +@code{swapcontext}. + +Once the current context is saved the context described in @var{ucp} is +installed and execution continues as described in this context. + +If @code{swapcontext} succeeds the function does not return unless the +context @var{oucp} is used without prior modification by +@code{makecontext}. The return value in this case is @code{0}. If the +function fails it returns @code{-1} and set @var{errno} accordingly. +@end deftypefun + +@heading Example for SVID Context Handling + +The easiest way to use the context handling functions is as a +replacement for @code{setjmp} and @code{longjmp}. The context contains +on most platforms more information which might lead to less surprises +but this also means using these functions is more expensive (beside +being less portable). + +@smallexample +int +random_search (int n, int (*fp) (int, ucontext_t *)) +@{ + volatile int cnt = 0; + ucontext_t uc; + + /* @r{Safe current context.} */ + if (getcontext (&uc) < 0) + return -1; + + /* @r{If we have not tried @var{n} times try again.} */ + if (cnt++ < n) + /* @r{Call the function with a new random number} + @r{and the context}. */ + if (fp (rand (), &uc) != 0) + /* @r{We found what we were looking for.} */ + return 1; + + /* @r{Not found.} */ + return 0; +@} +@end smallexample + +Using contexts in such a way enables emulating exception handling. The +search functions passed in the @var{fp} parameter could be very large, +nested, and complex which would make it complicated (or at least would +require a lot of code) to leave the function with an error value which +has to be passed down to the caller. By using the context it is +possible to leave the search function in one step and allow restarting +the search which also has the nice side effect that it can be +significantly faster. + +Something which is harder to implement with @code{setjmp} and +@code{longjmp} is to switch temporarily to a different execution path +and then resume where execution was stopped. + +@smallexample +@include swapcontext.c.texi +@end smallexample + +This an example how the context functions can be used to implement +co-routines or cooperative multi-threading. All that has to be done is +to call every once in a while @code{swapcontext} to continue running a +different context. It is not allowed to do the context switching from +the signal handler directly since neither @code{setcontext} nor +@code{swapcontext} are functions which can be called from a signal +handler. But setting a variable in the signal handler and checking it +in the body of the functions which are executed. Since +@code{swapcontext} is saving the current context it is possible to have +multiple different scheduling points in the code. Execution will always +resume where it was left. diff --git a/manual/signal.texi b/manual/signal.texi index 90839375e2..c92e877113 100644 --- a/manual/signal.texi +++ b/manual/signal.texi @@ -1171,7 +1171,7 @@ the signal. These are described in more detail in @ref{Flags for Sigaction}. @comment signal.h @comment POSIX.1 -@deftypefun int sigaction (int @var{signum}, const struct sigaction *@var{action}, struct sigaction *@var{old-action}) +@deftypefun int sigaction (int @var{signum}, const struct sigaction *restrict @var{action}, struct sigaction *restrict @var{old-action}) The @var{action} argument is used to set up a new action for the signal @var{signum}, while the @var{old-action} argument is used to return information about the action previously associated with this symbol. @@ -2563,7 +2563,7 @@ The prototype for the @code{sigprocmask} function is in @file{signal.h}. @comment signal.h @comment POSIX.1 -@deftypefun int sigprocmask (int @var{how}, const sigset_t *@var{set}, sigset_t *@var{oldset}) +@deftypefun int sigprocmask (int @var{how}, const sigset_t *restrict @var{set}, sigset_t *restrict @var{oldset}) The @code{sigprocmask} function is used to examine or change the calling process's signal mask. The @var{how} argument determines how the signal mask is changed, and must be one of the following values: @@ -3088,8 +3088,8 @@ not require your program to know which direction the stack grows, which depends on the specific machine and operating system. @comment signal.h -@comment BSD -@deftp {Data Type} {struct sigaltstack} +@comment XPG +@deftp {Data Type} stack_t This structure describes a signal stack. It contains the following members: @table @code @@ -3136,8 +3136,8 @@ delivered on the normal user stack. @end deftp @comment signal.h -@comment BSD -@deftypefun int sigaltstack (const struct sigaltstack *@var{stack}, struct sigaltstack *@var{oldstack}) +@comment XPG +@deftypefun int sigaltstack (const stack_t *restrict @var{stack}, stack_t *restrict @var{oldstack}) The @code{sigaltstack} function specifies an alternate stack for use during signal handling. When a signal is received by the process and its action indicates that the signal stack is used, the system arranges |