2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * File: spc.h $XConsortium: spc.h /main/3 1995/10/26 15:48:38 rswiston $
27 * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
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. *
38 /* -------------------------------------------- */
41 #include <bms/XeUserMsg.h>
45 /* -------------------------------------------- */
47 typedef struct _SPC_Channel *SPC_Channel_Ptr;
49 typedef struct _XeHostInfo {
55 extern FILE *SPC_Print_Protocol;
56 extern FILE *spc_logF;
57 extern XeString spc_user_environment_file;
59 /* Error returns for SPC routines */
61 #define SPC_ERROR FALSE /* Use this value for error checking */
64 * These are the channel connector definitions
74 /* These are the sub-process notification identifiers */
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 */
82 /* This is the maximum size of an SPC I/O Buffer */
83 #define SPC_BUFSIZ 4096
86 * These macros define the bit field portion of an SPC_IOMode
89 #define SPCIO_ALL_MASK 0xffffffff
91 /* The IO Modes that define the input and output sources */
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) */
103 /* Use this bit with above IO Mode for splitting stdout and stderr data */
105 #define SPCIO_SEPARATEREADERROR 0x8 /* Separate stdout & stderr */
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 */
113 #define SPCIO_LINEEDIT 0x80 /* Valid only with PTY */
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 */
127 #define SPCIO_SIGNAL_PGRP 0x20000 /* Propagate signals to entire process
129 #define SPCIO_FORCE_CONTEXT 0x40000 /* Error on SPC Spawn if context dir
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 ; }
146 # define EXTERN_C_CALLABLE(type, name, arglist) \
147 EXTERN_DECL(type, name, arglist)
151 # define EXTERN_C_CALLABLE(type, name, arglist) \
152 extern type name arglist
153 # define EXTERN_DECL(type, name, arglist) \
156 # define EXTERN_DECL(type, name, arglist) name arglist
157 # define EXTERN_C_DECL(type, name, arglist) EXTERN_DECL(type, name, arglist)
162 EXTERN_C_CALLABLE(SPC_Channel_Ptr, XeSPCOpen, (XeString hostname, int iomode));
165 Open an SPC channel. Process will run on 'hostname' (or the local
166 host if value is NULL), with the specified iomode.
169 EXTERN_C_CALLABLE(int, XeSPCClose, (SPC_Channel_Ptr channel));
172 Close an SPC channel. Closing a channel will automatically deactivate it
173 (meaning that any subprocess associated with the channel is terminated).
176 EXTERN_DECL(int, XeSPCReset, (SPC_Channel_Ptr channel));
179 Reset an SPC channel. This will allow it to be used in a subsequent
184 EXTERN_DECL(int, XeSPCRead,
185 (SPC_Channel_Ptr channel, int connector,
186 XeString buffer, int length));
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.
196 EXTERN_DECL(int, XeSPCWrite,
197 (SPC_Channel_Ptr channel, XeString buffer, int length));
200 Write length characters from buffer to the standard input of a
201 process on the other side of an SPC channel.
204 EXTERN_C_CALLABLE(int, XeSPCActive, (SPC_Channel_Ptr channel));
207 Returns True when channel is active, False otherwise
210 EXTERN_DECL(int, XeSPCData, (SPC_Channel_Ptr channel));
213 Returns True when channel be read from, False otherwise
216 EXTERN_C_CALLABLE(int, XeSPCSpawn,
217 (XeString pathname, XeString context_dir, XeString *argv,
218 XeString *envp, SPC_Channel_Ptr channel));
221 Spawn an application under SPC
224 EXTERN_DECL(SPC_Channel_Ptr, XeSPCOpenAndSpawn,
225 (XeString hostname, int iomode, XeString pathname,
226 XeString context_dir, XeString *argv, XeString *envp));
229 Combine the Open and Spawn channel operations
232 EXTERN_DECL(int, XeSPCExecuteProcess, (SPC_Channel_Ptr channel));
235 Restart a new subprocess on a channel
238 EXTERN_C_CALLABLE(void, XeSPCKillProcesses, (int wait));
241 Kill all known executing processes (useful for catching SIGTERM, etc)
244 EXTERN_DECL(int, XeSPCKillProcess, (SPC_Channel_Ptr channel, int wait));
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).
252 EXTERN_DECL(int, XeSPCInterruptProcess, (SPC_Channel_Ptr channel));
255 Interrupt executing process on an SPC channel (send SIGINT).
258 EXTERN_DECL(int, XeSPCSignalProcess, (SPC_Channel_Ptr channel, int sig));
261 Send an arbitrary signal to executing process on an SPC channel.
265 EXTERN_DECL(void, (*SbInputHandlerProc),
266 (void *client_data, XeString buf, int nchars, int connector));
268 EXTERN_C_CALLABLE(int, XeSPCAddInput,
269 (SPC_Channel_Ptr channel,
270 SbInputHandlerProc handler,
274 Add an input channel handler
278 * The user input handler takes the following form:
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) ***
289 EXTERN_DECL(void, (*SPC_TerminateHandlerType),
290 (SPC_Channel_Ptr chan,
294 void *Terminate_Data));
296 EXTERN_C_CALLABLE(int, XeSPCRegisterTerminator,
297 (SPC_Channel_Ptr channel,
298 SPC_TerminateHandlerType teminator,
299 void * client_data));
302 Add a termination handler to a channel (called when sub-process dies)
306 * The user termination handler takes the following form:
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 ***
317 * These are the channel access routines
320 EXTERN_DECL(XeString, XeSPCGetDevice,
321 (SPC_Channel_Ptr channel, int connector, int side));
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
330 EXTERN_DECL(int, XeSPCGetProcessStatus,
331 (SPC_Channel_Ptr channel, int *type, int *cause));
334 Fill in the type and cause of a process termination.
337 EXTERN_DECL(int, XeSPCAttach, (SPC_Channel_Ptr channel, int pid));
340 Returns True if a process ID was associated with an SPC channel.
343 EXTERN_DECL(int, XeSPCDetach, (SPC_Channel_Ptr channel));
345 EXTERN_DECL(int, XeSPCGetPID, (SPC_Channel_Ptr channel));
348 Returns the Process ID of the channel or NULL if none
351 EXTERN_DECL(int, XeSPCGetLogfile,
352 (SPC_Channel_Ptr channel, XeString *host, XeString *file));
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.
360 EXTERN_DECL(int, XeSPCRemoveLogfile, (SPC_Channel_Ptr channel));
363 Remove the logfile associated with the channel
368 * Features currently not implemented:
370 * SPCIO_WAIT with ptys
372 * SEPARATEREADERROR with ptys
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
380 EXTERN_DECL(int, XeSPCGetChannelSyncFd, (SPC_Channel_Ptr channel));
383 Get the file descriptor for checking synchronous termination. This
384 is used for interfacing with event loops.
387 EXTERN_DECL(SPC_Channel_Ptr, XeSPCHandleTerminator, (int fd));
390 Handle a synchronous termination condition
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
405 /* SPC Error handling */
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 */
414 /* Use this to get the current error number */
416 extern int XeSPCErrorNumber;
418 EXTERN_DECL(SPCError *, XeSPCLookupError, (int errnum));
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.
427 EXTERN_DECL(void, XeSPCShutdownCallbacks, (void));
429 EXTERN_DECL(void, XeSPCRestartCallbacks, (void));
431 /* These two routines are used to temporarily suspend SPC callbacks */
433 EXTERN_DECL(int, XeSetpgrp, (int read_current_termio));
436 This routine will do the following:
439 2. get the termio information from the file descriptor just opened
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
444 6. open the slave side.
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.
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
456 EXTERN_DECL(XeHostInfo, SPC_GetHostinfo, (SPC_Channel_Ptr channel));
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!
466 ** New B.00 functions
470 EXTERN_C_CALLABLE(int, XeSPCSendEOF, (SPC_Channel_Ptr channel));
473 Close the standard input of the process on the other side of the channel
476 EXTERN_C_CALLABLE(int, XeSPCSetTermio,
477 (SPC_Channel_Ptr channel,
480 struct termios *termio));
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.
489 #endif /* #ifdef _spc_h */