-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsli_processes.h
1035 lines (788 loc) · 33.3 KB
/
sli_processes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* processes.h
*
* This file is part of NEST
*
* Copyright (C) 2004 by
* The NEST Initiative
*
* See the file AUTHORS for details.
*
* Permission is granted to compile and modify
* this file for non-commercial use.
* See the file LICENSE for details.
*
*/
#ifndef PROCESSES_H
#define PROCESSES_H
/*
SLI's basic process management capabilities
*/
#include <cstdlib>
#include "config.h"
#include <cstdio>
#include <sys/types.h>
#include <fstream>
#include <string>
#include <vector>
#include "sli_module.h"
#include "sli_function.h"
#include "sli_name.h"
namespace sli3
{
// A new SLI-Module:
class Processes: public SLIModule
{
// The following concernes the new module: -----------------------
public:
static const std::string systemerror(SLIInterpreter *); // This will be used to produce systemerror-messages
static int fd(std::istream *s);
static int fd(std::ostream *s);
static int fd(std::ostream &s) {return fd(&s);}
static int fd(std::istream &s) {return fd(&s);}
static pid_t children_group; // the declaration of a static variable. It will
// persist as long as the instantiation of the Processes module lives. Never
// confuse declaration and definition of a variable, by the way...
static std::vector<std::string> *envstrings; // this will contain our copy of
// the environment variables
static char **original_environ; // this will
// store the original environment for cleanup
const Name signaldict_name; // The name of the signal dictionary
// The Names of the signals contained in signal dictionary:
// These are the signals defined by the POSIX standard
const Name SIGABRT_name;
const Name SIGALRM_name;
const Name SIGFPE_name;
const Name SIGHUP_name;
const Name SIGILL_name;
const Name SIGINT_name;
const Name SIGKILL_name;
const Name SIGPIPE_name;
const Name SIGQUIT_name;
const Name SIGSEGV_name;
const Name SIGTERM_name;
const Name SIGUSR1_name;
const Name SIGUSR2_name;
const Name SIGCHLD_name;
const Name SIGCONT_name;
const Name SIGSTOP_name;
const Name SIGTSTP_name;
const Name SIGTTIN_name;
const Name SIGTTOU_name;
const Name sys_errname; // The name of the variable in errordict, in which the name of a system error will be stored
const Name sys_errno; // The corresponding error-number
// The Names of the system's error-numberes contained in errordict
const Name E2BIG_name;
const Name EACCES_name;
const Name EAGAIN_name;
const Name EBADF_name;
const Name EBUSY_name;
const Name ECHILD_name;
const Name EDEADLK_name;
const Name EDOM_name;
const Name EEXIST_name;
const Name EFAULT_name;
const Name EFBIG_name;
const Name EINTR_name;
const Name EINVAL_name;
const Name EIO_name;
const Name EISDIR_name;
const Name EMFILE_name;
const Name EMLINK_name;
const Name ENAMETOOLONG_name;
const Name ENFILE_name;
const Name ENODEV_name;
const Name ENOENT_name;
const Name ENOEXEC_name;
const Name ENOLCK_name;
const Name ENOMEM_name;
const Name ENOSPC_name;
const Name ENOSYS_name;
const Name ENOTDIR_name;
const Name ENOTEMPTY_name;
const Name ENOTTY_name;
const Name ENXIO_name;
const Name EPERM_name;
const Name EPIPE_name;
const Name ERANGE_name;
const Name EROFS_name;
const Name ESPIPE_name;
const Name ESRCH_name;
const Name EXDEV_name;
// The constructor and destructor for our module object (-if we need them-):
Processes(void):
signaldict_name("signaldict"),
SIGABRT_name("SIGABRT"),
SIGALRM_name("SIGALRM"),
SIGFPE_name ("SIGFPE"),
SIGHUP_name ("SIGHUP"),
SIGILL_name ("SIGILL"),
SIGINT_name ("SIGINT"),
SIGKILL_name("SIGKILL"),
SIGPIPE_name("SIGPIPE"),
SIGQUIT_name("SIGQUIT"),
SIGSEGV_name("SIGSEGV"),
SIGTERM_name("SIGTERM"),
SIGUSR1_name("SIGUSR1"),
SIGUSR2_name("SIGUSR2"),
SIGCHLD_name("SIGCHLD"),
SIGCONT_name("SIGCONT"),
SIGSTOP_name("SIGSTOP"),
SIGTSTP_name("SIGTSTP"),
SIGTTIN_name("SIGTTIN"),
SIGTTOU_name("SIGTTOU"),
sys_errname("sys_errname"), // The name of the variable in errordict, in which the name of a system error will be stored
sys_errno("sys_errno"), // The corresponding error-number
// The Names of the system's error-numberes contained in errordict
E2BIG_name("E2BIG"),
EACCES_name("EACCES"),
EAGAIN_name("EAGAIN"),
EBADF_name("EBADF"),
EBUSY_name("EBUSY"),
ECHILD_name("ECHILD"),
EDEADLK_name("EDEADLK"),
EDOM_name("EDOM"),
EEXIST_name("EEXIST"),
EFAULT_name("EFAULT"),
EFBIG_name("EFBIG"),
EINTR_name("EINTR"),
EINVAL_name("EINVAL"),
EIO_name("EIO"),
EISDIR_name("EISDIR"),
EMFILE_name("EMFILE"),
EMLINK_name("EMLINK"),
ENAMETOOLONG_name("ENAMETOOLONG"),
ENFILE_name("ENFILE"),
ENODEV_name("ENODEV"),
ENOENT_name("ENOENT"),
ENOEXEC_name("ENOEXEC"),
ENOLCK_name("ENOLCK"),
ENOMEM_name("ENOMEM"),
ENOSPC_name("ENOSPC"),
ENOSYS_name("ENOSYS"),
ENOTDIR_name("ENOTDIR"),
ENOTEMPTY_name("ENOTEMPTY"),
ENOTTY_name("ENOTTY"),
ENXIO_name("ENXIO"),
EPERM_name("EPERM"),
EPIPE_name("EPIPE"),
ERANGE_name("ERANGE"),
EROFS_name("EROFS"),
ESPIPE_name("ESPIPE"),
ESRCH_name("ESRCH"),
EXDEV_name("EXDEV")
{} //Processes constructor
~Processes(void); // clean up dynmem for static variables...
// The Module is registered by a call to this Function:
void init(SLIInterpreter *);
// This function will return the name of our module:
const std::string name(void) const;
// This function -may- return a string of SLI-commands to be executed for initialization
const std::string commandstring(void) const;
// ---------------------------------------------------------------
// The following concernes the new command(s): -------------------
public:
// Module contains classes defining new SLI-functions:
class ForkFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Sysexec_aFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class WaitPIDFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class KillFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class PipeFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Dup2_is_isFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Dup2_os_osFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Dup2_is_osFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Dup2_os_isFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class AvailableFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class GetPIDFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class GetPPIDFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class GetPGRPFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class MkfifoFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class SetNonblockFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class EnvironmentFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Setenvironment_diFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class CtermidFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Isatty_isFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
class Isatty_osFunction: public SLIFunction
{
public:
void execute(SLIInterpreter *) const; // This is all we need.
};
// Module contains -one- instantiation of each new function-class:
public:
ForkFunction forkfunction;
Sysexec_aFunction sysexec_afunction;
WaitPIDFunction waitPIDfunction;
KillFunction killfunction;
PipeFunction pipefunction;
Dup2_is_isFunction dup2_is_isfunction;
Dup2_os_osFunction dup2_os_osfunction;
Dup2_is_osFunction dup2_is_osfunction;
Dup2_os_isFunction dup2_os_isfunction;
AvailableFunction availablefunction;
GetPIDFunction getpidfunction;
GetPPIDFunction getppidfunction;
GetPGRPFunction getpgrpfunction;
MkfifoFunction mkfifofunction;
SetNonblockFunction setnonblockfunction;
EnvironmentFunction environmentfunction;
Setenvironment_diFunction setenvironment_difunction;
CtermidFunction ctermidfunction;
Isatty_osFunction isatty_osfunction;
Isatty_isFunction isatty_isfunction;
// ---------------------------------------------------------------
};
}
// Description of new SLI-commands:
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: fork - create a child process of SLI
Synopsis: fork -> PID
Description: Thin wrapper to the fork() system function
Parameters: In : -none-
Out: PID(integer) : 0 (for the child)
the child's process ID (for the parent)
Examples: 1. fork
(Well, just kidding...)
2. fork 0 eq {(I'm the child!) = quit} {(I'm the parent!) =} ifelse
Try this several times. You will notice the child message to appear
before or after the parent message "by chance". (Even after the
parent's SLI-prompt...)
Bugs: -
Author: R Kupper
FirstVersion: Mar 17 1999
Remarks: A full parallel process of SLI is forked.
Parent and child will execute in parallel. There is no way to know which
will start being executed first.
Child inherits all open files, including stdin and stdout, from parent!
Thus, calling fork interactively from the SLI-prompt will result in
command-line-confusion if both processes end up without quitting.
If fork() cannot be executed, an error is raised.
SLI-function spoon (processes.sli) is a more convenient wrapper
to fork!
SeeAlso: spoon, sysexec, getPID, getPPID, getPGRP, wait, waitPID
*/
//-----------------------------------------------------------------------------
/* Now Documented with sysexec!
Name: sysexec_a - execute a UNIX command
Synopsis: CommandArray sysexec -> -
Description: Transfer control to a UNIX-Command.
Parameters: In : CommandArray (array of strings):
An array containing the command to execute. The first element
is interpreted as the command, the remaining elements as it's
parameters.
Out: -whatever will be will be-
Examples: -see command sysexec-
Bugs: -see command sysexec-
Author: R Kupper
FirstVersion: Mar 1999
Remarks: There is a SLI-wrapper called "sysexec" to this function.
-see command sysexec-
SeeAlso: sysexec, fork, spoon
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: waitPID - wait or check for a child process to terminate
Synopsis: PIDin NoHangFlag waitPID -> Status NormalExitFlag PIDout
-> 0
Description: The waitPID function suspends execution of the calling process
until status information for the given child is available,
or until delivery of a signal whose action is either to
execute a signal-catching function or to terminate the
process. If status information is available prior to the call
to waitPID, it returns immediately.
The waitPID function returns the process ID of the child for
which status is being reported.
Zero is returned immediately, if the NoHangFlag is set
and no status is available.
Alternatives: Function waitPID_i_b (undocumented)
-> behaviour and synopsis are the same.
Parameters: In : PIDin(integer): -1: Wait for any child process.
positive: Wait for the specific child whose
process ID is equal to PIDin.
( 0: -not supported-)
(less than -1: -not supported-)
NoHangFlag(boolean):
If true, causes waitPID function not to suspend execution
of the calling process if status is not immediately
available for any of the child processes specified by
PIDin. In this case, zero is returned as only result.
Out: PIDout(integer):
The process ID of the child for which status is being
reported.
NormalExitFlag(boolean):
True, if status is returned for a child that terminated
normally, i.e. by a call to exit() or by returning from
main(). In that case, the exit code is reported in the Status
argument (see below).
False, if status is returned for a child that terminated due
to a signal that was not caught. In that case, the number of
that signal is reported in the Status argument (see below).
Status(integer):
If NormalExitFlag is true, this reports the child's exit code,
i.e. the low-order eight bits of the status argument that the
child passed to exit(), or the value the child process
returned from main().
If NormalExitFlag is false, this reports the number of the
signal that caused the termination of the child process. Look
up this number in signaldict, to know what it means.
Examples:1. {(sleep 3) sysexec} spoon false waitPID
2. {(ls) sysexec} spoon false waitPID
Note the parent process' SLI-Prompt appearing AFTER execution of the
command finished.
This is different to the call "{(ls) sysexec} spoon" only.
3. 23 false waitPID
Bugs: -
Author: R Kupper
FirstVersion: Apr 13 1999
Remarks: The features normally used only by the UNIX-shell-program
(such as the WUNTRACED-option) are currently not supported,
although values <=0 can be passed through PIDin.
See any documentation of POSIX-function waitpid().
Discription text is mainly taken from
Donald A. Lewine, "POSIX programmer's guide", O'Reilly&Associates,Inc.
SeeAlso: wait, spoon, signaldict, getPGRP
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: kill - send a signal to another process
Synopsis: PID SIGNAL kill -> -
PID /SIGNAL kill -> -
Description: The "kill" function sends a signal to a process or a group
of processes specified by "PID". If the signal is zero,
error checking is performed but no signal is actually sent.
This can be used to check for a valid PID.
SIGNAL may be given either as an integer value or as the
literal name of the signal, as found in "signaldict".
Alternative: Functions kill_i_i for integer (SIGNAL),
kill_i_l for literal (SIGNAL) (both undocumented)
-> behaviour and synopsis are the same.
Parameters: In : PID(integer):
The ID of the process that shall be signalled.
If "PID" is greater than zero, "SIGNAL" is sent to the
process whose ID is "PID".
(If "PID" is negative, "SIGNAL" is sent to all processes
whose process group ID is equal to the absolute value
of "PID". - Process groups are usually used by the
shell program only.)
SIGNAL(integer):
The number of the signal to be sent.
Signal codes are machine-dependent values, so do not
rely on any given value! The valid signal codes for
your machine are compiled into the "signaldict"
dictionary, where they can be looked up by
their literal names.
The only value you may rely on is zero:
If SIGNAL is zero, error checking is performed
but no signal is actually sent.
This can be used to check for a valid PID.
/SIGNAL(literal):
The literal name of the signal to be sent.
This name is automatically looked up in "signaldict"
and substituted to it's corresponding value prior
to a call to wait.
Out: -none-.
Examples: 1. 23 /SIGTERM kill %send TERM signal to Process 23
2. %This is equivalent to 1. :
signaldict begin
23 SIGTERM kill
end
3. (xterm) 2 system %star an xterm-process
/SIGKILL kill %kill it again
Bugs: -
Author: R Kupper
FirstVersion: Apr 27 1999
Remarks: "kill" can be used to send ANY signal, but it's most oftenly used
to terminate another process. Hence the name.
Resolution of literal signal names is done by a trie defined
in file processes.sli.
Description taken mainly from "POSIX Programmer's Guide",
D. Lewine, O'Reilly & Assoc. Inc.
SeeAlso: signaldict, system, sysexec, wait, waitPID, spoon, fork, getPPID, getPGRP
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: signaldict - Dictionary containing the machine-dependent signal codes.
Synopsis: signaldict -> signaldict
Description: A SLI dictionary containing the system's valid signal codes.
"signaldict" is used in combination with the "kill",
"wait" or "waitPID" commands.
Signal codes are machine-dependent values, so do not
rely on any given value! The valid signal codes for
your machine are compiled into the "signaldict"
dictionary, where they can be looked up by
their literal names.
Examples: 1. signaldict /SIGTERM get %get the value for signal SIGTERM
2. (xterm) 2 system %start an xterm-prcess
signaldict begin %open signal dictionary
SIGKILL kill %kill process
end %close dictionary
3. %This is equivalent to 2. (see description of "kill"):
(xterm) 2 system %start an xterm-process
/SIGKILL kill %kill it again
Bugs: -
Author: R Kupper
FirstVersion: Apr 16 1999
SeeAlso: kill, wait, waitPID, system, sysexec, spoon, fork
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: pipe - Open up a pipe
Synopsis: pipe -> read_end write_end
Description: The pipe function creates a pipe, placing a filestream
for the read end and a filestream for the write end of
the pipe on the stack.
Data can be written to "write_end" and read from "read_end".
A read on "read_end" accesses the data written to "write_end"
on a first-in-first-out basis.
Parameters: In : -none-
Out: read_end(ifstream):
A filestream open for reading, connected to the read-
end of the newly created pipe.
write_end(ofstream):
A filestream open for writing, connected to the write-
end of the newly created pipe.
Examples: pipe
(Hello Pipe) <- std::endl
pop
getline =
Diagnostics: If a system-error occurs, a code is stored in "sys_errno"
(contained in errordict) to identify the error, and
"sys_errname" is set to the error message. Then a
"SystemError" is raised.
Bugs: -
Author: R Kupper
FirstVersion: May 02 1999
Remarks: Description-text taken mainly from "POSIX Programmer's Guide",
D. Lewine, O'Reilly & Assoc. Inc.
The O_NONBLOCK and FD_CLOEXEC flags are clear on the
file descriptors of both streams.
Opening a pipe in a single process is next to useless (however,
it might be used for buffering data). The usual application
is for inter-process-communication: A pipe is opened, and fork
is called. The child process inherits both filestreams from
the parent. The child will then close one of the streams (say:
the read-end), the parent will close the other (say: the write-
end). Data may then be transfered from the child to the parent
process through the pipe.
If the child is to "sysexec" a UNIX command, it may duplicate
the pipes's write-end onto its standard "cout" stream using "dup2",
thus directing any data written to "cout" into the pipe. It then
calles "sysexec". The parent process is thus enabled to read
the UNIX-command's standard output from the pipe.
Pipes are unidirectional communication channels.
For bidirectional communication, two separate pipes must be opened.
The "spawn" command provides this functionality.
SeeAlso: dup2, available, spawn
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: available - check if data is available from an istream
Synopsis: istream available -> istream {true|false}
Description: "availabe" gives the answer to one question:
--Is there at least one character waitng to be read
from the istream?--
If "available" returns true, it can be safely assumed that
reading one character from the given istream is safe,
i.e. it will NEITHER BLOCK nor yield EOF or an error.
Alternative: Functions available_is (undocumented)
-> behaviour and synopsis are the same.
Parameters: In: istream: The istream to check.
Out: true or false, indicating if data is waiting on the stream.
Examples: myfifo available { getline } if % read it data is available.
Diagnostics: If a system-error occurs, a code is stored in "sys_errno"
(contained in errordict) to identify the error, and "sys_errname" is
set to the error message. Then a "SystemError" is raised.
The following system errors may be issued, according to the
POSIX standard (errors in parantheses are not
expected to occur in this routines' context):
(EACCES) Search permission is denied for a
directory in a files path prefix.
(EAGAIN) The ON_NONBLOCK flag is set for a file
descriptor and the process would be
delayed in the I/O operation.
EBADF Invalid file descriptor. (With the current
implementation, this indicates trouble
getting a fildescriptor from a stream. If
it occurs, ask the author for a proper
soultion!)
(EDEADLK) A fcntl with function F_SETLKW would
cause a deadlock.
EINTR Function was interrupted by a signal.
(EINVAL) Invalid argument.
(EMFILE Too many file descriptors are in use by
this process.
(ENOLCK) No locks available.
Bugs: -
Author: R Kupper
FirstVersion: May 10 1999
Remarks: "available" will be typically used with pipes or fifos.
There are two possible reasons why "available" may return false:
1. There are processes writing to the pipe/fifo, but none
of the is currently writing data to it.
A subsequent read attempt will block until data becomes
available.
2. There are no processes writing to the pipe (any longer).
A subsequent read attempt will yield EOF.
It is NOT possible to tell these possibilities apart! This is
not a fault of the implementation of this function. It is generally
impossible to do this. The only way to know is to start a read
attempt. If it blocks, you know the answer - but you could wait
forever. Anyway, there normally is no need to distinguish between
these alternatives: Just NEVER try a read attempt, if "available"
returned false. Even if temporarily no process was connected to
the stream, it will return true as soon as the connection is re-
established and data is waiting.
"available" just tells you if -one- character may be read safely.
It is left to the programmer to assure that a given amount of
data (e.g. upto the next linefeed) may be read.
SeeAlso: pipe, mkfifo, spawn, eof, in_avail
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: getPID - Get ID of the current process
Synopsis: getPID -> -
Description: Returns the process ID for the calling process.
Parameters: -
Examples: (I am process #) =only getPID =
Diagnostics: A call to "getPID" should never produce an error.
Bugs: -
Author: R Kupper
FirstVersion: May 26 1999
SeeAlso: getPPID, getPGRP, fork, spoon, waitPID, kill, system, spawn, shpawn
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: getPPID - Get parent ID of the current process
Synopsis: getPPID -> -
Description: Returns the process parent ID for the calling process.
Parameters: -
Examples: (I was called by process #) =only getPPID =
Bugs: -
Author: S Schrader, taken from getPID
FirstVersion: Nov 11 2005
SeeAlso: getPID, getPGRP, fork, spoon, waitPID, kill, system, spawn, shpawn
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: getPGRP - Get process group ID of the current process
Synopsis: getPGRP -> -
Description: Returns the process group ID for the calling process.
Parameters: -
Examples: (I am member of process group #) =only getPGRP =
Diagnostics: A call to "getPGRP" should never produce an error.
Bugs: -
Author: R Kupper
FirstVersion: Apr 18 2000
SeeAlso: fork, getPID, kill
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: mkfifo - Create a FIFO special file (named pipe)
Synopsis: path mkfifo -> -
Description: The "mkfifo" command creates a new FIFO special file named
"path". The permission bits are set to "rwx rwx rwx" (full access
for anyone). Note that these bits may be modified by the process'
file creation mask. (See remarks below.)
Alternative: Functions mkfifo_s (undocumented)
-> behaviour and synopsis are the same.
Parameters: In: path(string):
Path name of the FIFO to create.
Examples: (/home/kupper/my_fifo) mkfifo
Diagnostics: If a system-error occurs, a code is stored in "sys_errno"
(contained in errordict) to identify the error, and "sys_errname" is
set to the error message. Then a "SystemError" is raised.
The following system errors may be issued, according to the
POSIX standard:
EACCES Search permission denied for a directory in a file's path
prefix.
EEXIST The named file already exists.
ENOENT A file or directory does not exist.
ENOSPC No space left on disk.
ENOTDIR A component of the specified pathname was not a directory
when a directory was expected.
EROFS Read-only file system.
Bugs: -
Author: R. Kupper
FirstVersion: Aug 13 1999 (Friday 13th!)
Remarks: The FIFO may be used (and has to be opened) like any regular file.
In special cases, it might be desireable to change the FIFO's file
permission bits. This is not supported by SLI commands.
Use UNIX-command "chmod" to change file permissions on the newly
created file, or use UNIX-command "umask" to set the process' file
creation mask. (See command "system" for issuing UNIX-commands from
SLI).
SeeAlso: pipe, mkfifo, ifstream, available, ignore, dup2
*/
//-----------------------------------------------------------------------------
/* BeginDocumentation
Name: setNONBLOCK - Switch between blocking and non-blocking I/O.
Synopsis: ifstream {true|false} setNONBLOCK -> ifstream
Description: "setNONBLOCK" sets or erases the O_NONBLOCK flag on
an input stream. The O_NONBLOCK flag determines, if
a read attempt will block when no data is currently
available from the stream. By default, a newly
created stream has the O_NONBLOCK-Flag erased,
meaning that blocking I/O is selected. By erasing
O_NONBLOCK, a subsequent read attempt on the stream
will yield EOF if no data is availabe.
Alternatives: Function setNONBLOCK_is_b (undocumented)
-> behaviour and synopsis are the same.
Parameters: In : ifstream: The stream to change the flag on.
Out: -
Examples: cin false setNONBLOCK
myfifo true setNONBLOCK % set non-blocking I/O for my fifo.
Diagnostics: If a system-error occurs, a code is stored in "sys_errno"
(contained in errordict) to identify the error, and "sys_errname" is
set to the error message. Then a "SystemError" is raised.
The following system errors may be issued, according to the
POSIX standard (errors in parantheses are not
expected to occur in this routines' context):
(EACCES) Search permission is denied for a
directory in a files path prefix.
(EAGAIN) The ON_NONBLOCK flag is set for a file
descriptor and the process would be
delayed in the I/O operation.
EBADF Invalid file descriptor. (With the current
implementation, this indicates trouble
getting a fildescriptor from a stream. If
it occurs, ask the author for a proper
soultion!)
(EDEADLK) An fcntl with function F_SETLKW would
cause a deadlock.
EINTR Function was interrupted by a signal.
(EINVAL) Invalid argument.
(EMFILE Too many file descriptors are in use by
this process.
(ENOLCK) No locks available.
Bugs: -
Author: R Kupper
FirstVersion: Oct 20 1999
SeeAlso: available, ignore
*/
//--------------------------------------------------------------------------------- <- end of line (C84) is maximum width for LaTeX-include1
/* BeginDocumentation
Name: environment - return the environment of the current SLI process.
Synopsis: environment -> envdict
Description: This command returns the full program environment of the
current SLI process as a dictionary of string values.
The result is a dictionary of all defined environment
variables and their corresponding values.
Examples: SLI ] environment info
Diagnostics: As every process has a program environment (even if it
should be empty), this routine should never fail.
Author: R Kupper
FirstVersion: Nov 10 2000
Remarks: Note that changing the contents of the returned dictionary
does -NOT- in turn affect the program environment of the
current SLI process! See the "setenvironment" command on how
to change the process environment.
SeeAlso: setenvironment, getenv
*/
//--------------------------------------------------------------------------------- <- end of line (C84) is maximum width for LaTeX-include1
/* setenvironment_di
is documented with its root setenvironment in file
/lib/sli/processes.sli.
*/
//--------------------------------------------------------------------------------- <- end of line (C84) is maximum width for LaTeX-include1
/*
BeginDocumentation
Name: ctermid - Return the path to the controlling terminal of the process.
Synopsis: ctermid -> (pathname)
Remarks: This is a wrapper to the POSIX kernel function ctermid().
SeeAlso: isatty
*/