Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / DtSvc / include / bms / spc.h
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * File:         spc.h $XConsortium: spc.h /main/3 1995/10/26 15:48:38 rswiston $
25  * Language:     C
26  *
27  * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
28  *
29  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
30  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
31  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
32  * (c) Copyright 1993, 1994 Novell, Inc.                                *
33  */
34
35 #ifndef _spc_h
36 #define _spc_h
37
38 /* -------------------------------------------- */
39 /* Requires:                                    */
40 #include <stdio.h>
41 #include <bms/XeUserMsg.h>
42
43 #include <termios.h>
44
45 /* -------------------------------------------- */
46
47 typedef struct _SPC_Channel *SPC_Channel_Ptr;
48
49 typedef struct _XeHostInfo {
50     XeString    os;
51     XeString    os_ver;
52     XeString    hw_arch;
53 } *XeHostInfo;
54
55 extern FILE *SPC_Print_Protocol;
56 extern FILE *spc_logF;
57 extern XeString spc_user_environment_file;
58
59 /* Error returns for SPC routines */
60
61 #define SPC_ERROR       FALSE  /* Use this value for error checking */
62
63 /*
64  * These are the channel connector definitions
65  */
66
67 #define STDIN                   0
68 #define STDOUT                  1
69 #define STDERR                  2
70
71 #define MASTER_SIDE     0
72 #define SLAVE_SIDE      1
73
74 /* These are the sub-process notification identifiers */
75
76 #define SPC_PROCESS_STOPPED     1 /* Child process is in background */
77 #define SPC_PROCESS_EXITED      2 /* Child process called exit(cause); */
78 #define SPC_PROCESS_SIGNALLED   3 /* Child process received signal: cause */
79 #define SPC_PROCESS_INTERRUPT   4 /* Child process WAIT was interrupted */
80 #define SPC_PROCESS_DUMPED(a)   ((a) & 0200) /* True when core dumped */
81
82 /* This is the maximum size of an SPC I/O Buffer */
83 #define SPC_BUFSIZ              4096
84
85 /*
86  * These macros define the bit field portion of an SPC_IOMode
87  */
88
89 #define SPCIO_ALL_MASK          0xffffffff
90
91 /* The IO Modes that define the input and output sources */
92
93 #define SPCIO_SOURCE_MASK       0xf
94 #define SPCIO_NOIO              0x0 /* The default - no input/output */
95 #define SPCIO_WRITEONLY         0x1 /* Only write app stdin */
96 #define SPCIO_READONLY          0x2 /* Only read app stdout */
97 #define SPCIO_READWRITE         0x3 /* Read stdout, write stdin */
98 #define SPCIO_ERRORONLY         0x4 /* Only read stderr */
99 #define SPCIO_WRITEERROR        0x5 /* Write stdin, read stderr */
100 #define SPCIO_READERROR         0x6 /* Only read stdout/stderr */
101 #define SPCIO_READWRITEERROR    0x7 /* Full std (in, out, err) */
102
103 /* Use this bit with above IO Mode for splitting stdout and stderr data */
104
105 #define SPCIO_SEPARATEREADERROR 0x8 /* Separate stdout & stderr */
106
107 /* The IO Modes that deal with communication styles (features) */
108 #define SPCIO_STYLE_MASK        0x70
109 #define SPCIO_PTY               0x10 /* Use a PTY */
110 #define SPCIO_PIPE              0x20 /* Use pipe() - no line editing */
111 #define SPCIO_NOIOMODE          0x40 /* Use neither */
112
113 #define SPCIO_LINEEDIT          0x80 /* Valid only with PTY */
114
115 /* Other flags */
116
117 #define SPCIO_SYSTEM            0x100 /* Use system() - Spawns a SHELL */
118 #define SPCIO_LINEORIENTED      0x200 /* Invoke callback on line bounds */
119                                       /* It is possible to break two byte
120                                          characters.  See note on XeSPCRead. */
121 #define SPCIO_WAIT              0x400 /* Wait for process to finish */
122 #define SPCIO_USE_XTOOLKIT      0x800 /* Use the X toolkit */
123 #define SPCIO_SYNC_TERMINATOR  0x1000 /* Handle termination synchronously */
124 #define SPCIO_USE_LOGFILE      0x2000 /* Use logfile for stderr -- only
125                                          valid with SPCIO_NOIO */
126
127 #define SPCIO_SIGNAL_PGRP     0x20000 /* Propagate signals to entire process
128                                          group. */
129 #define SPCIO_FORCE_CONTEXT   0x40000 /* Error on SPC Spawn if context dir
130                                          is not present */
131
132 /*
133  * Routines
134  */
135
136
137 /* spc.c */
138
139
140 #if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
141 # define EXTERN_DECL(type, name, arglist) type name arglist
142 # if defined(__cplusplus) && defined(__c_callable)
143 #  define EXTERN_C_CALLABLE(type, name, arglist) \
144           extern "C" { type name arglist ; }
145 # else
146 #  define EXTERN_C_CALLABLE(type, name, arglist) \
147           EXTERN_DECL(type, name, arglist)
148 # endif
149 #else
150 #ifdef _AIX
151 # define EXTERN_C_CALLABLE(type, name, arglist) \
152          extern type name arglist 
153 # define EXTERN_DECL(type, name, arglist) \
154          type name arglist
155 #else /* _AIX */
156 # define EXTERN_DECL(type, name, arglist) name arglist
157 # define EXTERN_C_DECL(type, name, arglist) EXTERN_DECL(type, name, arglist)
158
159 #endif /* (_AIX) */
160 #endif
161
162 EXTERN_C_CALLABLE(SPC_Channel_Ptr, XeSPCOpen, (XeString hostname, int iomode));
163
164 /*
165   Open an SPC channel.  Process will run on 'hostname' (or the local
166   host if value is NULL), with the specified iomode.
167 */
168
169 EXTERN_C_CALLABLE(int, XeSPCClose, (SPC_Channel_Ptr channel));
170
171 /*
172   Close an SPC channel.  Closing a channel will automatically deactivate it
173   (meaning that any subprocess associated with the channel is terminated).
174 */
175
176 EXTERN_DECL(int, XeSPCReset, (SPC_Channel_Ptr channel));
177
178 /*
179   Reset an SPC channel.  This will allow it to be used in a subsequent
180   spawn or exec call.
181 */
182
183
184 EXTERN_DECL(int, XeSPCRead,
185             (SPC_Channel_Ptr channel, int connector,
186              XeString buffer, int length));
187
188 /*
189   Read length characters from an SPC channel into some preallocated buffer.
190   Note that it is possible to split a two-byte character, if the first
191   byte if the character is read in just at buffer[length].  However, the
192   next read will return the second byte (just like Unix read).  The
193   'connector' value is either STDOUT or STDERR.
194 */
195
196 EXTERN_DECL(int, XeSPCWrite,
197             (SPC_Channel_Ptr channel, XeString buffer, int length));
198
199 /*
200   Write length characters from buffer to the standard input of a
201   process on the other side of an SPC channel.
202 */
203
204 EXTERN_C_CALLABLE(int, XeSPCActive, (SPC_Channel_Ptr channel));
205
206 /*
207   Returns True when channel is active, False otherwise
208 */  
209
210 EXTERN_DECL(int, XeSPCData, (SPC_Channel_Ptr channel));
211
212 /*
213   Returns True when channel be read from, False otherwise
214 */  
215
216 EXTERN_C_CALLABLE(int, XeSPCSpawn,
217                   (XeString pathname, XeString context_dir, XeString *argv,
218                    XeString *envp, SPC_Channel_Ptr channel));
219
220 /*
221   Spawn an application under SPC
222 */
223
224 EXTERN_DECL(SPC_Channel_Ptr, XeSPCOpenAndSpawn,
225             (XeString hostname, int iomode, XeString pathname,
226              XeString context_dir, XeString *argv, XeString *envp));
227             
228 /*
229   Combine the Open and Spawn channel operations
230 */
231
232 EXTERN_DECL(int, XeSPCExecuteProcess, (SPC_Channel_Ptr channel));
233
234 /*
235   Restart a new subprocess on a channel
236 */
237
238 EXTERN_C_CALLABLE(void, XeSPCKillProcesses, (int wait));
239
240 /*
241   Kill all known executing processes (useful for catching SIGTERM, etc)
242 */
243
244 EXTERN_DECL(int, XeSPCKillProcess, (SPC_Channel_Ptr channel, int wait));
245
246 /*
247   Kill executing process on an SPC channel.  'wait' TRUE means don't
248   return from call until process is completely terminated (including
249   after user specified callbacks are called).
250 */
251
252 EXTERN_DECL(int, XeSPCInterruptProcess, (SPC_Channel_Ptr channel));
253
254 /*
255   Interrupt executing process on an SPC channel (send SIGINT).
256 */
257
258 EXTERN_DECL(int, XeSPCSignalProcess, (SPC_Channel_Ptr channel, int sig));
259
260 /*
261   Send an arbitrary signal to executing process on an SPC channel.
262 */  
263
264 typedef
265   EXTERN_DECL(void, (*SbInputHandlerProc),
266               (void *client_data, XeString buf, int nchars, int connector));
267
268 EXTERN_C_CALLABLE(int, XeSPCAddInput,
269                   (SPC_Channel_Ptr    channel,
270                    SbInputHandlerProc handler,
271                    void               *client_data));
272
273 /*
274   Add an input channel handler
275 */
276
277 /*
278  * The user input handler takes the following form:
279  *
280  * void UserInputHandler(client_data, text, size, connection)
281  *      void * client_data; *** Useful for passing widet destination ***
282  *      XeString text;      *** The text coming from the SPC channel ***
283  *      int size;           *** The number of character in passed text ***
284  *      int connection;     *** The connection where data was received ***
285  *                          ***  (STDOUT or STDERR)                    ***
286  */
287
288 typedef
289   EXTERN_DECL(void, (*SPC_TerminateHandlerType),
290               (SPC_Channel_Ptr  chan,
291                int  pid,
292                int  type,
293                int  cause,
294                void *Terminate_Data));
295
296 EXTERN_C_CALLABLE(int, XeSPCRegisterTerminator,
297                   (SPC_Channel_Ptr          channel,
298                    SPC_TerminateHandlerType teminator,
299                    void *                   client_data));
300
301 /*
302   Add a termination handler to a channel (called when sub-process dies)
303 */
304
305 /*
306  * The user termination handler takes the following form:
307  *
308  * void UserTerminator(channel, pid, type, cause, client_data)
309  *      SPC_CHannel_ptr channel;
310  *      int pid;            *** The Process ID of the terminated appl. ***
311  *      int type;           *** The type of termination (see above)    ***
312  *      int cause;          *** The number associated w/termination    ***
313  *      void * client_data; *** User specified client data             ***
314  */
315
316 /*
317  * These are the channel access routines
318  */
319
320 EXTERN_DECL(XeString, XeSPCGetDevice,
321             (SPC_Channel_Ptr channel, int connector, int side));
322
323 /*
324   Return the device name associated with a side of a channel device
325   pair.  'connector' is either STDIN, STDOUT, or STDERR, and 'side' is
326   either MASTER_SIDE or SLAVE_SIDE.  This call is valid only in PTY
327   channels.
328 */  
329
330 EXTERN_DECL(int, XeSPCGetProcessStatus,
331             (SPC_Channel_Ptr channel, int *type, int *cause));
332
333 /*
334   Fill in the type and cause of a process termination.
335 */
336
337 EXTERN_DECL(int, XeSPCAttach, (SPC_Channel_Ptr channel, int pid));
338
339 /*
340   Returns True if a process ID was associated with an SPC channel.
341 */
342
343 EXTERN_DECL(int, XeSPCDetach, (SPC_Channel_Ptr channel));
344
345 EXTERN_DECL(int, XeSPCGetPID, (SPC_Channel_Ptr channel));
346
347 /*
348   Returns the Process ID of the channel or NULL if none
349 */  
350
351 EXTERN_DECL(int, XeSPCGetLogfile,
352             (SPC_Channel_Ptr channel, XeString *host, XeString *file));
353
354 /*
355   Return the logfile for the channel.  If the channel was not opened
356   with SPCIO_USE_LOGFILE specified, it will return NULL.  Also note
357   that it returns an XeString *, not an XeString.
358 */  
359
360 EXTERN_DECL(int, XeSPCRemoveLogfile, (SPC_Channel_Ptr channel));
361
362 /*
363   Remove the logfile associated with the channel
364 */
365
366 /*
367  *
368  * Features currently not implemented:
369  *
370  *  SPCIO_WAIT with ptys
371  *
372  *  SEPARATEREADERROR with ptys
373  *
374  *  Complete error checking.  For example, there
375  *  are no checks for trying to write to a channel
376  *  opened W/O SPCIO_WRITE specified
377  *
378  */
379
380 EXTERN_DECL(int, XeSPCGetChannelSyncFd, (SPC_Channel_Ptr channel));
381
382 /*
383   Get the file descriptor for checking synchronous termination.  This
384   is used for interfacing with event loops.
385 */
386
387 EXTERN_DECL(SPC_Channel_Ptr, XeSPCHandleTerminator, (int fd));
388
389 /*
390   Handle a synchronous termination condition
391
392   This routine is to be used with the file descriptor returned by
393   XeSPCGetChannelSyncFd.  The idea is that one opens a channel using
394   SPCIO_SYNC_TERMINATOR set in the iomode, and then at some point
395   checks for input available on the returned file descriptor (possibly
396   using a select(2) system call).  If there is input, it means that
397   some SYNC_TERMINATOR channel had a subprocess die.  The program then
398   calls XeSPCHandleTerminator to get the termination handler invoked.
399   IT IS THE RESPONSIBILITY OF THE USER PROGRAM TO EVENTUALLY CALL
400   XeSPCHandleTerminator.  IF IT DOES NOT, THE PROGRAM MAY DEADLOCK
401   ITSELF.
402 */
403
404
405 /* SPC Error handling */
406
407 typedef struct _SPCError { /* An SPC Error message */
408   XeString text;     /* The text */
409   XeString format;   /* How to format args */
410   XeSeverity severity;     /* How bad is it, doc? */
411   char use_errno;          /* Whether to use the system errno */
412 } SPCError;
413
414 /* Use this to get the current error number */
415
416 extern int XeSPCErrorNumber;
417
418 EXTERN_DECL(SPCError *, XeSPCLookupError, (int errnum));
419
420 /*
421   Returns the SPCError structure associated with the passed error number or
422    NULL if the passed error number is not a valid SPC error.  The
423    error structure returned will be overwritten by a subsequent
424    XeSPCLookupError call.
425 */
426
427 EXTERN_DECL(void, XeSPCShutdownCallbacks, (void));
428
429 EXTERN_DECL(void, XeSPCRestartCallbacks, (void));
430
431 /* These two routines are used to temporarily suspend SPC callbacks */
432
433 EXTERN_DECL(int, XeSetpgrp, (int read_current_termio));
434
435 /*
436   This routine will do the following:
437
438   1. open /dev/tty
439   2. get the termio information from the file descriptor just opened
440   3. close /dev/tty
441   3. allocate a master / slave pty pair, opening the master side
442   4. set the termio info of the master side to be the result of step 2
443   5. setpgrp
444   6. open the slave side.
445   
446   All of this has the effect of making the process which called this
447   routine immune to interrupts, etc., but also passing on the termio
448   characteristics of the original tty.
449
450   If read_current_termio is non-zero, steps 1-3 will NOT be performed, but
451   instead this routine will get the information from the following termio
452   struct:
453   
454 */
455
456 EXTERN_DECL(XeHostInfo, SPC_GetHostinfo, (SPC_Channel_Ptr channel));
457
458 /* 
459   Return information about the host (os, os-ver, hw) to which "channel"
460   is currently connected.  The return is to a static structure of static
461   strings.  Do not modify or free and of them!
462 */
463
464 /*
465  **
466  ** New B.00 functions
467  **
468 */
469
470 EXTERN_C_CALLABLE(int, XeSPCSendEOF, (SPC_Channel_Ptr channel));
471
472 /*
473  Close the standard input of the process on the other side of the channel
474 */
475
476 EXTERN_C_CALLABLE(int, XeSPCSetTermio,
477                   (SPC_Channel_Ptr channel,
478                    int connection,
479                    int side,
480                    struct termios *termio));
481
482 /*
483  Set the termio value of the PTY associated with 'connection' (STDIN,
484  STDOUT, or STDERR), on 'side' (MASTER_SIDE or SLAVE_SIDE) to the
485  value pointed to by termio.  This call must be made before the
486  subprocess is spawned.
487 */
488
489 #endif /* #ifdef _spc_h */