tcl.lock-break Verb: Access/TCL, cfunc.introduction Introductory/C Functions, perf Definition/General, filename.peqs File/Spooler, boot.error Definition/Unix, basic.%kill C Function/BASIC Program, tcl.trap Verb: Access/TCL, signals Definition/Unix, spooler.account Definition/Spooler, up Introductory/Update Processor, tcl.kill Verb: Access/TCL, signals Definition/Unix

tcl.lock-break

Command tcl.lock-break Verb: Access/TCL
Applicable release versions: AP 6.2
Category TCL (746)
Description Enables or Disables the ability to unconditionally break during a lock failure.

By default, the user is allowed to break during a lock failure EVEN if the break has been disabled by the user. This is to allow escape from deadlock situations. On communications lines, this can cause trouble since certian hardware can generate erroneous break signals. In this case, it is recommended to disable this function by doing "lock-break (f".
Syntax lock-break {(options}
Options n Allows breaking during lock failure.
f Disallows breaking during lock failure.
Example
Purpose
Related tcl.lock-break-on
tcl.lock-break-off

cfunc.introduction

Command cfunc.introduction Introductory/C Functions
Applicable release versions: AP 6.1
Category C Functions (120)
Description outlines how to access the Pick environment from the "C" programming language.

The functionality of the Pick environment is available from the C programming language. This is made available through a set of functions and macros defined in the include file "CPuser.h".

Library Format

Functions within the library have the following general structure:

{rc=}_CP_xxx({arg0{,arg1{,...}}});

where:

_CP_xxx is a general pattern for the name. It is always prefixed with _CP_ to avoid naming conflicts with standard libraries and is suffixed with an entirely lower-case tag like _CP_execute. Macros are provided using the same model, but they use uppercase tags like _CP_SLEN.

arg0 - argi are arguments.

rc is the result code. Almost all functions return an integer result. This result is -1 if an error occurs, and the global variable _CP_errno is set to one of the following error codes:

PE_NFILE Not enough memory to open more files
PE_ACCESS Cannot access file
PE_TRUNC String trunctated due to lack of memory
PE_NOSPACE Could not allocate workspace
PE_LOCK Item is locked
PE_INVAL Invalid call
PE_NONUM Not a number
PE_BADF File not opened
PE_MISSING File not found
PE_CONV Conversion error
PE_BADATTR Bad attribute
PE_TMOUT Input time out
PE_TAPE Tape error
PE_PROC Proc read error
PE_EOF End of file/item
PE_CALLMAIN Tried to call a main as a subroutine
PE_NOTROOT Bad root variable
PE_ILL_KEY Bad key operator
PE_LONG_STR Too long a string for heading
PE_LEVEL Debugger entered
PE_DEBUG Debugger entered
PE_BAD_PARAMS Too many parameters on a call
PE_LOAD_ERR Unable to load Flash subroutine
PE_END_LIST No more items on select
PE_GETSEND Bad pib on get/send
PE_MISCERR Miscellaneous logon error
PE_INIT Virtual machine not booted or attached
PE_BADUSER Bad user ID or user password
PE_BADMD Bad MD or MD password

General Usage

To use this library, the user makes a call to _CP_logon() at the beginning of the C program to connect to the Pick virtual machine. This call goes through the normal Pick logon activities, but suppress all user prompts and messages. Note that neither the user nor the MD macro will be executed. After logging on, the user has full access to the Pick database using C calls which provide functionality previously available only through Pick/BASIC. When the C program completes, the user must issue a _CP_logoff() call to terminate the Pick connection.

String Handling

The standard C string type is not sufficient for handling the dynamic nature of Pick strings, so a hybrid data type has been created called CPSTR. This data type provides allocation, deallocation, and resizing of strings at a much higher performance level than that obtained using malloc(), and free() with C strings. The internal structure of a CPSTR is reserved and SHOULD NOT BE ACCESSED DIRECTLY. Failure to abide by this rule will DEFINITELY GUARANTEE INCOMPATIBILITY WITH FUTURE RELEASES. The structure of a CPSTR is as follows:

Header Internal use only - DO NOT MODIFY
String - Character array containing the actual string
Terminator - A single character used for termination
Footer Internal use only - DO NOT MODIFY

The following macros are provided to access all desired portions of a CPSTR structure.

_CP_SLEN(s) returns the current length of a string. This length does not include any terminating character like a segment mark or a null character.

_CP_SADDR(s) returns a (char *) to the actual string data which may or may not be terminated by a 0x00. Note that this (char *) MUST NOT be passed to the free() C function or to any C function which may try to use free() on the (char *).

Allocation of CPSTR strings is accomplished via special allocation routines. CPSTR strings MUST NOT be allocated with the C function malloc(). The allocation routines provided set necessary internal flags, and they are much more efficient than malloc. Note that these routines create dynamic structures which must be deallocated with the routines listed below.

_CP_str_alloc(l) returns a CPSTR of length l. The actual string data portion of the string is undefined.

_CP_mkstrl(char *s, int l) Returns a CPSTR from a C string s, of length l. The string portion of the CPSTR will contain a copy of the C string's data.

_CP_mkstr(char *s) Returns a CPSTR from a C string s terminated by a 0x00. The string portion of the CPSTR will contain a copy of the C string's data. This function is less efficient than _CP_mkstrl as it must scan the C string to determine its length.

_CP_str_realloc(CPSTR **s, int l) Resizes the CPSTR s.

_CP_str_free(CPSTR ** s) Frees the desired string s.

Note that when the _CP_logoff call is executed, all CPSTR's remain valid, but they may not be passed to any of the _CP_ routines. All CPSTR's are properly cleaned up when the C program exits.

The user must be careful with termination. Any _CP_ routine may modify the termination character. Therefore, the user must use the _CP_TERM() macro to terminate CPSTR's with a 0x00 if it is necessary to pass the string portion of it to a standard Unix routine.

Note that it is necessary to free strings only when the user has finished with them completely. All resizing of strings is accomplished automatically by the _CP_routines. For example, if a process repeatedly reads data into a buffer via the _CP_read call, this buffer will be automatically resized to fit the new data within the _CP_read call at every read.

Environment Setting

To make it easier to handle the differences between the standard behavior of Unix programs and the standard behavior of Pick programs, two calls are provided that set the "environment" to either Pick or Unix.

_CP_pick_env() sets the application to a standard "Pick" environment. When using this setting, all terminal input and output must be done via Pick routines ONLY.

_CP_unix_env() sets the application to a standard "Unix" environment. With this setting, all terminal input and output must be done directly from "C". The program must not "execute" or "call" any Pick routines which may "crt" or "print" something through Pick.

The original logon to Pick calls _CP_pick_env(). After that, the user may use these routines to switch environments as often as desired, but the environment functions are fairly expensive so they should only be used when switching environments is absolutely necessary. To ensure the correct functionality of the Unix shell, the system automatically calls _CP_unix_env() when the user logs off the of the Pick virtual machine.

Break Key Handling

When logged into Pick, the default action for the break key is set to push a level or drop into the debugger as is standard in Pick. This behavior may be changed however by using the following calls:

_CP_unix_break() causes the break key to force a logoff from Pick and terminate the C program with an exit() call. This simulates the standard behavior of the break key in a Unix application.

_CP_pick_break() causes the break key to behave in the Pick manner.

Handling General Pick Interrupts

Pick interrupts, besides breaks, such as messages, may not be masked, but they may be detected (after the occurence) by interrogating the _CP_interrupt variable. This integer location contains the same information available in BASIC from the system(37) function. However, examination of _CP_interrupt is much more efficient when programming in C.

Custom Signal Processing

The Pick libraries make extensive use of signal processing. Because of this, the practice of reprogramming signals within a C application using Pick C routines is strongly discouraged. However, if it is absolutely necessary, there are several rules which must be followed.

When calling _CP_logon, all signals are re-routed to Pick signal handlers.

When calling _CP_logoff, all signals are re-routed to Unix defaults. Note that they are not necessarily reset to the values they held before the _CP_logon call.

The signal SIGUSR2 must never be reprogrammed as it is used by Pick for logging off and sending messages.

Because interrupts may occur within critical code, the user may not make calls to _CP_ functions within signal handlers.
Syntax
Options
Example
The following program prints the name of all users in the users file.

#include "CPuser.h"

main()
{
  CPSTR * machine = _CP_mkstrl("pick0",5); /* default */
  CPSTR * user = _CP_mkstrl("dm",2);
  CPSTR * md = _CP_mkstrl("dm",2);

  CPSTR * filename = _CP_mkstrl("users",5);
  int     fd = -1;
  int     sl = -1; /* initialize select list */

  CPSTR * item_id = _CP_str_null;

/* Logon onto "pick0" as "dm" in the "dm" md */

  if (_CP_logon(machine, user, _CP_str_null, 
      md, _CP_str_null, -1, 0) < 0)
  {
    printf("Logon error %dn", _CP_errno);
    exit(1);   
  }

  /* done with machine, user, and md */

  _CP_str_free(machine);
  _CP_str_free(user);
  _CP_str_free(md);

  /* Make the break key terminate the program */

  _CP_unix_break();

  /* Open the users file into the file descriptor fd */

  if (_CP_open(&fd, _CP_str_null, filename) < 0)
  {
    _CP_logoff();
    printf("Could not open users file n");
    exit(2);
  }

  /* done with filename */

  _CP_str_free(filename);
  
  /* Do a raw select of "users" and store that select
     list in the select list descriptor sl */

  _CP_select(fd, &sl, 0);

  /* Switch to Unix-type I/O so we can use printf */

  _CP_unix_env();

  /* repeatedly read item-ids and print them as a list */

  /* Note how item_id is repeatedly passed to _CP_readnext.
     Each time, _CP_readnext will resize it if necessary,
     and write the next item-id into that CPSTR  */

  while (_CP_readnext(&item_id, &sl, 0, 0) >= 0)
  {
    _CP_TERM(item_id); /* terminate for printf */
    printf("%sn", _CP_SADDR(item_id));
  }

  /* done with item_id - Not absolutely necessary since */
  /*   it will be cleaned up when we exit               */

  _CP_str_free(item_id);

  /* logoff and return */

  _CP_logoff();
  return 0;
}
Purpose
Related cpstr*
cfunc.alpha
cfunc.ascii
cfunc.ati
cfunc.at2
cfunc.break
cfunc.call
cfunc.casing
cfunc.cat
cfunc.clearfile
cfunc.close
cfunc.col1
cfunc.col2
cfunc.compare
cfunc.convert
cfunc.count
cfunc.crt
cfunc.crtn
cfunc.data
cfunc.date
cfunc.dcount
cfunc.debug
cfunc.delete
cfunc.delete_item
cfunc.dtx
cfunc.ebcdic
cfunc.echo
cfunc.execute
cfunc.extract
cfunc.field
cfunc.field_store
cfunc.fold
cfunc.footing
cfunc.get
cfunc.heading
cfunc.iconv
cfunc.in
cfunc.index
cfunc.insert
cfunc.interrupt
cfunc.key
cfunc.load
cfunc.locate
cfunc.lock
cfunc.logon
cfunc.match
cfunc.mkstr
cfunc.mkstrl
cfunc.num
cfunc.occurs
cfunc.oconv
cfunc.open
cfunc.out
cfunc.ovly_subs
cfunc.page
cfunc.page_n
cfunc.pick_break
cfunc.pick_env
cfunc.print
cfunc.printer
cfunc.printn
cfunc.print_on
cfunc.prompt
cfunc.read
cfunc.readnext
cfunc.readt
cfunc.readv
cfunc.release
cfunc.release_all
cfunc.replace
cfunc.replace_bridge
cfunc.rewind
cfunc.root
cfunc.saddr
cfunc.select
cfunc.send
cfunc.sleep
cfunc.slen
cfunc.sort
cfunc.soundex
cfunc.space
cfunc.str
cfunc.str0
cfunc.str_alloc
cfunc.str_free
cfunc.str_null
cfunc.str_realloc
cfunc.substr
cfunc.sum
cfunc.system
cfunc.term
cfunc.time
cfunc.timedate
cfunc.trim
cfunc.unix_break
cfunc.unix_env
cfunc.unlock
cfunc.unlock_all
cfunc.weof
cfunc.write
cfunc.writet
cfunc.writev
cfunc.xtd
cpstr
cfunc.integration
cfunc.precision
cfunc.rs
cfunc.sr
cfunc.si
cfunc.is
cfunc.str_copy
cfunc.filelock
cfunc.fileunlock
cfunc.trans
cfunc.clearselect
cfunc.build_msg
cfunc.out_msg

perf

Command perf Definition/General
Applicable release versions: AP/Unix
Category General (155)
Description describes various tips, utilities and performance monitoring tools which allow identifying possible bottlenecks in a given configuration.

Introduction

When performance problems are experienced on a system, it is necessary to distinguish problems due to the Unix environment and problems due to a configuration not adapted to the application.

The reader is assumed to have a fairly good understanding of a Pick environment and some knowledge of Unix.

Overview

Unix related performance problems are usually punctual: at one given time, the system performances degrade noticeably, but overall performance should remain satisfactory. These problems are usually fairly easy to track and to fix.

Configuration problems are more insidious, in that they appear repetitively under some circumstances. The basic principle is to monitor the activity of the system over a long period of time during normal system activity. A series of statistics are taken and stored in a log file for later analysis.

The command to monitor the activity is buffers. The command to display the log file is buffers.g.

Unix Related Bottlenecks

The first elements to look at are the results provided by sar to eliminate configuration problems due to an unexpected Unix activity alongside with the Pick activity. Device related problems may also have very visible effects on the overall performance.

SAR Results

See the section 'System Activity Reporting' in the chapter 'System Administration' in the Installation or User's Guide for more details about sar.

CPU usage:

A well balanced system should have a high percentage (above 80-90%) of user cpu usage. High system mode usage indicates too many process switches, or too many system calls. A non null waiting for IO cpu usage indicates disk bottleneck. If the system cpu usage becomes very high, without high IO activity, this may indicate a device problem (see next section).

Paging activity:

The absolute golden rule is to avoid swapping (paging) during normal operations. To avoid swapping, the physical memory must be increased, or the amount of memory allocated to Pick decreased. Surprisingly, if the system swaps, Pick performances may improve by reducing the amount of memory allocated to Pick in the configuration file. Obviously, there are some lower limits which should not be crossed. The Pick activity monitoring should allow determining how far it is possible to go on that path.

If possible, avoid using costly Unix commands during peak hours (compiling is painful, X-window requires a lot of memory, etc...).

If some significant swapping is taking place, control that the memory allocated to Pick (see the verb what) is not bigger than the total amount of physical memory minus the minimum size of memory required for the Unix Kernel (from 2 megabytes for SCO Unix to 6 megabytes for AIX, depending on the Implementation).

To identify which processes are running, do the following (as 'root'):

ps -edalf | grep R

S UID PID PPID STIME TTY TIME CMD
R root 4719 1 ... 07:08:53 24/0 0:05 ap - 24 tty24
R root 8999 10534 ... 07:58:33 89/0 0:00 ps -edalf
S root 10534 4133 ... 08:58:33 89/0 0:00 grep R
R demo 26242 25467 ... 07:10:03 75/0 0:16 demo

The above example shows an extract of the result. This shows that the process 4719 runs Pick on the PIB 24. The process 26242 is a non Pick process which has used three times as much CPU as the Pick process did. By running this command several times, if some processes show several times, it will be possible to identify processes that may be should not be running during peak hours.

Device Problems

The most common problems with TTYs are due to incorrect cabling. When Unix tries to spawn a process (Pick or Unix) attached to a terminal, the device must be ready. If not, Unix 'waits' a bit and tries again. Worse, a port with a DCD in an unstable state can generate many interrupts, which, in turn, generate 'hang up' signals, creating a very important system load. To identify such problem, do the following (as 'root'):

ps -edalf | grep '?'

S root 4184 9047 ... 09:06:26 89/0 0:00 grep ?
S root 25185 1 ... 07:08:52 ? 0:00 ap - 9 tty9
R root 30571 1 ... 07:08:52 ? 23:45 ap - 19 tty19 printer

This command shows the process attached to terminals the system could not open. In the above example,the second line shows a Pick process (pid=25185), in a sleeping state (S): this process does not consume any CPU. The system could not open the terminal /dev/tty9, but the system abandoned tyring to open it. The third line shows a Pick process (pid=30571), in a running state (R): this terminal does use CPU, as the CPU usage '23:45' shows. The system tried to open the device /dev/tty19, failed, as in the first case, but, probably, the cable is incorrect or hanging loose at the other end, and is generating constant signals.

To fix this situation, the terminal must be connected properly or the associated entry in /etc/inittab turned to off instead of respawn. Unfortunately, it is sometimes very difficult to identify which device is in trouble when the above command does not show it explicitly. Only careful checking of the cables or trying to find which ports which did not start as expected, will allow, by elimination, to find the faulty port.

Identifying Configuration Problems

Statistics

The following elements are monitored by the buffers command:


Name Description

Activ Number of Process activations. Each disk read, keystroke, process wake up after a sleep increments this counter. When the number of frame faults is subtracted from this counter, this gives an idea of the volume of data entry.

Idle Idle time. Not supported on Unix Implementations

Fflt Frame faults. This counts the number of disk reads.

Writes Disk Writes. All writes are normally done by the background flush process to update disk from dirty frames in memory. A high number indicates either a lot of updates, but also may be an insufficient memory allocated for the Pick virtual machine.

Bfail Buffer Search Failures. This counters counts the number of failures to allocate a buffer in memory for a new frame. When non zero, this indicates that the memory is insufficient. This counter should never be non zero.

RqFull Disk Read Queue Full. Not supported on Unix Implementations

WqFull Disk Write Queue Full. This counter counts the number of instances where the flusher cannot keep up with the dirtying of frames. This is an indication that either the write queue is too small for the given configuration (see the section 'Flusher Adjustments' later in this appendix) or that the memory is too small.

DskErr Disk Errors.

Elapsd Elapsed time. This is the time in seconds between two sampling. For internal use only.

DblSrc Double Search. This counts the number of collisions between two or more processes frame faulting on the same frame at the same instant. A non zero counter should be exceptional.

Breuse Buffer Re-Use. This counts the number of instances where a memory buffer has been allocated by one process to read one FID and another process allocated the same buffer to contain another FID. A non zero counter should be exceptional.

Bcolls Batch Contentions/Collisions. This counts the number of collisions between a 'batch' process (i.e., a process which is disk intensive) and an 'interactive' process (i.e., a process which is keyboard input intensive). By default, Pick insures that interactive processes are given priority over batch processes in accessing certain resources. See the section 'Batch Processes' in this appendix for more details.

Sem Semaphores Collisions. This counts the number of collisions between two processes trying to access a systemwide internal table.

Vlocks Virtual Locks Failures. This counts the number of cases when a Pick process tried to assert a virtual lock and failed to acquire it because another process had it.

Blocks FlashBASIC or Pick/BASIC Locks Failures. This counts the number of cases when a Pick process tried to assert a FlashBASIC or Pick/BASIC lock and failed to acquire it because another process had it.

B0reg Buffers with no Virtual Registers attached. These are the buffers not currently attached for immediate reference. At any given time, very few buffers are actually attached. It is therefore normal that this number be almost equal to the total buffers in memory.

B1reg Buffers used by more than one process, but not used by its owner any more. These should be in very small number.

B2reg Buffers used exclusively by their owner. On RISC implementations, this situation allows better performance, because there is no conflict on these buffers. Normally, these buffers contain private workspace, data which is not shared, etc...

B>3reg Buffers used both by their owner and other processes. This number represent the number of pages actually shared among processes (data files) at any given time.

ww Write Required. This counts the number of buffers currently modified and not yet written to disk.

IObusy Buffers being read from disk. This counts the number of pending disk reads. This counters is usually null, since the reads are too fast to be picked up.

Mlock Number of buffers memory locked. If the ABS section is locked, this number is at least equal to the ABS size. Also included, are the tape buffers when the tape is attached.

Ref Referenced Buffers. This counts the number of buffers which have been recently used.

WQ Write Queued. Number of buffers currently enqueued for write.

Tophsh Top of Hash. This number measures the quality of the hashing algorithm used to find a frame in memory. This number must be high (above 60% of the total buffers).

avail Available buffers. Number of buffers candidate for replacement. These are the buffers that nobody has been using recently. When this number drops below 10% of the total buffers, performance decreases significantly.

batch Batch Buffers. This is the Number of buffers used by batch processes. A high level (something approaching 50% of disk buffers) indicates that disk intensive activity is taking place by batch processes.


Activity Log File

The activity log is stored in the file buffers.log with a data level per weekday (buffer.log,Monday, buffer.log,Tuesday, etc... ). The file is created automatically when the buffers (H) command is used for the first time. Each data level is cleared when changing day, so that the file records a whole week of activity automatically. The itemid is the internal time on five digits.

The buffers command also creates automatically the dictionary attributes corresponding to the various counters, as shown in the table above. The attribute TIME displays the sampling time.

The attribute DESCRIPTION in the D pointers Monday, Tuesday etc... contains the date.

The file is created with a DX attribute.

Monitoring Activity

Logon to the dm account. Type:

buffers {(options}

options


C Clear todays log data level, when used with the (H) option. This option must be used the very first time. To restart the monitoring after having stopped it for a while, do not use the (C) option.

H{n} Record statistics in the log file. If followed by a number n, the process sleeps n seconds between each sample. The default value is 5 seconds. When sampling over long periods, 5 minutes (300 seconds) are a good compromise between accuracy and volume of data.

L{n} Loop sampling and displaying statistics. If followed by a number n, the process sleeps n seconds between each sample. The default value is 5 seconds.

S Display system counters. Without this option, a simplified set of counters is displayed. All counters are always recorded, even without this option.


Examples:

buffers

Take one sample of the non-system statistics.

buffers (sh300c

Loop displaying all counters, recording history and sampling every 300 seconds (5mn). The log file data level corresponding to today is cleared, thus starting a new session.

When looping, buffers polls the keyboard to detect the key "x" to stop or "r" to redraw the screen if it has been disturbed by a message, for instance. Any other key forces buffers to take another sample.

Displaying Log File

Raw display

The history file can be displayed by any access sentence. For example:

sort buffers.log,friday with time >= "11:14:00"

Histograms

The buffers.g command lists the log file as a series of histograms. The syntax is:

buffers.g cntr [day{-{day}}|*] {step {strt.time-{end.time}}} {(option}

cntr Statistic counter name (eg. fflt for the 3rd counter). Must be among the list shown in the table above. If the counter specified is relative to the buffers, percentages of the total buffers are displayed, rather than raw figures.

day Day{s} to list. The day can be one day, expressed either explicitly (monday, tuesday, etc...) or a number from 1 (Sunday) to 7 (saturday). A range of days can be specified by specifying two days separated by a dash (-). If the second day is omitted, Saturday is assumed. The whole week can be listed by using an asterisk (*).

step Specifies the display time step as HH:MM{:SS}. All samples taken within the step are accumulated and averaged. If step is not specified or if the step is 0, or if the step is smaller than the sampling period in the log file, all samples are displayed.

strt.time Starting time. If no starting time is specified, 00:00:00 is assumed.

end.time Ending time. If no ending time is specified, 23:59:59 is assumed.


Options


P Direct output to printer.

Examples:

buffers.g fflt * 01:00:00

List the number of frames faults (disk reads), for the whole week, by step of one hour. In the example below, no history was recorded before Wednesday.

No log for Sunday

No log for Monday

No log for Tuesday

20Feb1991; Wednesday; Ctr=fflt, Step=01:00:00, Range=00:00:00-23:59:59

0 8848 17696 26544 35392 44240 53088 61936
+------+------+------+------+------+------+------+------+----
10:59:28 *************************
11:59:54 ***********************************************************
13:00:25 **********************************************************
14:00:52 ************************************
15:01:18 ***************************
16:01:49 ********************************************************
17:02:22 ***************************************
18:02:55 ******
19:03:32 ***********************************************
20:04:08 *************************************************
21:04:43
22:05:21 ***************************************************
23:05:55 *************

Number of samples : 155
Total : 622070
Average per period : 7.1999 / sec.
Max value : 88481
Peak time : 13:00:25

buffers.g ww monday-friday 00:30 08:00-17:30 (p

List the percentage of write required write required buffers, for the week days only, during business hours, by steps of 30 minutes.


Interpreting Results

After taking a significant sample, list the results with the buffers.g command . The most useful parameters to survey are:


Fflt This measures the number of frame faults. If this number approaches the disk bandwidth as determined by the manufacturer, the system becomes disk bound. Solutions range from increasing the memory allocated to Pick, to changing disks, or reorganizing the Pick data base on separate disks to increase parallelism.

Writes This number should stay about one third to a half of the number of frame faults. It is not 'normal' for a system to do more writes than it reads, under normal operation. If this is not the case, see the section 'Flusher Adjustment' in this article.

Bfail This number should never be non zero. If it is not the case, the memory allocated to Pick is definitely too small.

WqFull This number should not be non-zero 'too often'. If it is the case, and if the number of writes is too big also, there is an abnormal rate of writes. See the section 'Flusher Adjustment' in this article.

Bcolls If this number becomes too high, this indicates that a lot of batch jobs (like selects of big files) are done while other processes are doing data entry. It is also an indicator that indeed interactive jobs are receiving higher priority than batch processes. See the section 'Interactive - Batch Processes' below.

ww This number should never go above 50 % of the whole buffer pool. If this is the case, the flusher is probably not activated often enough. See the section 'Flushed Adjustment' below.

avail This number should never go below 10% of the whole buffer pool. If this is the case, memory must be increased or the flusher must be adjusted.


Flusher Adjustment

The flusher is a background process, started automatically at boot time, which scans the Pick memory and writes back to disk frames which have been modified. It is an important task, not only to ensure that data gets back on disk, but also to make room for new data. Usually, a process reads data, modifies it, but may not need it for a 'long' time. The flusher takes care of writing the data back on disk so that the memory can be reused to read in other data.

This 'cleaning' of the memory is done:


- Periodically, when the disk is not active. If the disk becomes inactive 'for some time', the flusher wakes up and scans the memory writing back all it can unless another a process requires a disk access. This period is defined by the flush statement in the configuration file.

- On demand. When the memory gets 'full', i.e., when a lot of pages in memory have to be written back to disk, the flusher wakes up immediately.


The more often the flusher gets awakened, the more often memory is written back to disk. But this creates disk activity, thus decreasing the disk channel bandwidth available for 'useful' work, and CPU activity, therefore adding system load. Another catch to a high frequency flush is that data which is being modified (workspace, select lists, etc...) may be written several times on disk when only the last time would have been necessary.

The verb set-flush allows changing the flush period (see the section 'TCL commands' in this document. Increase this period, checking with buffers that the 'write queue full' events remains low and that the number of available buffers does not drop too low. Normally, the system is self regulating, increasing the flush frequency in case of high memory usage, so there is no need for a low flush period. 30 seconds should be a high limit.

The configuration file also contains the statement dwqnum which defines the length of the internal write queue. Increasing this queue reduces the probability of the situation in which the flusher awakened on critical demand, thus reducing the number of flushes. The down side to increasing the write queue size is that the flusher works by 'bursts', which may overload the disk channel when this phenomenon occurs. This parameter cannot be changed dynamically, which makes a bit more difficult to monitor.

Interactive - Batch Processes

Pick user processes are divided into two classes, depending on the type of activity they have: interactive processes are processes which typically do keyboard inputs 'frequently'; a batch process is a process which has little keyboard activity, require a lot of disk i/o, and/or is CPU intensive.>The system automatically discerns which type of process is running based on internal statistics.

The System Adminstrator can bias and/or override the default parameters used by the prioritization mechanism. Though not recommended, one can even force any processes, regardless its process activity, to be seen by the system as "interactive", for example. This can be changed dynamically on a per process basis via the set-batch command Also, the TCL command set-batchdly allows the displaying and setting of global values used in the queueing of certain types of process activity.
Syntax
Options
Example
Purpose
Related tcl.what
tcl.set-batchdly
tcl.set-batch
tcl.syschk
tcl.buffers
unix.performance

filename.peqs

Command filename.peqs File/Spooler
Applicable release versions: AP 6.2
Category Spooler (24)
Description a super-Q-pointer used to access spooler jobs.

The "peqs" super-Q-pointer allows access to spooler jobs as if they were standard files.

The following translations are applied on both retrieval and update (note that a DLE is character 16):

Raw Job Simulated File Item

CR,LF AM
DLE DLE,DLE
SM DLE,'_'
AM DLE,'^'
VM DLE,']'

Note also that all trailing null characters are removed when reading a job.

This translation makes it easy to read, modify, and update jobs using BASIC, ED, or the Update processor.

The "COPY" verb can be used to copy jobs into standard files for archival purposes.

The "DELETE" and "CLEARFILE" operations are supported, but only affect unlocked hold files (as with the associated SP-EDIT operation).

An update of an existing, unlocked, hold job updates the job contents without changing the job number. An update of a non-existent job creates a new spooler job with the current SP-ASSIGN options. An update of a locked or non-hold job fails and does nothing.

When reading an item for later update, it is suggested to use a READU. This operation will fail if the job is locked or not a hold file.

If the user updates the "peqs" item "0", then the job is re-spooled with the current sp-assign options to the first available entry number. The user may optionally override the current sp-assign parameters by directly following the "0" in the item id by the new options. Note that there can be no spaces in the item id and that the sp-assign options "c","i","o","rnnn","t" and "?" are ignored.

When using the Update processor to edit "peqs" items, it is suggested to use the "(r" option to better handle control characters and to prevent truncation of trailing attribute marks.

The following pseudo-attributes are defined off of the peqs file. These attributes actually translate from the peqs item-id into the header section of the peqs file (called "hdr:peqs"):

Job The job number
Size The size of the spooler entry
User The user who last modified the job
Pib The PIB of the user who last modified the job
Line The PIB of the user who last modified the job
Date The date of last modification
Time The time of last modification
Permissions Indicates ability to read or write a job
Form The form queue number
Copies The number of copies set
Status The job status information (similar to list-peqs)
Prio Indicates printing priority within a form queue

The "SPOOLER" account holds a super-Q-pointer with the file definition attribute set to "qs". This signals the save processor to dump the both the spooler header information and the spooler job itself to tape. For more information see the spooler.account entry.
Syntax
Options
Example
:list peqs
Page 1    Peqs           10:57:12 12 Sep 1994

peqs

1
2
3

[405] 3 items listed out of 3 items.
:u peqs 3 (r

peqs '3' size = 167
01 .:list md md (p
02 Page 1 md           10:57:59 12 Sep 1994
03
04 md...................
05
06 md
07
08 [405] 1 items listed out of 1 items.
09
peqs '3' size = 167 filed
Purpose
Related filename.hosts
general.super.q.ptr
general.remote
filename.peqs.link
qs-pointer
s-pointer
tcl.sp-assign
tcl.pr-spool-job
spooler.account

boot.error

Command boot.error Definition/Unix
Applicable release versions: AP/Unix
Category Unix (24)
Description describes the boot error codes, displayed in the message: Boot aborted Pick process terminated. Line 0. Code X (0xNNNNNNNN)

where

X is a decimal value
0xNNNNNNNN is the hexadecimal value of X


Name/Value Description/Note

>0 Signal number from 1 to 22. Normally, all signals are caught by the process. However, uncaught signals terminate the process. Normally all Unix signals are caught by the monitor. If this error happens, it is probably because a user-written C function restored the signal handler routine to SIG_DFL.

-n ( 1< n < 1000) Instruction diagnostic error. Optionally, the monitor instruction diagnostics are executed at boot time by the line 0. In case of error, the process is terminated with a negative error code. The absolute value is the instruction diagnostic number.

p_dskerr/-1000 Disk error. Unrecoverable. Check Configuration File. Common cause for this error is a disk size too small (third argument to the disk statement in the configuration file).

p_ioerr/-1001 Terminal I/O error. Using the following command, check read/write permissions to your terminal:
ls -l /dev/ttyXX

p_maxfid/-1010 MAXFID has changed. The monitor required confirmation, but the user decided to abandon. A file restore is necessary. This error happens when choosing the option 'X' on a disk which has no file or has damaged files. Check the Configuration file to make sure the size of the disks or the number of disks has not been changed.

p_sysbase/-1011 SYSBASE has changed. The monitor required confirmation, but the user decided to abandon. This error occurs if the number of PIBS is changed beyond the number allowed by the license. A file restore will be necessary.

p_flushst/-1012 The flush process has terminated, upon receiving a 'logoff' signal.

p_halt/-1013 Monitor HALT. The halt code and the halt address are displayed. Note the code and address.

p_nopib/-1014 No PIB available on the virtual machine. The allowed maximum number of users on the system has been reached. No new user process can be started.

p_twoflsh/-1015 Flush process already active.

p_vabserr/-1016 ABS is invalid or not loaded. Do an ABS restore (option 'A') and retry boot.

p_defect/-1017 Defect table has not been initalized. Delete disk and reload abs and files.

p_defectr/-1018 Defect table can not be read. Disk needs to be reformatted and both abs and files reloaded.

p_bactkey/-1019 An error occured while trying to activate the machine. Possible reasons are:
Installer does not agree with terms.
Invalid activation key entered.
Attempt to activate more pibs than license allows.

p_badsksz/-1020 The size of the disk in the configuation file is invalid. Check the size and change the configuration file.

p_ra/-2001 Global MCB address error. The monitor is incompatible with the Unix version. A different monitor is required for Unix System V Release 4.
Syntax
Options
Example
Purpose
Related maxfid
pib
abs
tcl.config.options
sysbase

basic.%kill

Command basic.%kill C Function/BASIC Program
Applicable release versions: AP/Unix
Category BASIC Program (486)
Description sends the signal specified in "signal" to the process "pid".

All Pick processes normally catch signals for their internal use. The built-in "%pgetpid" allows finding the PID of a process by knowing its port.number (pib). Only "SIGUSR2" should be sent to a Pick process. Other signals are used internally and may cause problems if used out of context.

"SIGTERM" will logoff the Pick process and disconnect it.

"SIGHUP" will logoff the Pick process, but leave it connected to the Pick virtual machine. This behavior can be modified by providing a user writtem signal handler. See the 'trap' command.

"SIGINT" will emulate a <BREAK>, possibly sending the Pick process to the debugger.

Signal numbers are defined in "dm,bp,unix.h signal.h".
Syntax variable=%kill(pid, signal)
Options
Example
Get its pid, and send hangup
* (SIGHUP=1) to it.
pib=32
pid=%pgetpid( pib )
if %kill( pid, 1 ) = -1 then
  print "Cannot logoff process ":pib
end
Purpose
Related tcl.trap
tcl.pid
basic.cfunc
basic.%pgetpid
port.number
basic.cfunction
pid
tcl.kill

tcl.trap

Command tcl.trap Verb: Access/TCL
Applicable release versions: AP/Unix
Category TCL (746)
Description allows a TCL command (signal handler) to be executed upon receiving a specific signal.
The "trap" command traps a system-generated signal generated by the Pick monitor or by the Unix kernel and executes a TCL statement. Without any argument, lists the currently used signals.

"?" displays "help" and the list of user definable signals.

"*" specifies all user definable signals.

If the command is not specified, the signal handler is set to null, thus ignoring the signal. If a question mark (?) is used as a command, the signal handler, if any, of the specified signal is displayed.

If "command" is the keyword "default", the signal is reset to the default listed in the table in example 1. Otherwise, it may be any TCL command, including spaces and options.

Signal handlers are set for the whole virtual machine. When it is desirable to differentiate the signal handlers depending on the user or account, a Pick/BASIC program, a PROC or an environ script must be provided to execute commands selectively. The signal handler is executed by pushing a level. Therefore, the user might see some effect on the terminal (Update processor screen being re-displayed, for instance). If fifteen TCL levels are pushed when the signal occurs, it will not be processed. Signals are always pre-emptive, even upon their own signal handler. For a signal handler to be processed correctly, the process receiving the signal must be logged on.

signame is one of the valid user definable signal names:

"alrm" Stands for "alarm". When a Unix SIGALRM is generated, either by a Unix program called from the Pick process, or by the Pick/BASIC program calling the "%alarm()" C function, a signal is sent to the process. This signal can be used to log the process off, for instance, after a given time. The TCL "alarm" command generates this signal. The default action is to ignore the signal, therefore, an explicit "trap alrm" command must be used.

"dcd" Stands for Data Carrier Detect. If the DCD OFF protocol is active on one port, a HANGUP signal is generated by the terminal Unix driver when the DCD signal is dropped by the modem. The default handler logs the process off. On a network, a more complex program might be necessary to terminate the connection properly and must finish with a 'disc' command. See the section "hangup" for more details about the precautions to take when writing a signal handler for the loss of carrier.

"pwr" Stands for PoWeR off. When an imminent power failure is detected by Unix, the Kernel sends a SIGPWR signal to all active processes on the system. This signal is relayed to the Pick processes. Care must be taken to synchronize the default system handler (defined in the inittab) with the Pick handler. This signal might not be generated, depending on the hardware configuration.

"tdet" Stand for Tape DETach. When a "t-det (u)" command is issued, the process owner of the tape device receives this signal, so that the device can be closed properly. AP versions earlier than 6.1: Ignoring this signal will prevent the "t-det (u)" operation. The default signal handler just detaches the tape. AP versions 6.1 and later (multi-tape) : The handler for this signal is just a comment. It MUST NOT issue any tape command, including a "t-det".

"tdmof" Stands for TanDeM OFf. When the master process terminates, this displays "TANDEM TANDEM ON port.number". The slave terminal TERMINATED receives this signal.

"tdmon" Stands for TanDeM ON. When a process activates TANDEM, this displays "TANDEM STARTED ON port.number", both the master and slave terminals receive this signal.
Syntax trap { [*|signame] { [?|default|command] } }
Options
Example
trap
Sig   Description      Handler
----- ---------------- --------------------------
tdmof Stop tandem      display TANDEM TERMINATED
tdmon Start tandem     display TANDEM STARTED
dcd   Modem hangup     off
mirof Stop mirror      display MIRROR TERMINATED
alrm  Alarm            run dm,bp, useralarm
tdet  t-det (U         display Tape detached with (U)
pwr   Power off        off

 List the current settings

trap * default
 Resets all signals to their default.

trap tdmon
Disables the signal associated with TANDEM.

trap tdmof display @(-13)TANDEM ENTERED@(-14)
Sets the TANDEM ON trap to display a message in reverse video.
Purpose
Related tcl.dcd
basic.%kill
tcl.useralarm
tcl.t-det
basic.%alarm
port.number
tcl.alarm
tcl.tandem
general.hangup

signals

Command signals Definition/Unix
Applicable release versions: AP/Unix
Category Unix (24)
Description examines Unix signals in relationship to the Pick Virtal Machine.

This discussion is intended for experienced Unix programmers to interface Unix applications with Pick or to use Unix process synchronization in a purely Pick environment.
For performance reasons, Unix signals are not used in regular Pick activity. They are used solely to handle exceptions. Diverting signal usage for an application would simply remove nonessential facilities, like the possibility to send a message or to logoff a process. This does not mean that signals can be used freely, though. The Pick Monitor provides a system call to process regular Pick signals inside a customized signal handler, thus combining system and application signal handling.

The following list, details the Pick signal system call and gives some examples of application signal handler.

Signal Usage

The following is a table of the signals currently used by Advanced Pick. Future development may require using more signals.

Advanced Pick uses only System V.3 signals, which are common to more recent Unix versions. Non System V.3 signals are left to their default signal handler (normally SIG_IGN) as set by the system.

Numerical values may vary between Unix implementations. It is very important to use the proper include when writing in C or the include dm,bp,unix.h, signal.h when writing FlashBASIC or Pick/BASIC programs using signals.

Signal Description

SIGHUP Hangup. When received, the process is logged off Pick, but remains connected to the virtual machine. The signal is controlled by the hupcl command in the Pick configuration file. It is normally generated by the TTY device driver when data carrier is lost. This signal can be altered by the TCL command trap dcd command .

SIGINT Interrupt. Generated by the BREAK key and the alternate rtual Machine. break character as defined by the brkchr in the configuration file or by the TCL command set-break . The process is sent to the FlashBASIC, Pick/BASIC, or system debugger, if brk-debug is on or a level is pushed if brk-level is on.

SIGQUIT Quit. Generated by the ESC key or the alternate escape character as defined by the escchr in the configuration file or by the TCL command set-esc . A level is pushed if esc-level is on. If esc-data is on, a signal is still generated, but eventually ignored by the Virtual debugger. The character defined by set-esc will eventually be put in the process input buffer, but it must be emphasized that a noticeable delay can be experienced when inputting this character.

SIGILL Illegal instruction. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGTRAP Trace trap. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGIOT I/O trap instruction. Sends the process to the system debugger with an 'illegal opcode' abort.

SIGEMT Emulator trap. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGFPE Floating point exception. Sends the process to the system debugger with an 'illegal opcode' abort.

SIGKILL Kill. This signal cannot be caught and will terminate the process immediately after doing a logoff. Killing the flusher of a virtual machine will log all processes off and shut down the virtual machine.

SIGBUS Bus error. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGSEGV Segmentation violation. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGSYS Bad argument to a system call. Sends the process to the system debugger with an 'illegal opcode' abort.

SIGPIPE Write to a pipe with no one to read it. The process is sent to the Virtual debugger. Pipes are sometimes used as 'tapes' to do file save. The other end of the pipe can be connected to a serial device, a communication server process... Therefore, when this signal is raised, the write system calls aborts.In an application environment, this signal should be caught and a message sent to the user saying 'Communication Server not Ready', for instance. The write system call would then be interrupted, reported to the save process as a 'parity' error, and the write would be retried until the write finally succeeds.

SIGALRM Alarm clock. The default signal handler is a simple return. Therefore, the signal is active, but does nothing. It can be used in FlashBASIC or Pick/BASIC, with the %alarm() function, do set time outs around critical sections. This signal can be altered by the TCL trap alrm command.

SIGTERM Software termination signal. This signals terminates the Pick process, leaving it logged on, but disconnected. This signal 'freezes' the Pick environment. If the process is restarted, execution will resume where it stopped. Normally, this signal should be preceded by a SIGHUP to log the process off.

SIGUSR1 User-defined signal 1. Not used. Can be used freely by the applications.

SIGUSR2 User-defined signal 2. Force the process to examine its current state, possibly changing it. This signal is used for Pick message, by the TCL logoff , TCL , END commands. Sending this signal out of context will cause no harm. This should be the way, for instance, to wake up a process waiting in a %pause() system call. This signal can be used by applications, provided they call the Pick signal handler inside their customized signal handler. See the section about the examples below.

SIGCLD Death of a child. Not used.

SIGPWR Power fail. When received, the process is logged off Pick, but remains connected to the virtual machine. The behavior of the system depends on how the hardware generates this signal. If there is no battery back-up, it is unlikely that the virtual machine will be brought down gently. The system usually change its running state, which will control what happens. A ap - k command should be inserted in the appropriate shell script associated to the new run level. This signal can be altered by the TCL trap pwr command.


Pick Signal System Call

The Pick monitor provides a system call to inform the Pick Virtual environment of an incoming signal. This C function is normally called by the default signal system handlers, but it can be called by an application signal handler too.

This function is defined as follows:

#include "/usr/lib/pick/include/sigmon.h"

void sigmon( code )
int code;

code is the action code, as described in the following table. Note some functions do not return to the caller .


Code Value/Description
db_slcout 0/No operation. Simply forces the process to examine its current state. This function must be called by the SIGUSR2 signal handler.

db_privop 7/Privileged opcode. Sends the caller to the system debugger. This call does not return to the caller. This call can be used to abort a C program, even if not called from a signal handler.

db_break 10/Interrupt. Sends the process to the FlashBASIC, Pick/BASIC, or system debugger. This function must be called by the SIGINT signal handler. Going to the system debugger is not immediate. Normally, the process will enter the debugger (or push a level) when the signal handler terminates.

db_esc 12/Quit. Pushes a level . This function must be called by the SIGQUIT signal handler. Normally, the process will push a level when the signal handler terminates.

db_logoff 14/Log off. This function is normally called by the SIGHUP handler. It can be called by other signal handlers as part of the application (like SIGALRM for instance, to log off a process after a given time).

db_pwrdown -1/Disconnect. The process is disconnected from the virtual machine, but remains logged on.


Examples

This sections shows some simple examples of using signals in a Pick application, or cooperating with Unix applications. All these examples require writing a C signal handler, which must be linked with the Pick monitor, as detailed in this document.

Time out

The purpose is to write a signal handler which will log the user process off if there is no activity for a given time. It is assumed the user is in a FlashBASIC or Pick/BASIC application, waiting input.

- Write the following signal handler and function

setalrm.c:

#include <signal.h>
#include "/usr/lib/pick/include/sigmon.h"

myalrm(){
/* signal handler. When activated,
log the process off */
sigmon( db_logoff );
}

/* Set the new signal handler
Set the signal handler to
the application signal handler.
Return the address of the
previous signal handler, so
that the basic application
can remove the time out
*/

void (*setalrm())(){
return signal(SIGALRM, myalrm );
}
<

- Compile the previous program and incorporate it to the Pick monitor, by typing, in the dm account:

addbi setalrm signal
ar vru libgm.a setalrm.o
make -f /usr/lib/pick/Makefile

Note this incorporates the user-defined function setalrm() as well as the system call signal() not normally shipped with the Monitor. The latter will be extracted from the standard C library. The %setalrm function can then be called from FlashBASIC or Pick/BASIC.

- Enter the following 'application' program

*
* Reprogram the alarm handler,
* keeping the previous system
* handler
* Note the function pointer
* returned by the function
* is treated as a pointer to a character.

include dm,bp,unix.h signal.h
old$alarm = (char*)%setalrm()
*
loop
* Set the alarm to 10 minutes
* From now on, if the user
* doesn't enter a command before
* 10 minutes, the process will
* be logged off.
%alarm(600)
* .. display application entry screen here
crt 'Command : ':
input command
while 1 do
begin case
case command = 'a'
* ... put command 'a' routine
case command = 'end'
print 'end of the application'
* disable the alarm and set the default alarm
* handler back to the default.
%alarm( 0 )
%signal( SIGALRM, (char*)old$alarm )
chain 'off'
end case
repeat

Note that, in the example above, if the alarm was not disabled and if the signal handler is not reset to the default, the alarm clock would have continued to run, even if the process went back to TCL, thus logging it off later. A small FlashBASIC or Pick/BASIC program, just rearming the alarm can be written to incorporate the alarm in PROCs or menus to achieve the same time out capability in TCL.

Synchronizing Two Pick Processes

On conventional Pick implementations, synchronizing two Pick processes is done either through polling for the existence of a file or, a little better, by using a FlashBASIC or Pick/BASIC LOCK instruction. On most implementations, however, the FlashBASIC or Pick/BASIC LOCK instruction itself involves, internally, a polling, thus making the waiting process to consume cpu resource. By using signals, it is possible to have a process waiting for a signal to occur (a BREAK, logoff or a signal generated by another process, possibly a Unix process or a Pick process from another Pick virtual machine) without any cpu consumption.

The following example has one phantom task waiting for a signal sent by 'somebody' to go read a message in a pipe where the 'somebody' has deposited a message. This communication with message, probably, would be better achieved through Unix messages, but this is merely an example. Also, this is a one to one communication. Multiple partners in this scheme would require semaphores. The server process makes itself visible to the entire system (Pick and Unix) by writing a temporary file which contains its process id, which other processes use to send a signal to it.

The (simple) signal handler uses SIGUSR1 . The 'message' is in ASCII, containing a header and some data. The message has the following format:

+---+---+--------//-----------+
| |NL | +
+---+---+--------//-----------+
| | |
| | +- Data (code dependant)
| +------------ New line (discarded)
+---------------- Command code.
T : Terminate
M : Message
R : file receive
- Enter the following C signal handler:


setusr1.c:

#include <signal.h>
#include "/usr/lib/pick/include/sigmon.h"

myusr1(){
/* Just reset the signal for next time */
signal( SIGUSR1, myusr1 );
}

/* Set the new signal handler
Set the signal handler to the
application signal handler.
Return the address of the
previous signal handler
so that the basic application
can remove the time out
*/

void (*setusr1())(){
return signal(SIGUSR1, myusr1 );
}

- Enter the following phantom task code in the item dm,bp, pserver :

pserver
001 !
002 * Example of a file server running as
003 * a phantom
004 * Commands are received on a named pipe.
005 *
006 include dm,bp,unix.h signal.h
007 include dm,bp,unix.h mode.h
008 include dm,bp,unix.h fcntl.h
009 *
010 * Defines:
011 equ NL to char(10) ;* UNIX line terminator
012 equ AM to char(254)
013 equ PIPE to "/dev/mypipe"
014 equ BUFSIZE to 10000 ;* max message size
015 *
016 char buffer[BUFSIZE]
107 *
018 * Remove temporary file
019 execute '!rm -f /tmp/pserverid'
020 *
021 restart:*
022 *
023 * Open the communication pipe in read
024 * only, no wait on read
025 * If open error, stop, sending a
026 * message back to the originating
027 * process.
028 fd=%open(PIPE, O$RDONLY+O$NDELAY)
029 if fd<0 then
030 stop 1,"Cannot open '":PIPE:"'. Error ":system(0)
031 end
032 *
033 * Do not allow BREAK from now on
034 break off
035 *
036 * Create the temporary file which
037 * contains our pid, so that
038 * everybody on the system will
039 * know the server id
040 mypid=%pgetpid(-1)
041 execute "!echo ":mypid:" > /tmp/pserverid"
042 *
043 * Reprogram the alarm handler,
044 * keeping the previous system handler
045 * Note the function pointer returned
046 * by the function is treated as
047 * a pointer to a character.
048 old$usr1 = (char*)%setusr1()
049 *
050 * Go try read the pipe. If there is no
051 * message, the signal we received
052 * was not an application one. May be
053 * somebody tried to log us off
054 * so close the pipe, restore the
055 * signal and wait a bit. If we come
056 * come back, was a false alarm. Restart.
057 loop while 1 do
058 * Wait for a signal
059 %pause()
060 *
061 * Read the pipe
062 n=%read(fd, buffer, BUFSIZE )
063 *
064 begin case
065 case n=-1
066 * IO error
067 gosub terminate
068 stop 1,"PSERVER: IO error ":system(0)
069 case n=0
070 * Pipe is empty...
071 * The signals we got is not
072 * the one we expected. Enable
073 * break to allow for a
074 * possible
075 * logoff, and restart
076 gosub terminate
077 sleep 1
078 goto restart
079 case 1
080 * Got something (n is the
081 * number of byte)
082 * The 1st byte is a code,
083 * the second a new line
084 * (discarded)
085 code=buffer[1,1]
086 message=buffer[3,n-2]
087 * Go handle the message
088 gosub do$it
089 end case
090 repeat
091 *
092 do$it:*
093 begin case
094 case code='T'
095 * Terminate
096 gosub terminate
097 stop 1,"PSERVER: Terminated"
098 case code='M'
099 * Message.
100 execute "msg * PSERVER: ":message
101 case code='R'
102 * Receive a file. The message is
103 * full filename (NL) item (NL)
104 * text
105 convert NL to AM in message
106 filename=message<1>
107 item=message<2>
108 message=delete(message,1)
109 message=delete(message,1)
110 open filename then
111 write message on item
112 close
113 end else
114 execute "msg !0 PSERVER: '":filename:"' is not filename"
115 end
116 end case
117 *
118 return
119 *
120 * Clean everything
121 terminate:*
122 %close(fd)
123 %signal( SIGUSR1, (char*)old$usr1 )
124 execute '!rm -f /tmp/pserverid'
125 break on
126 return
127 *
128 end


- Create a communication pipe by doing the following from TCL:

su (must be superuser to do the following )
mknod /dev/mypipe p
chmod 0666 /dev/mypipe
exit (Get back to TCL)

- Compile and catalog the FlashBASIC or Pick/BASIC program, compile the C program and add it to the built in function list by:


addbi setusr1
cc -c setusr1.c
ar vru libgmu.a setusr1.o

To be able to use the customized monitor with a phantom process, it is necessary to shutdown and to move the customized monitor to the common directory /usr/bin while being in single user mode.

shutdown
make -f /usr/lib/pick/Makefile
init s (wait for the system to effectively go to single user)
mv /usr/bin/ap /usr/bin/ap.save
mv ./ap /usr/bin
init 2 (go back to multiuser)

Restart the Pick virtual machine.

- Create the phantom task server:

z pserver

- The server is now waiting for a signal to read the message. Normally, this would be done by another process (Pick or Unix), but, just to test this, the following shell script allows sending messages, small Unix files or terminate the server:

snd:

# Send a command to pserver through a pipe
PIPE=/dev/mypipe # the communication pipe
SERVERID=/tmp/pserverid # where the server puts its PID
COMMAND=$1

# Make sure the Pick server is active
if [ ! -r $SERVERID ]
then
echo Pick server is not active
exit 1
fi
# Get the server pid
PSERVERID=`cat $SERVERID`

# Send it a signal 0 to test its existence
kill -0 $PSERVERID
if [ $? != 0 ]
then
echo Pick server is not active. PID is not valid.
exit 1
fi

# Parse command
case $COMMAND in
"r"|"R")
# Receive a file : snd r unix.file
# pick.file item
echo "Rn$3n$4n~`cat $2~`" > $PIPE
;;
"m"|"M")
# Send a message: snd m <text>
shift
echo "Mn$*" > $PIPE
;;
"t"|"T")
# Terminate
echo "Tn" > $PIPE
;;
*)
echo "usage: snd r unix.file pick.file item"
echo " snd m message"
echo " snd t"
;;
esac

# Wake up the server by sending SIGUSR1
# -30 for AIX; -16 for SCO, DG
kill -30 $PSERVERID

- Test the server by the following commands (from Shell):

snd m Hi there

This command should send a Pick message to all Pick users.

snd r /etc/inittab dm,pointer-file, inittab

This command should send the Unix file /etc/inittab into the Pick item dm,pointer-file, inittab .

snd t

This command should terminate the server process.
Syntax
Options
Example
Purpose
Related

spooler.account

Command spooler.account Definition/Spooler
Applicable release versions: AP 6.2
Category Spooler (24)
Description account holding a file called "Peqs" which is used to reference spooler jobs as normal Pick items.

The data section of this file is a "QS" pointer to the "peqs:" driver. The "QS" signals the save processor to dump booth the spooler header information and the spooler jobs to tape. In general, this is the only account that should contain a "QS" pointer to the peqs: driver. All other accounts should contain simple "Q" pointers.

At the present time, the spooler account does not serve any purpose beyond this. The "QS" super-q-pointer was not put into dm because confusion could result if the peqs file was restored accidently.

It is now possible to restore spooler jobs from previous file-saves. Two options are available; individual items or the entire file can be restored to a temporary file, then copied to the spooler as needed, or the entire contents of the previous spooler can be overlaid on the current spooler.

Note that the save must be done with the "E" option to save spooler jobs.
Syntax
Options
Example
Purpose
Related filename.peqs
general.super.q.ptr

up

Command up Introductory/Update Processor
Applicable release versions:
Category Update Processor (113)
Description UP is a dictionary-driven, full-screen editor and data processor. Used with the Output processor (OP), it operates as a document processor.
UP can be used to view, create, and manipulate file items. UP facilitates editing of text, dictionaries and programs, as well as data files (remember, everything in Pick is an item in a file). When used as a data processor, attribute-defining items in the file’s dictionary are employed to verify and translate data as it is entered and retrieved.
Pick/BASIC subroutines can be called from dictionaries allowing absolute control of all data entry using the Update processor and dictionaries. Without any attribute-defining items specified, UP functions as a full-screen editor.
When invoked, UP copies the specified item to a workspace and displays as much of the item on the screen as it can. UP places the cursor at the upper left corner of the item (top) on the first character of the first value of the first attribute and waits for your input.
Once the item has been loaded, any character you type will overwrite whatever is on the screen. Control keys are used to perform editing functions, but as long as the control key is not down, all characters are entered as typed. An automatic word-wrap feature moves whole words to the next line as they are typed when you overrun the end of the current line. An optional spelling checker beeps and rejects your input when you type a character that does not lead to a legal word.
Text is normally entered in the insert mode (<Ctrl>+r is used to toggle between the insert and overtype mode). While in the input mode, the return/enter key (<Ctrl>+m) creates a new attribute/paragraph. When in the overtype mode, that same key does not create a new attribute but instead goes to the next attribute. The default mode is overtype.
UP commands begin with a control character formed by simultaneously pressing the <Ctrl> key and one of the alpha keys. Some UP commands require more command characters, while others require text input.
Until the item is saved, changes made using UP have no effect on the actual item in the file -- only UP workspace is changed. The item can be exited at any time without filing, by typing <Ctrl>+xe>, and the item in the file will not change.

Using UP as a Text Editor
In the absence of any attribute list, UP functions as a text editor. An attribute list generates a data entry screen with whatever audits and transformations are defined in the corresponding dictionary. The text edit form is to specify just the file name and item list (no attribute list) and if no macro is present on the file-defining item, the raw item will be presented. Refer to the entries update, up, and u for more niformation about the update commands.
update file.reference {item.list} { (options) }
up
u

Cursor Movement
The cursor is the underline or block which moves around the screen when characters are typed. Cursors can have various forms depending on the terminal: highlighted, blinking, reverse video, etc. In all cases, the cursor indicates where the next character typed is displayed on the screen.
Cursor movement commands are used to position the cursor anywhere in the item without altering the text. The cursor actually moves on the CRT screen. And, since the screen is only a window into the item, the cursor may be moved off the screen forcing a screen redisplay (scrolling).
<Ctrl> +

k Moves the cursor forward (right) one character.
j Moves the cursor back (left) one character.
n Moves the cursor down one line.
b Moves the cursor up one line.
i Moves the cursor forward to the next tab stop in the line.
u Moves the cursor forward (right) one word.
y Moves the cursor back (left) one word.
f Moves the cursor forward to the next sentence.
d Moves the cursor back to the beginning of the sentence.
g Moves the cursor to the end of the current paragraph.
m Moves the cursor to the beginning of the next paragraph(attribute) if in overtype mode. Creates a new attribute if in insert mode.
t Moves the cursor to the top of the current item.
z n Moves the cursor to the top of the next screen.
z y Moves the cursor to the top of the previous screen.
z h Moves the cursor to the first line of the next screen, then moves the display up 12 lines.
z q Moves the cursor to the first line of the next screen, then moves display up one quarter of a screen.
z e Move the cursor to the end of the current item.
z a Redisplay the screen with the current line at the top of the screen.
z b Redisplays the screen with the current line at the bottom of the screen.
z p Redisplays the screen.
z numeric Goes to the specified line number.


Overtype and Insert Modes
When UP is first entered, it is in overtype mode. This means that characters typed overwrite the characters on the screen. Insert mode is used to insert new text just in front of the text beginning at the cursor. When text is entered in the insert mode, the following text is "opened" and shown on the next line until insert mode is exited or a cursor movement command is typed.
The letter "O" is displayed at the top right corner of the screen when in overtype mode; the letter "I" is displayed when in insert mode. As text is entered in either mode, UP word-wraps the text as necessary. That is, if a character string is longer than the remaining space on the current line, the entire string is moved to the next line. This means you can type continuously within a paragraph (attribute) without pressing the <Ctrl>+m.
<Ctrl>+r Toggle between overtype and insert modes.

Paragraphs
To create a new paragraph in the middle of existing text, enter the insert mode and type <Ctrl>+m. This terminates the current paragraph and prompts with the next attribute number. If the cursor is at the end of an item, <Ctrl>+m creates a new paragraph whether or not in input mode. In the absence of a dictionary definition, this is how UP is used as a word processor; each attribute is a paragraph.
<Ctrl>+m Same as <Return>. Always moves the cursor to the beginning of the next attribute. If in insert mode or at the end of an item, <Ctrl>+m creates a new paragraph. If UP is being controlled by a dictionary, <Ctrl>+m does not create a new attribute mark, rather the cursor moves to the next attribute.

Inputting Text Using the Spelling Checker
UP uses a spelling checker to verify text as it is entered. The spelling checker looks at each character to see if those typed so far make a legal word or may become a legal word. The words used by the spelling checker are kept in the words file in the dm account.
In order to activate the spelling checker, a q-pointer must be present on the current account and an index must be generated on attribute 0 of the words file. If an error is detected, the terminal beeps and does not display the last character typed. If an incorrect letter is typed, type the correct one and continue entering data.
To view the words immediately adjacent to the misspelled word in the words file, use <Ctrl>+u to get the next legal word or <Ctrl>+y to get the previous word. Otherwise, press one of the following:
<Ctrl> +
a Override spell checker and accept the characters.
a a Insert the word into the words file and continue.
a a a Turn off spelling checker.
z s Toggle the spelling checker on and off from any point in the item. If the spelling checker is on, <Ctrl>+zs toggles it off; if the spelling checker is off, <Ctrl>+zs toggles it on.


Deleting and Undeleting Text
As text is deleted, the remaining characters in the paragraph are moved to the left. The Cut and Paste commands also delete text.
<Ctrl >+
l Deletes the character under the cursor and moves the text left.
o Deletes characters from the cursor position to the end of the word including the character under the cursor.
e Deletes from the character under the cursor to the end of the sentence.
z o Deletes the characters from the cursor to the end of the paragraph (attribute).
z d Deletes the characters from the cursor to the end of the item.
z z Undo the last delete or data change if the change was made by using one of the control delete keys.


Exiting Items
The <Ctrl>+x commands offer different methods for exiting an item. <Ctrl>+x signals to exit this item and perform one of a series of options. For example, an item can be exited and the information filed (saved), or the item can be exited without the information being filed.
If an item is exited without being filed, the changes made during the editing session are not saved. To save the changes, the item must be filed. Several of the options that exit an item do not file it. If changes have been made to an item during the current editing session and an option is selected that exits the item without filing it, the system double-checks with the user to make sure that the changed information is not to be saved.
All UP exit commands are made up of a minimum of two characters. When the <Ctrl>+x is pressed, the current size of the item, file name, and item-id are displayed on the top line of the CRT. UP waits for an additional command.
<Ctrl>+x+
b Exits the item and goes back to the previous item in the item list. If there is no previous item, the terminal beeps and remains in the current item.
c Files the current item then compiles and catalogs it. This option is used with Pick/BASIC programs.
e Exits the item without filing it.
f Files the item, then exit it.
i {(file.reference}{item.id}
Renames and files the new item. This command prompts for a standard file item specification where the item is copied. After the file item specification is entered, the system asks if the old item from which the new item was created, is to be deleted. Enter <Ctrl>+y to remove the old item; otherwise, the item is unchanged.
k Exits the item and returns to calling process. If editing with a select list, the select list is terminated.
n Exits current item and creates a new null item. If a name is not entered when the new item is filed, it can be named using the <Ctrl>+xi> command. If there is no id processing code, UP uses the current date concatenated with a system-wide sequence number as the item-id.
o Exits and deletes the item.
p Files the item and prints it using the Output processor (OP).
r Files the item, then compiles and runs it if compilation was successful.
s Files (save) the item and remains in UP with the current item.
x Exits the item without filing it.


Searching and Replacing Text
The search commands in UP offer the capability to search for text, search for text and replace the text, and search for text and, once the text is found, determine whether or not to replace it.
<Ctrl >+
a string <Ctrl>+m
Search for the first occurrence of the specified string. If a match is found, the cursor is displayed on the first character of the matched string; otherwise, the cursor remains at the current location. When <Ctrl>+a is pressed, UP prompts for the search string at the top of the screen.
The search string is not case sensitive. To search for letters that are case specific, enclose the string in single- or double-quotation marks. If the string itself contains quotation marks, enclose those quotes in quotes.
a Search again for the string specified by the last search command. If a search string is not specified, the terminal beeps and displays a message.
a string1 <Ctrl>+r string2 <Ctrl>+n
Search for and replace every occurrence of string1 with the string2 from the current cursor position to the end of the item. When <Ctrl>+r is pressed, UP prompts for the replacing string. After entering the new text press <Ctrl>+n to indicate all occurrences.
The text is replaced as entered. If the replacement is at the beginning of a sentence, the initial letter is replaced as an upper-case letter. To specify an exact replacement of upper- and lower-case letters, enclose the text in single or double quotation marks.
a string1 <Ctrl>+r string2 <Ctrl>+m
Search for the first occurrence of string1. If a match is found, the cursor is positioned on the first character of the match and UP waits for one of the following commands:
Ctrl +
a Do not replace string1. Search again for next occurrence.
n Replace string1 with string2. Replace all further matches.
r Replace string1 with string2. Search again for string1.
x Stop search. Return to edit mode.

Cutting and Pasting Text
Cut commands are used to move or copy data from one place in an item to another place in an item. Text can be cut and deleted or cut with the original left in place (copied). After the text is cut, it is placed in the cut buffer replacing the previous contents of the cut buffer. The cut text in the cut buffer can be pasted in the current document or it can be pasted in a specified item in a file. Text can also be pasted from a specified item and file.
<Ctrl >+
c d Mark the beginning location of the text to be cut and deleted.
c l Mark the beginning of text to cut and leave (i.e., does not remove the cut from the current location in the text and makes a copy for the cut buffer).
c c Mark end of text to cut or copy from the beginning cut and puts the text in the cut buffer.
c p Paste contents of cut buffer at current cursor position. Once text has been put in the cut buffer it remains there for the duration of the current update session in the UP workspace.
c r {(file.reference}item.id {n{-m}} <Ctrl>+m
Read contents of specified item and paste at current cursor location. The optional n parameter is an integer that specifies the first attribute to copy; the optional m parameter is an integer that specifies the last attribute to copy. If a range is not specified, all attributes from beginning to the end of the item are copied.
c w {(file.reference }item.id <Ctrl>+m
Write the contents of the current item cut buffer to the item specified by item.id.


Prestore Commands
Prestore commands are used to store and execute a sequence of UP commands. These commands can be used during the current update session or saved as an item in a file and recalled for use in subsequent update sessions. Prestore commands can contain both UP commands and text. To specify a UP command, enter the letter portion of the editing command without pressing the <Ctrl> key. To specify text, enter the text enclosed within single/double quotation marks.
Prestores can be created in the prestore buffer or they can be created as an item in a file. Prestore items can exist in any file and must have a p in the first attribute. The following attribute values will contain prestore commands and text.
<Ctrl > +
p Execute the current command in the prestore buffer. If the prestore buffer is empty, displays the next screen of the item being edited (default).
z l Create or edit a prestore command in the prestore buffer. Most UP commands are available to input and edit the prestore buffer.
z r {(file.reference}item.id <Ctrl>+m
Load specified item into the prestore buffer but do not execute it. The first attribute must be the character p.
z r {(file.reference}item.id <Ctrl>+p
Load the specified item into the prestore buffer and execute it. The first attribute in the item must be a p. The default file is the master dictionary.
z w {(file.reference}item.id <Ctrl>+m
Write the prestore buffer into the specified item. The character p is written as the first attribute of the item. The default file is the master dictionary.


Using UP as a Data Processor
update file.reference item.id attribute.list (options
up
u
When UP is called with an attribute list it functions as a data processor. Each attribute name in the UP statement becomes a data entry location on the screen identified by the named attribute. The attribute names are listed along the left of the screen in half-intensity. Dependent attribute names are displayed horizontally across the screen with the controlling attribute. Each attribute-defining item creates a cell on the screen through which data may be accessed and modified under the control of dictionary processing codes. Since a Pick/BASIC program may be called using a processing code, complete application flexibility is provided.
The cursor can be moved, using the previously defined cursor movement commands, from attribute name to attribute name. (Some of the commands function in a different manner. These are defined below.) Data entered or changed next to an attribute name is filed in that attribute when the edited item is saved.
Stored data is subject to output conversions defined in attribute-defining items in the file dictionary prior to display. Data entered using UP is subject to input conversions defined prior to storage on disk. By invoking a single UP command, an entire data access and update screen can be defined. When that command is saved as a macro, it can be recalled any time for file access.UP can be used to scan data using file indexes. When attributes are indexed using the create-index verb, UP can be used to cruise on the index.
The key to cruising is understanding the Balanced Tree (b-tree) indexing feature of Advanced Pick. A b-tree is a structure used to keep an ordered list, such as names, and provides the ability to search through the list very quickly with a minimal number of disk I/Os. Any attribute in a file can contain an index. Indexes are defined using a-correlatives. Once the b-tree has been defined, the system automatically maintains the index.
b-trees allow access to data in ways not before possible. The new access capabilities are cruising (using the file index), cruising (using the file related index), zooming, and double clutching.
Cruising using the file index (local file) is the ability to move from item to item in the current file. You can move forward (with <Ctrl>+f or backward (with <Ctrl>+d through the items on any indexed attribute.
Cruising using the related file index (remote file) provides the ability to view valid data from another file. For example, a sales order file could have an attribute called name which points to the entity file. From the orders file one could view the valid names in the entity file and select the one desired.
Double-clutching means the combined abilities of searching the remote file for valid values and also searching the local file for specific items. For example, in an order file the name attribute could have an index pointing to the entity file allowing for searching of valid people. A local index on the name attribute would allow for searching for all of the orders already on file for that person.
Zooming refers to moving through a defined door to another file. Once in the other file, the user has the option to cruise from item to item in the new file, return to the original file or zoom through a door into yet another file. <Ctrl>+g is the command to zoom to another file.
When the cursor is positioned in a cell belonging to an indexed attribute, the commands <Ctrl>+d and <Ctrl>+f can be used to display the data associated with the item containing an adjacent value in the indexed attribute. The command <Ctrl>+f causes the data associated with the next value in the index to be displayed. The command <Ctrl>+d causes the data associated with the previous value in the index to be displayed.
For example, if an item containing customer name and order number indexed attributes is being displayed on the screen and the cursor is at the order number prompt, the <Ctrl>+f command will display the data associated with the next order number in the order number index. If the cursor is residing adjacent to customer name, <Ctrl>+f causes the data associated with the next customer name in the index to be displayed and customer name is the key. All of the data in the new item associated with the attribute names displayed on the screen is displayed.
When the input conversion attribute in an attribute-defining item specifies an index pointing to another file, that file can be accessed (zoomed to) by using the <Ctrl>+g command. This command pushes the current process one level and accesses the item-id in the pointed to file that matches the current value in the cell where the cursor resides. Attributes to be displayed with that item-id must be specified in attribute 15 of the original attribute-defining item. Several logical views may be defined as macros in Attribute 15 of the d-pointer.
A FlashBASIC or Pick/BASIC program may be called to specify the actual logical view to use for the current data item. It does this by assigning the logical view number into the pseudo-variable "Access (18)." If no attributes are specified, the entire item is displayed. After viewing the new item the original item can be returned to the screen by a file exit command such as <Ctrl>+xe>.
When the input conversion attribute in an attribute-defining item specifies a second index as well as one pointing to another file, the commands <Ctrl>+u and <Ctrl>+y allow the user to cruise on indexes in the pointed to file. The attribute pointed to in the second file must have been previously indexed by the create-index verb. <Ctrl>+u shows the next attribute value in the pointed to file. Only this value is updated and it is shown in the cell where the cursor is residing. What is displayed is subject to the conversions specified in the dictionary of the first file. The command <Ctrl>+y shows the preceding item-id in the pointed to file. In order for UP to function in this manner, the attribute-defining items must contain the proper index processing codes. The input conversion attribute (att 14) of the attribute-defining item in the file dictionary is where they are specified.

Overloaded UP Commands for Data Files
Most UP commands work the same whether or not dictionary attributes are in control. Certain commands function differently when certain conditions are met. These commands provide the functionality for browsing on indexes. The cruising commands can be used in a double-clutching fashion by specifying the index for the current file and a second index for another file. <Ctrl>+u and <Ctrl>+y cruise on legal instances in the pointed to file staying in the same item. <Ctrl>+f and <Ctrl>+d cruise on other items in the same file using the index for the attribute as a guide.
<Ctrl> +
g When in an attribute which indexes to another file or has a translate code in the input processing code, this command pushes the current process one level and calls UP again with the item pointed to in the new file as the argument. If the macro attribute (attribute 15) in the primary file attribute definition item is used, this list is appended to the update statement. This is known as "zooming".
f On an indexed attribute, the sentence forward command goes to the next sequential index and gets the corresponding item into the UP workspace.
d On an attribute with an index, the sentence backward command goes to the previous sequential index and gets the corresponding item into the UP workspace.
u If the attribute indexes to another file, the word forward command gets the next sequential item from the pointed to file as the value for this attribute.
y If the attribute indexes to another file, the word backward command gets the previous sequential item from the pointed to file as the value for this attribute.
Syntax
Options
Example
Purpose
Related up.a
up.sc.a
up.sc.aa
up.sc.aaa
up.arm
up.arn
up.b
up.c
up.options.c
up.cc
up.cd
up.cl
tcl.compile-run
up.correlative
up.correlative.adi
up.cp
up.cr
cruising
up.cut.paste
up.cw
up.d
up.data-entry
up.delete.text
double.clutching
up.e
up.exit.item
up.f
up.g
up.h
hotkeys
up.i
up.options.i
access.id-prompt
up.input-conversion.adi
up.input-conversion.fdi
up.insert.mode
up.j
up.k
up.l
up.options.l
up.m
up.n
up.o
up.only
up.options
up.output-conversion.adi
up.overtype.mode
up.p
up.prestore
processing.codes
up.r
up.options.s
up.search.replace
tcl.spelling.checker
up.t
up.u
up.commands
update.processor
up.v
up.w
up.x
up.x0
up.x1
up.x2
up.x3
up.x4
up.x5
up.x6
up.x7
up.x8
up.x9
up.xb
up.xc
up.xe
up.xf
up.xi
up.xk
up.xl
up.xn
up.xo
up.xp
up.xr
up.xs
up.xx
up.y
up.z
up.znumber
up.za
up.zb
up.zc
up.zd
up.ze
up.zg
up.zh
up.zl
up.zn
up.zo
zooming
up.zp
up.zq
up.zr
up.zs
up.zt
up.zw
up.zy
up.zz
up.zx
up.macro
updte.processor

tcl.kill

Command tcl.kill Verb: Access/TCL
Applicable release versions: AP/Unix, AP 6.0
Category TCL (746)
Description sends a Unix signal to a Pick or Unix process.

Signals can be specified by their usual names, rather than their number, and Pick processes by their port numbers instead of Unix process-ids ("pid's").

signalno is the optional signal number in decimal. If not specified, "SIGTERM" is sent.

signame is the optional signal name. Among the valid signal lists are: {SIG}TERM, {SIG}HUP, and {SIG}USR2. If not specified, SIGTERM is sent.

p pib indicates the Pick pib (port.number), prefixed by the letter "p".

'kill' checks that none of the specified processes have a process-id of 0 (zero), which would mean 'kill all processes in the group', usually resulting in an abrupt shutdown of the Pick virtual machine.
Syntax kill {-[signo|signame] } [pid|ppib] { [pid|ppib] ... }
Options
Example
kill p17
Kills the (Unix) process associated with port 17.

kill -sigalrm p33 7143
Sends a sinal, "sigalrm", to the Unix process associated with port 33 
and to the Unix process whose process-id is 7143.

kill -1 p0
Sends a "sighup" to port 0.
Purpose
Related port.number
tcl.ap.unix
pid
tcl.pid
tcl.psr
basic.%kill

signals

Command signals Definition/Unix
Applicable release versions: AP/Unix
Category Unix (24)
Description examines Unix signals in relationship to the Pick Virtal Machine.

This discussion is intended for experienced Unix programmers to interface Unix applications with Pick or to use Unix process synchronization in a purely Pick environment.
For performance reasons, Unix signals are not used in regular Pick activity. They are used solely to handle exceptions. Diverting signal usage for an application would simply remove nonessential facilities, like the possibility to send a message or to logoff a process. This does not mean that signals can be used freely, though. The Pick Monitor provides a system call to process regular Pick signals inside a customized signal handler, thus combining system and application signal handling.

The following list, details the Pick signal system call and gives some examples of application signal handler.

Signal Usage

The following is a table of the signals currently used by Advanced Pick. Future development may require using more signals.

Advanced Pick uses only System V.3 signals, which are common to more recent Unix versions. Non System V.3 signals are left to their default signal handler (normally SIG_IGN) as set by the system.

Numerical values may vary between Unix implementations. It is very important to use the proper include when writing in C or the include dm,bp,unix.h, signal.h when writing FlashBASIC or Pick/BASIC programs using signals.

Signal Description

SIGHUP Hangup. When received, the process is logged off Pick, but remains connected to the virtual machine. The signal is controlled by the hupcl command in the Pick configuration file. It is normally generated by the TTY device driver when data carrier is lost. This signal can be altered by the TCL command trap dcd command .

SIGINT Interrupt. Generated by the BREAK key and the alternate rtual Machine. break character as defined by the brkchr in the configuration file or by the TCL command set-break . The process is sent to the FlashBASIC, Pick/BASIC, or system debugger, if brk-debug is on or a level is pushed if brk-level is on.

SIGQUIT Quit. Generated by the ESC key or the alternate escape character as defined by the escchr in the configuration file or by the TCL command set-esc . A level is pushed if esc-level is on. If esc-data is on, a signal is still generated, but eventually ignored by the Virtual debugger. The character defined by set-esc will eventually be put in the process input buffer, but it must be emphasized that a noticeable delay can be experienced when inputting this character.

SIGILL Illegal instruction. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGTRAP Trace trap. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGIOT I/O trap instruction. Sends the process to the system debugger with an 'illegal opcode' abort.

SIGEMT Emulator trap. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGFPE Floating point exception. Sends the process to the system debugger with an 'illegal opcode' abort.

SIGKILL Kill. This signal cannot be caught and will terminate the process immediately after doing a logoff. Killing the flusher of a virtual machine will log all processes off and shut down the virtual machine.

SIGBUS Bus error. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGSEGV Segmentation violation. Sends the process to the system debugger with an 'illegal opcode' abort. Used for assembly single stepping on some implementations.

SIGSYS Bad argument to a system call. Sends the process to the system debugger with an 'illegal opcode' abort.

SIGPIPE Write to a pipe with no one to read it. The process is sent to the Virtual debugger. Pipes are sometimes used as 'tapes' to do file save. The other end of the pipe can be connected to a serial device, a communication server process... Therefore, when this signal is raised, the write system calls aborts.In an application environment, this signal should be caught and a message sent to the user saying 'Communication Server not Ready', for instance. The write system call would then be interrupted, reported to the save process as a 'parity' error, and the write would be retried until the write finally succeeds.

SIGALRM Alarm clock. The default signal handler is a simple return. Therefore, the signal is active, but does nothing. It can be used in FlashBASIC or Pick/BASIC, with the %alarm() function, do set time outs around critical sections. This signal can be altered by the TCL trap alrm command.

SIGTERM Software termination signal. This signals terminates the Pick process, leaving it logged on, but disconnected. This signal 'freezes' the Pick environment. If the process is restarted, execution will resume where it stopped. Normally, this signal should be preceded by a SIGHUP to log the process off.

SIGUSR1 User-defined signal 1. Not used. Can be used freely by the applications.

SIGUSR2 User-defined signal 2. Force the process to examine its current state, possibly changing it. This signal is used for Pick message, by the TCL logoff , TCL , END commands. Sending this signal out of context will cause no harm. This should be the way, for instance, to wake up a process waiting in a %pause() system call. This signal can be used by applications, provided they call the Pick signal handler inside their customized signal handler. See the section about the examples below.

SIGCLD Death of a child. Not used.

SIGPWR Power fail. When received, the process is logged off Pick, but remains connected to the virtual machine. The behavior of the system depends on how the hardware generates this signal. If there is no battery back-up, it is unlikely that the virtual machine will be brought down gently. The system usually change its running state, which will control what happens. A ap - k command should be inserted in the appropriate shell script associated to the new run level. This signal can be altered by the TCL trap pwr command.


Pick Signal System Call

The Pick monitor provides a system call to inform the Pick Virtual environment of an incoming signal. This C function is normally called by the default signal system handlers, but it can be called by an application signal handler too.

This function is defined as follows:

#include "/usr/lib/pick/include/sigmon.h"

void sigmon( code )
int code;

code is the action code, as described in the following table. Note some functions do not return to the caller .


Code Value/Description
db_slcout 0/No operation. Simply forces the process to examine its current state. This function must be called by the SIGUSR2 signal handler.

db_privop 7/Privileged opcode. Sends the caller to the system debugger. This call does not return to the caller. This call can be used to abort a C program, even if not called from a signal handler.

db_break 10/Interrupt. Sends the process to the FlashBASIC, Pick/BASIC, or system debugger. This function must be called by the SIGINT signal handler. Going to the system debugger is not immediate. Normally, the process will enter the debugger (or push a level) when the signal handler terminates.

db_esc 12/Quit. Pushes a level . This function must be called by the SIGQUIT signal handler. Normally, the process will push a level when the signal handler terminates.

db_logoff 14/Log off. This function is normally called by the SIGHUP handler. It can be called by other signal handlers as part of the application (like SIGALRM for instance, to log off a process after a given time).

db_pwrdown -1/Disconnect. The process is disconnected from the virtual machine, but remains logged on.


Examples

This sections shows some simple examples of using signals in a Pick application, or cooperating with Unix applications. All these examples require writing a C signal handler, which must be linked with the Pick monitor, as detailed in this document.

Time out

The purpose is to write a signal handler which will log the user process off if there is no activity for a given time. It is assumed the user is in a FlashBASIC or Pick/BASIC application, waiting input.

- Write the following signal handler and function

setalrm.c:

#include <signal.h>
#include "/usr/lib/pick/include/sigmon.h"

myalrm(){
/* signal handler. When activated,
log the process off */
sigmon( db_logoff );
}

/* Set the new signal handler
Set the signal handler to
the application signal handler.
Return the address of the
previous signal handler, so
that the basic application
can remove the time out
*/

void (*setalrm())(){
return signal(SIGALRM, myalrm );
}
<

- Compile the previous program and incorporate it to the Pick monitor, by typing, in the dm account:

addbi setalrm signal
ar vru libgm.a setalrm.o
make -f /usr/lib/pick/Makefile

Note this incorporates the user-defined function setalrm() as well as the system call signal() not normally shipped with the Monitor. The latter will be extracted from the standard C library. The %setalrm function can then be called from FlashBASIC or Pick/BASIC.

- Enter the following 'application' program

*
* Reprogram the alarm handler,
* keeping the previous system
* handler
* Note the function pointer
* returned by the function
* is treated as a pointer to a character.

include dm,bp,unix.h signal.h
old$alarm = (char*)%setalrm()
*
loop
* Set the alarm to 10 minutes
* From now on, if the user
* doesn't enter a command before
* 10 minutes, the process will
* be logged off.
%alarm(600)
* .. display application entry screen here
crt 'Command : ':
input command
while 1 do
begin case
case command = 'a'
* ... put command 'a' routine
case command = 'end'
print 'end of the application'
* disable the alarm and set the default alarm
* handler back to the default.
%alarm( 0 )
%signal( SIGALRM, (char*)old$alarm )
chain 'off'
end case
repeat

Note that, in the example above, if the alarm was not disabled and if the signal handler is not reset to the default, the alarm clock would have continued to run, even if the process went back to TCL, thus logging it off later. A small FlashBASIC or Pick/BASIC program, just rearming the alarm can be written to incorporate the alarm in PROCs or menus to achieve the same time out capability in TCL.

Synchronizing Two Pick Processes

On conventional Pick implementations, synchronizing two Pick processes is done either through polling for the existence of a file or, a little better, by using a FlashBASIC or Pick/BASIC LOCK instruction. On most implementations, however, the FlashBASIC or Pick/BASIC LOCK instruction itself involves, internally, a polling, thus making the waiting process to consume cpu resource. By using signals, it is possible to have a process waiting for a signal to occur (a BREAK, logoff or a signal generated by another process, possibly a Unix process or a Pick process from another Pick virtual machine) without any cpu consumption.

The following example has one phantom task waiting for a signal sent by 'somebody' to go read a message in a pipe where the 'somebody' has deposited a message. This communication with message, probably, would be better achieved through Unix messages, but this is merely an example. Also, this is a one to one communication. Multiple partners in this scheme would require semaphores. The server process makes itself visible to the entire system (Pick and Unix) by writing a temporary file which contains its process id, which other processes use to send a signal to it.

The (simple) signal handler uses SIGUSR1 . The 'message' is in ASCII, containing a header and some data. The message has the following format:

+---+---+--------//-----------+
| |NL | +
+---+---+--------//-----------+
| | |
| | +- Data (code dependant)
| +------------ New line (discarded)
+---------------- Command code.
T : Terminate
M : Message
R : file receive
- Enter the following C signal handler:


setusr1.c:

#include <signal.h>
#include "/usr/lib/pick/include/sigmon.h"

myusr1(){
/* Just reset the signal for next time */
signal( SIGUSR1, myusr1 );
}

/* Set the new signal handler
Set the signal handler to the
application signal handler.
Return the address of the
previous signal handler
so that the basic application
can remove the time out
*/

void (*setusr1())(){
return signal(SIGUSR1, myusr1 );
}

- Enter the following phantom task code in the item dm,bp, pserver :

pserver
001 !
002 * Example of a file server running as
003 * a phantom
004 * Commands are received on a named pipe.
005 *
006 include dm,bp,unix.h signal.h
007 include dm,bp,unix.h mode.h
008 include dm,bp,unix.h fcntl.h
009 *
010 * Defines:
011 equ NL to char(10) ;* UNIX line terminator
012 equ AM to char(254)
013 equ PIPE to "/dev/mypipe"
014 equ BUFSIZE to 10000 ;* max message size
015 *
016 char buffer[BUFSIZE]
107 *
018 * Remove temporary file
019 execute '!rm -f /tmp/pserverid'
020 *
021 restart:*
022 *
023 * Open the communication pipe in read
024 * only, no wait on read
025 * If open error, stop, sending a
026 * message back to the originating
027 * process.
028 fd=%open(PIPE, O$RDONLY+O$NDELAY)
029 if fd<0 then
030 stop 1,"Cannot open '":PIPE:"'. Error ":system(0)
031 end
032 *
033 * Do not allow BREAK from now on
034 break off
035 *
036 * Create the temporary file which
037 * contains our pid, so that
038 * everybody on the system will
039 * know the server id
040 mypid=%pgetpid(-1)
041 execute "!echo ":mypid:" > /tmp/pserverid"
042 *
043 * Reprogram the alarm handler,
044 * keeping the previous system handler
045 * Note the function pointer returned
046 * by the function is treated as
047 * a pointer to a character.
048 old$usr1 = (char*)%setusr1()
049 *
050 * Go try read the pipe. If there is no
051 * message, the signal we received
052 * was not an application one. May be
053 * somebody tried to log us off
054 * so close the pipe, restore the
055 * signal and wait a bit. If we come
056 * come back, was a false alarm. Restart.
057 loop while 1 do
058 * Wait for a signal
059 %pause()
060 *
061 * Read the pipe
062 n=%read(fd, buffer, BUFSIZE )
063 *
064 begin case
065 case n=-1
066 * IO error
067 gosub terminate
068 stop 1,"PSERVER: IO error ":system(0)
069 case n=0
070 * Pipe is empty...
071 * The signals we got is not
072 * the one we expected. Enable
073 * break to allow for a
074 * possible
075 * logoff, and restart
076 gosub terminate
077 sleep 1
078 goto restart
079 case 1
080 * Got something (n is the
081 * number of byte)
082 * The 1st byte is a code,
083 * the second a new line
084 * (discarded)
085 code=buffer[1,1]
086 message=buffer[3,n-2]
087 * Go handle the message
088 gosub do$it
089 end case
090 repeat
091 *
092 do$it:*
093 begin case
094 case code='T'
095 * Terminate
096 gosub terminate
097 stop 1,"PSERVER: Terminated"
098 case code='M'
099 * Message.
100 execute "msg * PSERVER: ":message
101 case code='R'
102 * Receive a file. The message is
103 * full filename (NL) item (NL)
104 * text
105 convert NL to AM in message
106 filename=message<1>
107 item=message<2>
108 message=delete(message,1)
109 message=delete(message,1)
110 open filename then
111 write message on item
112 close
113 end else
114 execute "msg !0 PSERVER: '":filename:"' is not filename"
115 end
116 end case
117 *
118 return
119 *
120 * Clean everything
121 terminate:*
122 %close(fd)
123 %signal( SIGUSR1, (char*)old$usr1 )
124 execute '!rm -f /tmp/pserverid'
125 break on
126 return
127 *
128 end


- Create a communication pipe by doing the following from TCL:

su (must be superuser to do the following )
mknod /dev/mypipe p
chmod 0666 /dev/mypipe
exit (Get back to TCL)

- Compile and catalog the FlashBASIC or Pick/BASIC program, compile the C program and add it to the built in function list by:


addbi setusr1
cc -c setusr1.c
ar vru libgmu.a setusr1.o

To be able to use the customized monitor with a phantom process, it is necessary to shutdown and to move the customized monitor to the common directory /usr/bin while being in single user mode.

shutdown
make -f /usr/lib/pick/Makefile
init s (wait for the system to effectively go to single user)
mv /usr/bin/ap /usr/bin/ap.save
mv ./ap /usr/bin
init 2 (go back to multiuser)

Restart the Pick virtual machine.

- Create the phantom task server:

z pserver

- The server is now waiting for a signal to read the message. Normally, this would be done by another process (Pick or Unix), but, just to test this, the following shell script allows sending messages, small Unix files or terminate the server:

snd:

# Send a command to pserver through a pipe
PIPE=/dev/mypipe # the communication pipe
SERVERID=/tmp/pserverid # where the server puts its PID
COMMAND=$1

# Make sure the Pick server is active
if [ ! -r $SERVERID ]
then
echo Pick server is not active
exit 1
fi
# Get the server pid
PSERVERID=`cat $SERVERID`

# Send it a signal 0 to test its existence
kill -0 $PSERVERID
if [ $? != 0 ]
then
echo Pick server is not active. PID is not valid.
exit 1
fi

# Parse command
case $COMMAND in
"r"|"R")
# Receive a file : snd r unix.file
# pick.file item
echo "Rn$3n$4n~`cat $2~`" > $PIPE
;;
"m"|"M")
# Send a message: snd m <text>
shift
echo "Mn$*" > $PIPE
;;
"t"|"T")
# Terminate
echo "Tn" > $PIPE
;;
*)
echo "usage: snd r unix.file pick.file item"
echo " snd m message"
echo " snd t"
;;
esac

# Wake up the server by sending SIGUSR1
# -30 for AIX; -16 for SCO, DG
kill -30 $PSERVERID

- Test the server by the following commands (from Shell):

snd m Hi there

This command should send a Pick message to all Pick users.

snd r /etc/inittab dm,pointer-file, inittab

This command should send the Unix file /etc/inittab into the Pick item dm,pointer-file, inittab .

snd t

This command should terminate the server process.
Syntax
Options
Example
Purpose
Related