rxunixsys.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 2009-2021 Rexx Language Association. All rights reserved. */
4 /* */
5 /* This program and the accompanying materials are made available under */
6 /* the terms of the Common Public License v1.0 which accompanies this */
7 /* distribution. A copy is also available at the following address: */
8 /* https://www.oorexx.org/license.html */
9 /* */
10 /* Redistribution and use in source and binary forms, with or */
11 /* without modification, are permitted provided that the following */
12 /* conditions are met: */
13 /* */
14 /* Redistributions of source code must retain the above copyright */
15 /* notice, this list of conditions and the following disclaimer. */
16 /* Redistributions in binary form must reproduce the above copyright */
17 /* notice, this list of conditions and the following disclaimer in */
18 /* the documentation and/or other materials provided with the distribution. */
19 /* */
20 /* Neither the name of Rexx Language Association nor the names */
21 /* of its contributors may be used to endorse or promote products */
22 /* derived from this software without specific prior written permission. */
23 /* */
24 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
25 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
26 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
27 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
28 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
29 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
30 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
31 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
32 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
33 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
34 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
35 /* */
36 /*----------------------------------------------------------------------------*/
37 
38 
39 #include "rxunixsys.h"
40 
41 
42 /**
43  * Function: SysSignal
44  *
45  * Change a signal behavior.
46  *
47  * @param signum The signal number.
48  *
49  * @param sigact The new signal action.
50  *
51  * @return Function return code
52  */
54  SysSignal,
55  int, signum,
56  CSTRING, sigact)
57 {
58 
59  if (strlen(sigact) == 0) {
60  context->InvalidRoutine();
61  return 0;
62  }
63  // According to POSIX we should only allow the following values for this function
64  else if (*sigact == 'D' || *sigact == 'd') {
65  signal(signum, SIG_DFL);
66  return 0;
67  }
68  else if (*sigact == 'I' || *sigact == 'i') {
69  signal(signum, SIG_IGN);
70  return 0;
71  }
72  context->InvalidRoutine();
73  return 0;
74 }
75 
76 
77 /**
78  * Method: SysUname
79  *
80  * Return the uname information.
81  *
82  * @param ichar The option string.
83  *
84  * @return Option information
85  */
87  SysUname,
88  OPTIONAL_CSTRING, ichar)
89 {
90  struct utsname name;
91 
92  uname(&name);
93  if (ichar == NULL || *ichar == 'S' || *ichar == 's') {
94  return (RexxObjectPtr)context->NewStringFromAsciiz(name.sysname);
95  }
96  else if (*ichar == 'N' || *ichar == 'n') {
97  return (RexxObjectPtr)context->NewStringFromAsciiz(name.nodename);
98  }
99  else if (*ichar == 'R' || *ichar == 'r') {
100  return (RexxObjectPtr)context->NewStringFromAsciiz(name.release);
101  }
102  else if (*ichar == 'V' || *ichar == 'v') {
103  return (RexxObjectPtr)context->NewStringFromAsciiz(name.version);
104  }
105  else if (*ichar == 'M' || *ichar == 'm') {
106  return (RexxObjectPtr)context->NewStringFromAsciiz(name.machine);
107  }
108  context->InvalidRoutine();
109  return context->NullString();
110 }
111 
112 
113 /**
114  * Method: SysSetsid
115  *
116  * Set the Session id.
117  *
118  * @return Process id
119  */
121  SysSetsid)
122 {
123  pid_t pid;
124 
125  pid = setsid();
126  return context->WholeNumberToObject((wholenumber_t)pid);
127 }
128 
129 
130 /**
131  * Method: SysGetsid
132  *
133  * Get the Session id.
134  *
135  * @param pid The pid.
136  *
137  * @return Session id
138  */
140  SysGetsid,
141  int, pid)
142 {
143  pid = getsid((pid_t)pid);
144  return context->WholeNumberToObject((wholenumber_t)pid);
145 }
146 
147 
148 /**
149  * Method: SysSetuid
150  *
151  * Set the userid.
152  *
153  * @param uid The userid.
154  *
155  * @return 0 or -1
156  */
158  SysSetuid,
159  int, uid)
160 {
161  setgroups(0, NULL);
162  return context->WholeNumberToObject((wholenumber_t)setuid((uid_t)uid));
163 }
164 
165 
166 /**
167  * Method: SysGetuid
168  *
169  * Get the userid.
170  *
171  * @return uid
172  */
174  SysGetuid)
175 {
176 
177  return context->WholeNumberToObject((wholenumber_t)getuid());
178 }
179 
180 
181 /**
182  * Method: SysSeteuid
183  *
184  * Set the effective userid.
185  *
186  * @param uid The userid.
187  *
188  * @return 0 or -1
189  */
191  SysSeteuid,
192  int, uid)
193 {
194 
195  return context->WholeNumberToObject((wholenumber_t)seteuid((uid_t)uid));
196 }
197 
198 
199 /**
200  * Method: SysGeteuid
201  *
202  * Get the effective userid.
203  *
204  * @return uid
205  */
207  SysGeteuid)
208 {
209 
210  return context->WholeNumberToObject((wholenumber_t)geteuid());
211 }
212 
213 
214 /**
215  * Method: SysSetgid
216  *
217  * Set the groupid.
218  *
219  * @param gid The groupid.
220  *
221  * @return 0 or -1
222  */
224  SysSetgid,
225  int, gid)
226 {
227 
228  return context->WholeNumberToObject((wholenumber_t)setgid((gid_t)gid));
229 }
230 
231 
232 /**
233  * Method: SysGetgid
234  *
235  * Get the groupid.
236  *
237  * @return 0 or -1
238  */
240  SysGetgid)
241 {
242 
243  return context->WholeNumberToObject((wholenumber_t)getgid());
244 }
245 
246 
247 /**
248  * Method: SysSetegid
249  *
250  * Set the effective groupid.
251  *
252  * @param gid The groupid.
253  *
254  * @return 0 or -1
255  */
257  SysSetegid,
258  int, gid)
259 {
260  return context->WholeNumberToObject((wholenumber_t)setegid((gid_t)gid));
261 }
262 
263 
264 /**
265  * Method: SysGetegid
266  *
267  * Get the effective groupid.
268  *
269  * @return 0 or -1
270  */
272  SysGetegid)
273 {
274 
275  return context->WholeNumberToObject((wholenumber_t)getegid());
276 }
277 
278 
279 /**
280  * Method: SysSetpgrp
281  *
282  * Set the pgrp.
283  *
284  * @return 0 or -1
285  */
287  SysSetpgrp)
288 {
289 #if defined(OPENBSD) || defined(OPSYS_NETBSD) || defined(OPSYS_FREEBSD)
290  return context->WholeNumberToObject((wholenumber_t)setpgrp(0, 0));
291 #else
292  return context->WholeNumberToObject((wholenumber_t)setpgrp());
293 #endif
294 }
295 
296 
297 /**
298  * Method: SysGetpgrp
299  *
300  * Get the pgrp.
301  *
302  * @return 0 or -1
303  */
305  SysGetpgrp)
306 {
307 
308  return context->WholeNumberToObject((wholenumber_t)getpgrp());
309 }
310 
311 
312 /**
313  * Method: SysSetpgid
314  *
315  * Set the pgid.
316  *
317  * @param pid1 The pid to set.
318  *
319  * @param pid2 The new pid.
320  *
321  * @return 0 or -1
322  */
324  SysSetpgid,
325  int, pid1,
326  int, pid2)
327 {
328 
329  return context->WholeNumberToObject((wholenumber_t)setpgid((pid_t)pid1, (pid_t)pid2));
330 }
331 
332 
333 /**
334  * Method: SysGetpgid
335  *
336  * Get the pgid.
337  *
338  * @param pid1 The pid to query.
339  *
340  * @return The pid.
341  */
343  SysGetpgid,
344  int, pid)
345 {
346 
347  return context->WholeNumberToObject((wholenumber_t)getpgid((pid_t)pid));
348 }
349 
350 
351 /**
352  * Method: SysGetpid
353  *
354  * Get the pid.
355  *
356  * @return pid
357  */
359  SysGetpid)
360 {
361  pid_t pid = getpid();
362  return context->WholeNumberToObject((wholenumber_t)pid);
363 }
364 
365 
366 /**
367  * Method: SysGetppid
368  *
369  * Get the ppid.
370  *
371  * @return pid
372  */
374  SysGetppid)
375 {
376  pid_t pid = getppid();
377  return context->WholeNumberToObject((wholenumber_t)pid);
378 }
379 
380 
381 /**
382  * Method: SysGettid
383  *
384  * Get the tid.
385  *
386  * @return tid
387  */
389  SysGettid)
390 {
391  pthread_t tid = pthread_self();
392  return context->UnsignedInt64ToObject((uint64_t)tid);
393 }
394 
395 
396 /**
397  * Method: SysKill
398  *
399  * Kill a process.
400  *
401  * @param pid1 The pid to kill.
402  *
403  * @param sig1 The signal to send.
404  *
405  * @return return code
406  */
408  SysKill,
409  int, pid1,
410  int, sig1)
411 {
412  return kill((pid_t)pid1, sig1);
413 }
414 
415 
416 /**
417  * Method: SysSymlink
418  *
419  * Create a symbolic link.
420  *
421  * @param path1 The source path.
422  *
423  * @param path2 The target path.
424  *
425  * @return int error code
426  */
428  SysSymlink,
429  CSTRING, path1,
430  CSTRING, path2)
431 {
432  return symlink(path1, path2);
433 }
434 
435 
436 /**
437  * Method: SysLink
438  *
439  * Create a hard link.
440  *
441  * @param path1 The source path.
442  *
443  * @param path2 The target path.
444  *
445  * @return int error code
446  */
448  SysLink,
449  CSTRING, path1,
450  CSTRING, path2)
451 {
452  return link(path1, path2);
453 }
454 
455 
456 /**
457  * Method: SysUnlink
458  *
459  * Remove a hard or soft link.
460  *
461  * @param path1 The source path.
462  *
463  * @return int error code
464  */
466  SysUnlink,
467  CSTRING, path1)
468 {
469  return unlink(path1);
470 }
471 
472 
473 /**
474  * Method: SysChown
475  *
476  * Change the owner and group of a file.
477  *
478  * @param path1 The file path.
479  *
480  * @param uid The new userid.
481  *
482  * @param gid The new groupid.
483  *
484  * @return int error code
485  */
487  SysChown,
488  CSTRING, path1,
489  int, uid,
490  int, gid)
491 {
492  return chown(path1, (uid_t)uid, (gid_t)gid);
493 }
494 
495 
496 /**
497  * Method: SysLchown
498  *
499  * Change the owner and group of a file.
500  *
501  * @param path1 The file path.
502  *
503  * @param uid The new userid.
504  *
505  * @param gid The new groupid.
506  *
507  * @return int error code
508  */
510  SysLchown,
511  CSTRING, path1,
512  int, uid,
513  int, gid)
514 {
515  return lchown(path1, (uid_t)uid, (gid_t)gid);
516 }
517 
518 
519 /**
520  * Method: SysChroot
521  *
522  * Changes the root directory of the calling process.
523  *
524  * @param path1 The new root path.
525  *
526  * @return int error code
527  */
529  SysChroot,
530  CSTRING, path1)
531 {
532  int ignore; // avoid warning: ignoring return value of 'int chdir(const char*)'
533 
534  ignore = chdir("/");
535  return chroot(path1);
536 }
537 
538 
539 /**
540  * Method: SysUmask
541  *
542  * Sets the calling process umask.
543  *
544  * @param nmask The new umask.
545  *
546  * @return the old umansk value
547  */
549  SysUmask,
550  int, nmask)
551 {
552  return umask((mode_t)nmask);
553 }
554 
555 
556 /**
557  * Method: SysClose
558  *
559  * Close a file handle.
560  *
561  * @param nmask The file handle to close.
562  *
563  * @return the return code from the C close function
564  */
566  SysClose,
567  int, fh)
568 {
569  return close(fh);
570 }
571 
572 
573 /**
574  * Method: SysGetpwnam
575  *
576  * Return user name information from the passwd file.
577  *
578  * @param user The user name.
579  *
580  * @param ichar The option string.
581  *
582  * @return Option information
583  */
585  SysGetpwnam,
586  CSTRING, user,
587  CSTRING, ichar)
588 {
589  if (strlen(user) == 0 || strlen(ichar) == 0) {
590  context->InvalidRoutine();
591  return context->NullString();
592  }
593  struct passwd *pw = getpwnam(user);
594  if (pw == NULL) {
595  return context->NullString();
596  }
597  else if (*ichar == 'N' || *ichar == 'n') {
598  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_name);
599  }
600  else if (*ichar == 'U' || *ichar == 'u') {
601  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)pw->pw_uid);
602  }
603  else if (*ichar == 'G' || *ichar == 'g') {
604  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)pw->pw_gid);
605  }
606  else if (*ichar == 'R' || *ichar == 'r') {
607  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_gecos);
608  }
609  else if (*ichar == 'D' || *ichar == 'd') {
610  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_dir);
611  }
612  else if (*ichar == 'S' || *ichar == 's') {
613  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_shell);
614  }
615  else if (*ichar == 'P' || *ichar == 'p') {
616  return context->NullString();
617  }
618  context->InvalidRoutine();
619  return context->NullString();
620 }
621 
622 
623 /**
624  * Method: SysGetpwuid
625  *
626  * Return user name information from the passwd file.
627  *
628  * @param user The uid.
629  *
630  * @param ichar The option string.
631  *
632  * @return Option information
633  */
635  SysGetpwuid,
636  int, uid,
637  CSTRING, ichar)
638 {
639  if (strlen(ichar) == 0) {
640  context->InvalidRoutine();
641  return context->NullString();
642  }
643  struct passwd *pw = getpwuid((uid_t)uid);
644  if (pw == NULL) {
645  return context->NullString();
646  }
647  else if (*ichar == 'N' || *ichar == 'n') {
648  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_name);
649  }
650  else if (*ichar == 'U' || *ichar == 'u') {
651  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)pw->pw_uid);
652  }
653  else if (*ichar == 'G' || *ichar == 'g') {
654  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)pw->pw_gid);
655  }
656  else if (*ichar == 'R' || *ichar == 'r') {
657  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_gecos);
658  }
659  else if (*ichar == 'D' || *ichar == 'd') {
660  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_dir);
661  }
662  else if (*ichar == 'S' || *ichar == 's') {
663  return (RexxObjectPtr)context->NewStringFromAsciiz(pw->pw_shell);
664  }
665  else if (*ichar == 'P' || *ichar == 'p') {
666  return context->NullString();
667  }
668  context->InvalidRoutine();
669  return context->NullString();
670 }
671 
672 
673 /**
674  * Method: SysGetgrnam
675  *
676  * Return group name information from the group file.
677  *
678  * @param user The group name.
679  *
680  * @param ichar The option string.
681  *
682  * @return Option information
683  */
685  SysGetgrnam,
686  CSTRING, grpname,
687  CSTRING, ichar)
688 {
689  if (strlen(grpname) == 0 || strlen(ichar) == 0) {
690  context->InvalidRoutine();
691  return context->NullString();
692  }
693  struct group *gr = getgrnam(grpname);
694  if (*ichar == 'N' || *ichar == 'n') {
695  return (RexxObjectPtr)context->NewStringFromAsciiz(gr->gr_name);
696  }
697  else if (*ichar == 'P' || *ichar == 'p') {
698  return context->NullString();
699  }
700  else if (*ichar == 'G' || *ichar == 'g') {
701  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)gr->gr_gid);
702  }
703  else if (*ichar == 'M' || *ichar == 'm') {
704  RexxArrayObject arr = context->NewArray(1);
705  char **members = gr->gr_mem;
706  while (*members != NULL) {
707  context->ArrayAppendString(arr, *members, strlen(*members));
708  members++;
709  }
710  return (RexxObjectPtr)arr;
711  }
712  context->InvalidRoutine();
713  return context->NullString();
714 }
715 
716 
717 /**
718  * Method: SysGetgrgid
719  *
720  * Return group name information from the group file.
721  *
722  * @param user The gid.
723  *
724  * @param ichar The option string.
725  *
726  * @return Option information
727  */
729  SysGetgrgid,
730  int, gid,
731  CSTRING, ichar)
732 {
733  if (strlen(ichar) == 0) {
734  context->InvalidRoutine();
735  return context->NullString();
736  }
737  struct group *gr = getgrgid(gid);
738  if (*ichar == 'N' || *ichar == 'n') {
739  return (RexxObjectPtr)context->NewStringFromAsciiz(gr->gr_name);
740  }
741  else if (*ichar == 'P' || *ichar == 'p') {
742  return context->NullString();
743  }
744  else if (*ichar == 'G' || *ichar == 'g') {
745  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)gr->gr_gid);
746  }
747  else if (*ichar == 'M' || *ichar == 'm') {
748  RexxArrayObject arr = context->NewArray(1);
749  char **members = gr->gr_mem;
750  while (*members != NULL) {
751  context->ArrayAppendString(arr, *members, strlen(*members));
752  members++;
753  }
754  return (RexxObjectPtr)arr;
755  }
756  context->InvalidRoutine();
757  return context->NullString();
758 }
759 
760 
761 /**
762  * Method: SysStat
763  *
764  * Return information from the stat API.
765  *
766  * @param user The file name.
767  *
768  * @param ichar The option string.
769  *
770  * @return Option information
771  */
773  SysStat,
774  CSTRING, fname,
775  CSTRING, ichar)
776 {
777  struct tm *ftime;
778  struct stat64 st;
779  char buf[32]; // used for both the file times and the permissions
780 
781  if (strlen(fname) == 0 || strlen(ichar) == 0) {
782  context->InvalidRoutine();
783  return context->NullString();
784  }
785  int retc = stat64(fname, &st);
786  if (retc != 0) {
787  return context->NullString();
788  }
789  else if (*ichar == 'D' || *ichar == 'd') {
790  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)st.st_dev);
791  }
792  else if (*ichar == 'I' || *ichar == 'i') {
793  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)st.st_ino);
794  }
795  else if (*ichar == 'P' || *ichar == 'p') {
796  // 1- file type
797  if (S_ISREG(st.st_mode)) strcpy(buf, "-");
798  else if (S_ISDIR(st.st_mode)) strcpy(buf, "d");
799  else if (S_ISLNK(st.st_mode)) strcpy(buf, "l");
800  else if (S_ISSOCK(st.st_mode)) strcpy(buf, "s");
801  else if (S_ISCHR(st.st_mode)) strcpy(buf, "c");
802  else if (S_ISBLK(st.st_mode)) strcpy(buf, "b");
803  else if (S_ISFIFO(st.st_mode)) strcpy(buf, "p");
804 
805  // 2 - user read
806  strcat(buf, S_IRUSR & st.st_mode ? "r" : "-");
807 
808  // 3 - user write
809  strcat(buf, S_IWUSR & st.st_mode ? "w" : "-");
810 
811  // 4 - user execute
812  // SUID If set, then replaces "x" in the owner permissions to "s",
813  // if owner has execute permissions, or to "S" otherwise. Examples:
814  // -rws------ both owner execute and SUID are set
815  // -r-S------ SUID is set, but owner execute is not set
816  strcat(buf, S_ISUID & st.st_mode ? (S_IXUSR & st.st_mode ? "s" : "S") : (S_IXUSR & st.st_mode ? "x" : "-"));
817 
818  // 5 -group read
819  strcat(buf, S_IRGRP & st.st_mode ? "r" : "-");
820 
821  // 6 - group write
822  strcat(buf, S_IWGRP & st.st_mode ? "w" : "-");
823 
824  // 7 - group execute
825  // SGID If set, then replaces "x" in the group permissions to "s",
826  // if group has execute permissions, or to "S" otherwise. Examples:
827  // -rwxrws--- both group execute and SGID are set
828  // -rwxr-S--- SGID is set, but group execute is not set
829  strcat(buf, S_ISGID & st.st_mode ? (S_IXGRP & st.st_mode ? "s" : "S") : (S_IXGRP & st.st_mode ? "x" : "-"));
830 
831  // 8 - other read
832  strcat(buf, S_IROTH & st.st_mode ? "r" : "-");
833 
834  // 9 - other write
835  strcat(buf, S_IWOTH & st.st_mode ? "w" : "-");
836 
837  // 10 - other execute
838  // Sticky If set, then replaces "x" in the others permissions to "t",
839  // if others have execute permissions, or to "T" otherwise. Examples:
840  // -rwxrwxrwt both others execute and sticky bit are set
841  // -rwxrwxr-T sticky bit is set, but others execute is not set
842  strcat(buf, S_ISVTX & st.st_mode ? (S_IXOTH & st.st_mode ? "t" : "T") : (S_IXOTH & st.st_mode ? "x" : "-"));
843 
844  return (RexxObjectPtr)context->NewStringFromAsciiz(buf);
845  }
846  else if (*ichar == 'N' || *ichar == 'n') {
847  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)st.st_nlink);
848  }
849  else if (*ichar == 'U' || *ichar == 'u') {
850  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)st.st_uid);
851  }
852  else if (*ichar == 'G' || *ichar == 'g') {
853  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)st.st_gid);
854  }
855  else if (*ichar == 'R' || *ichar == 'r') {
856  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)st.st_rdev);
857  }
858  else if (*ichar == 'S' || *ichar == 's') {
859  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)st.st_size);
860  }
861  else if (*ichar == 'A' || *ichar == 'a') {
862  ftime = localtime(&st.st_atime);
863  strftime(buf, sizeof(buf), "%F %T", ftime);
864  return (RexxObjectPtr)context->NewStringFromAsciiz(buf);
865  }
866  else if (*ichar == 'M' || *ichar == 'm') {
867  ftime = localtime(&st.st_mtime);
868  strftime(buf, sizeof(buf), "%F %T", ftime);
869  return (RexxObjectPtr)context->NewStringFromAsciiz(buf);
870  }
871  else if (*ichar == 'C' || *ichar == 'c') {
872  ftime = localtime(&st.st_ctime);
873  strftime(buf, sizeof(buf), "%F %T", ftime);
874  return (RexxObjectPtr)context->NewStringFromAsciiz(buf);
875  }
876  context->InvalidRoutine();
877  return context->NullString();
878 }
879 
880 
881 /**
882  * Method: SysAccess
883  *
884  * Return access information.
885  *
886  * @param file The file specification.
887  *
888  * @param ichar The integer option.
889  *
890  * @return 0 = access allowed.
891  */
893  SysAccess,
894  CSTRING, file,
895  int, option)
896 {
897 
898  return access(file, option);
899 }
900 
901 
902 #if defined (HAVE_EUIDACCESS)
903 /**
904  * Method: SysEuidaccess
905  *
906  * Return access information using the effective userid.
907  *
908  * @param file The file specification.
909  *
910  * @param ichar The integer option.
911  *
912  * @return 0 = access allowed.
913  */
914 RexxRoutine2(int,
915  SysEuidaccess,
916  CSTRING, file,
917  int, option)
918 {
919 
920  return euidaccess(file, option);
921 }
922 #endif
923 
924 /**
925  * Method: SysGetservbyname
926  *
927  * Return service information from the services file.
928  *
929  * @param name The service name.
930  *
931  * @param proto The service protocol.
932  *
933  * @param option The option string.
934  *
935  * @return Option information
936  */
938  SysGetservbyname,
939  CSTRING, name,
940  CSTRING, proto,
941  CSTRING, ichar)
942 {
943  if (strlen(name) == 0 || strlen(proto) == 0) {
944  context->InvalidRoutine();
945  return context->NullString();
946  }
947  struct servent *se = getservbyname(name, proto);
948  if (se == NULL) {
949  return context->NullString();
950  }
951  if (*ichar == 'N' || *ichar == 'n') {
952  return (RexxObjectPtr)context->NewStringFromAsciiz(se->s_name);
953  }
954  else if (*ichar == 'P' || *ichar == 'p') {
955  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)ntohs(se->s_port));
956  }
957  else if (*ichar == 'A' || *ichar == 'a') {
958  RexxArrayObject arr = context->NewArray(1);
959  char **members = se->s_aliases;
960  while (*members != NULL) {
961  context->ArrayAppendString(arr, *members, strlen(*members));
962  members++;
963  }
964  return (RexxObjectPtr)arr;
965  }
966  context->InvalidRoutine();
967  return context->NullString();
968 }
969 
970 
971 /**
972  * Method: SysGetservbyport
973  *
974  * Return service information from the services file.
975  *
976  * @param port The service port.
977  *
978  * @param proto The service protocol.
979  *
980  * @param option The option string.
981  *
982  * @return Option information
983  */
985  SysGetservbyport,
986  int, port,
987  CSTRING, proto,
988  CSTRING, ichar)
989 {
990  if (port <= 0 || port >= 65535 || strlen(proto) == 0) {
991  context->InvalidRoutine();
992  return context->NullString();
993  }
994  struct servent *se = getservbyport(htons(port), proto);
995  if (se == NULL) {
996  return context->NullString();
997  }
998  else if (*ichar == 'N' || *ichar == 'n') {
999  return (RexxObjectPtr)context->NewStringFromAsciiz(se->s_name);
1000  }
1001  else if (*ichar == 'P' || *ichar == 'p') {
1002  return (RexxObjectPtr)context->WholeNumberToObject((wholenumber_t)ntohs(se->s_port));
1003  }
1004  else if (*ichar == 'A' || *ichar == 'a') {
1005  RexxArrayObject arr = context->NewArray(1);
1006  char **members = se->s_aliases;
1007  while (*members != NULL) {
1008  context->ArrayAppendString(arr, *members, strlen(*members));
1009  members++;
1010  }
1011  return (RexxObjectPtr)arr;
1012  }
1013  context->InvalidRoutine();
1014  return context->NullString();
1015 }
1016 
1017 
1018 /**
1019  * Method: SysWordexp
1020  *
1021  * Return an array of files matching the input expression.
1022  *
1023  * @param inexp The input expression.
1024  *
1025  * @return Array of file names.
1026  */
1027 #if !defined(OPENBSD)
1029  SysWordexp,
1030  CSTRING, inexp)
1031 {
1032  wordexp_t p;
1033  char **w;
1034  if (strlen(inexp) == 0) {
1035  context->InvalidRoutine();
1036  return context->NullString();
1037  }
1038  RexxArrayObject arr = context->NewArray(1);
1039 
1040  wordexp(inexp, &p, 0);
1041 
1042  w = p.we_wordv;
1043  for (int i = 0; i < p.we_wordc; i++) {
1044  context->ArrayAppendString(arr, w[i], strlen(w[i]));
1045  }
1046  wordfree(&p);
1047  return (RexxObjectPtr)arr;
1048 }
1049 #endif
1050 
1051 
1052 #ifdef HAVE_XATTR
1053 /**
1054  * Method: SysSetxattr
1055  *
1056  * Set a file extended attribute.
1057  *
1058  * @param fname The file name.
1059  *
1060  * @param name The extended attribute name.
1061  *
1062  * @param val The extended attribute value.
1063  *
1064  * @return 0 or -1.
1065  */
1066 RexxRoutine3(int,
1067  SysSetxattr,
1068  CSTRING, fname,
1069  CSTRING, name,
1070  CSTRING, val)
1071 {
1072  return SetXattr(fname, name, val, strlen(val) + 1, 0);
1073 }
1074 
1075 
1076 /**
1077  * Method: SysGetxattr
1078  *
1079  * Get a file extended attribute.
1080  *
1081  * @param fname The file name.
1082  *
1083  * @param name The extended attribute name.
1084  *
1085  * @return 0 or -1.
1086  */
1088  SysGetxattr,
1089  CSTRING, fname,
1090  CSTRING, name)
1091 {
1092  ssize_t sz;
1093  char *buf;
1094 
1095  sz = GetXattr(fname, name, NULL, 0);
1096  if (sz == -1) {
1097  return context->NullString();
1098  }
1099  buf = (char *)alloca(sz);
1100  GetXattr(fname, name, buf, sz);
1101 
1102  return (RexxObjectPtr)context->NewStringFromAsciiz(buf);
1103 }
1104 
1105 
1106 /**
1107  * Method: SysListxattr
1108  *
1109  * List a file's extended attribute(s).
1110  *
1111  * @param fname The file name.
1112  *
1113  * @return 0 or -1.
1114  */
1116  SysListxattr,
1117  CSTRING, fname)
1118 {
1119  ssize_t sz;
1120  char *buf, *name;
1121 
1122  sz = ListXattr(fname, NULL, 0);
1123  if (sz == -1) {
1124  return context->NullString();
1125  }
1126  buf = (char *)alloca(sz);
1127  ListXattr(fname, buf, sz);
1128 
1129  // create a Rexx array of the xattr names
1130  RexxArrayObject arr = context->NewArray(1);
1131  while (sz > 0) {
1132  context->ArrayAppendString(arr, buf, strlen(buf));
1133  sz -= strlen(buf) + 1;
1134  buf += strlen(buf) + 1;
1135  }
1136 
1137  return (RexxObjectPtr)arr;
1138 }
1139 
1140 
1141 /**
1142  * Method: SysRemovexattr
1143  *
1144  * Remove an extended attribute.
1145  *
1146  * @param fname The file name.
1147  *
1148  * @param name The extended attribute name.
1149  *
1150  * @return 0 or -1.
1151  */
1152 RexxRoutine2(int,
1153  SysRemovexattr,
1154  CSTRING, fname,
1155  CSTRING, name)
1156 {
1157 
1158 
1159  return RemoveXattr(fname, name);
1160 }
1161 #endif
1162 
1163 
1164 /**
1165  * Method: SysGetsizeofptr
1166  *
1167  * Get the size of the ooRexx application pointers (in bits).
1168  *
1169  * @return 32 or 64.
1170  */
1172  SysGetsizeofptr)
1173 {
1174 
1175 
1176  return sizeof(void *) * 8;
1177 }
1178 
1179 
1180 /**
1181  * Method: SysGethostname
1182  *
1183  * Get the machine hostname.
1184  *
1185  * @return hostname.
1186  */
1188  SysGethostname)
1189 {
1190  char hostname[HOST_NAME_MAX];
1191 
1192  gethostname(hostname, HOST_NAME_MAX);
1193  return (RexxObjectPtr)context->NewStringFromAsciiz(hostname);
1194 }
1195 
1196 
1197 /**
1198  * Method: SysChmod
1199  *
1200  * Change the file permissions.
1201  *
1202  * @param usr The user permissions.
1203  *
1204  * @param grp The group permissions.
1205  *
1206  * @param oth The other permissions.
1207  *
1208  * @return Return code from chmod().
1209  */
1211  SysChmod,
1212  CSTRING, file,
1213  CSTRING, mode)
1214 {
1215  mode_t perm = 0;
1216 
1217  // make sure the mode is the correct size
1218  if (strlen(mode) != 9) {
1219  context->InvalidRoutine();
1220  return -1;
1221  }
1222 
1223  // set usr bits
1224  if (mode[0] == 'r') {
1225  perm |= S_IRUSR;
1226  }
1227  else if (mode[0] == '-') {
1228  }
1229  else {
1230  context->InvalidRoutine();
1231  return -1;
1232  }
1233  if (mode[1] == 'w') {
1234  perm |= S_IWUSR;
1235  }
1236  else if (mode[1] == '-') {
1237  }
1238  else {
1239  context->InvalidRoutine();
1240  return -1;
1241  }
1242  if (mode[2] == 'x') {
1243  perm |= S_IXUSR;
1244  }
1245  else if (mode[2] == 'S') {
1246  perm |= S_ISUID;
1247  }
1248  else if (mode[2] == 's') {
1249  perm |= S_IXUSR;
1250  perm |= S_ISUID;
1251  }
1252  else if (mode[2] == '-') {
1253  }
1254  else {
1255  context->InvalidRoutine();
1256  return -1;
1257  }
1258 
1259  // set grp bits
1260  if (mode[3] == 'r') {
1261  perm |= S_IRGRP;
1262  }
1263  else if (mode[3] == '-') {
1264  }
1265  else {
1266  context->InvalidRoutine();
1267  return -1;
1268  }
1269  if (mode[4] == 'w') {
1270  perm |= S_IWGRP;
1271  }
1272  else if (mode[4] == '-') {
1273  }
1274  else {
1275  context->InvalidRoutine();
1276  return -1;
1277  }
1278  if (mode[5] == 'x') {
1279  perm |= S_IXGRP;
1280  }
1281  else if (mode[5] == 'S') {
1282  perm |= S_ISGID;
1283  }
1284  else if (mode[5] == 's') {
1285  perm |= S_IXGRP;
1286  perm |= S_ISGID;
1287  }
1288  else if (mode[5] == '-') {
1289  }
1290  else {
1291  context->InvalidRoutine();
1292  return -1;
1293  }
1294 
1295  // set oth bits
1296  if (mode[6] == 'r') {
1297  perm |= S_IROTH;
1298  }
1299  else if (mode[6] == '-') {
1300  }
1301  else {
1302  context->InvalidRoutine();
1303  return -1;
1304  }
1305  if (mode[7] == 'w') {
1306  perm |= S_IWOTH;
1307  }
1308  else if (mode[7] == '-') {
1309  }
1310  else {
1311  context->InvalidRoutine();
1312  return -1;
1313  }
1314  if (mode[8] == 'x') {
1315  perm |= S_IXOTH;
1316  }
1317  else if (mode[8] == 'T') {
1318  perm |= S_ISVTX;
1319  }
1320  else if (mode[8] == 't') {
1321  perm |= S_IXOTH;
1322  perm |= S_ISVTX;
1323  }
1324  else if (mode[8] == '-') {
1325  }
1326  else {
1327  context->InvalidRoutine();
1328  return -1;
1329  }
1330 
1331  return chmod(file, perm);
1332 }
1333 
1334 
1335 /**
1336  * Method: SysGeterrno
1337  *
1338  * Get the errno value.
1339  *
1340  * @return errno.
1341  */
1343  SysGeterrno)
1344 {
1345 
1346  return errno;
1347 }
1348 
1349 
1350 /**
1351  * Method: SysGeterrnomsg
1352  *
1353  * Get the string definition of an error number.
1354  *
1355  * @return string.
1356  */
1358  SysGeterrnomsg,
1359  int, en)
1360 {
1361  static const char *msgs[] = {
1362  "Ok",
1363  "Operation not permitted",
1364  "No such file or directory",
1365  "No such process",
1366  "Interrupted system call",
1367  "I/O error",
1368  "No such device or address",
1369  "Argument list too long",
1370  "Exec format error",
1371  "Bad file number",
1372  "No child processes",
1373  "Try again",
1374  "Out of memory",
1375  "Permission denied",
1376  "Bad address",
1377  "Block device required",
1378  "Device or resource busy",
1379  "File exists",
1380  "Cross-device link",
1381  "No such device",
1382  "Not a directory",
1383  "Is a directory",
1384  "Invalid argument",
1385  "File table overflow",
1386  "Too many open files",
1387  "Not a typewriter",
1388  "Text file busy",
1389  "File too large",
1390  "No space left on device",
1391  "Illegal seek",
1392  "Read-only file system",
1393  "Too many links",
1394  "Broken pipe",
1395  "Math argument out of domain of func",
1396  "Math result not representable",
1397  "Resource deadlock would occur",
1398  "File name too long",
1399  "No record locks available",
1400  "Function not implemented",
1401  "Directory not empty",
1402  "Too many symbolic links encountered",
1403  "Operation would block",
1404  "No message of desired type",
1405  "Identifier removed",
1406  "Channel number out of range",
1407  "Level 2 not synchronized",
1408  "Level 3 halted",
1409  "Level 3 reset",
1410  "Link number out of range",
1411  "Protocol driver not attached",
1412  "No CSI structure available",
1413  "Level 2 halted",
1414  "Invalid exchange",
1415  "Invalid request descriptor",
1416  "Exchange full",
1417  "No anode",
1418  "Invalid request code",
1419  "Invalid slot",
1420  "Deadlock",
1421  "Bad font file format",
1422  "Device not a stream",
1423  "No data available",
1424  "Timer expired",
1425  "Out of streams resources",
1426  "Machine is not on the network",
1427  "Package not installed",
1428  "Object is remote",
1429  "Link has been severed",
1430  "Advertise error",
1431  "Srmount error",
1432  "Communication error on send",
1433  "Protocol error",
1434  "Multihop attempted",
1435  "RFS specific error",
1436  "Not a data message",
1437  "Value too large for defined data type",
1438  "Name not unique on network",
1439  "File descriptor in bad state",
1440  "Remote address changed",
1441  "Can not access a needed shared library",
1442  "Accessing a corrupted shared library",
1443  ".lib section in a.out corrupted",
1444  "Attempting to link in too many shared libraries",
1445  "Cannot exec a shared library directly",
1446  "Illegal byte sequence",
1447  "Interrupted system call should be restarted",
1448  "Streams pipe error",
1449  "Too many users",
1450  "Socket operation on non-socket",
1451  "Destination address required",
1452  "Message too long",
1453  "Protocol wrong type for socket",
1454  "Protocol not available",
1455  "Protocol not supported",
1456  "Socket type not supported",
1457  "Operation not supported on transport endpoint",
1458  "Protocol family not supported",
1459  "Address family not supported by protocol",
1460  "Address already in use",
1461  "Cannot assign requested address",
1462  "Network is down",
1463  "Network is unreachable",
1464  "Network dropped connection because of reset",
1465  "Software caused connection abort",
1466  "Connection reset by peer",
1467  "No buffer space available",
1468  "Transport endpoint is already connected",
1469  "Transport endpoint is not connected",
1470  "Cannot send after transport endpoint shutdown",
1471  "Too many references: cannot splice",
1472  "Connection timed out",
1473  "Connection refused",
1474  "Host is down",
1475  "No route to host",
1476  "Operation already in progress",
1477  "Operation now in progress",
1478  "Stale NFS file handle",
1479  "Structure needs cleaning",
1480  "Not a XENIX named type file",
1481  "No XENIX semaphores available",
1482  "Is a named type file",
1483  "Remote I/O error",
1484  "Quota exceeded",
1485  "No medium found",
1486  "Wrong medium type",
1487  "Operation Canceled",
1488  "Required key not available",
1489  "Key has expired",
1490  "Key has been revoked",
1491  "Key was rejected by service",
1492  "Owner died",
1493  "State not recoverable",
1494  "Operation not possible due to RF-kill",
1495  };
1496 
1497  if (en >= sizeof(msgs) / sizeof(char *)) {
1498  return (RexxObjectPtr)context->NewStringFromAsciiz("Unknown");
1499  }
1500  return (RexxObjectPtr)context->NewStringFromAsciiz(msgs[en]);
1501 }
1502 
1503 
1504 /**
1505  * Method: SysCrypt
1506  *
1507  * Encrypt a string.
1508  *
1509  * @param str The string to encrypt.
1510  *
1511  * @param salt The salt: two characters for the default DES encryption,
1512  * other salt lengths may be available depending on the Unix platform
1513  * for other encryption algorithms (MD5, Blowfish, SHA-256, SHA-512)
1514  *
1515  * @return Encrypted string.
1516  */
1518  SysCrypt,
1519  CSTRING, str,
1520  CSTRING, salt)
1521 {
1522  char *es;
1523 
1524  if (strlen(str) == 0)
1525  {
1526  context->RaiseException2(Rexx_Error_Incorrect_call_null,
1527  context->String("SYSCRYPT"), context->String("1"));
1528  return context->NullString();
1529  }
1530  if (strlen(salt) == 0)
1531  {
1532  context->RaiseException2(Rexx_Error_Incorrect_call_null,
1533  context->String("SYSCRYPT"), context->String("2"));
1534  return context->NullString();
1535  }
1536 
1537  es = crypt(str, salt);
1538  if (es == NULL) {
1539  return context->NullString();
1540  }
1541  return (RexxObjectPtr)context->NewStringFromAsciiz(es);
1542 }
1543 
1544 
1545 /**
1546  * Method: SysMkdir
1547  *
1548  * Create a subdirectory.
1549  *
1550  * @param dir The subdirectory to create.
1551  *
1552  * @param mode The mode for the new subdirectory.
1553  *
1554  * @return 0 or -1.
1555  */
1557  SysMkdir,
1558  CSTRING, dir,
1559  int, mode)
1560 {
1561  return mkdir(dir, mode);
1562 }
1563 
1564 
1565 /**
1566  * Method: SysRmdir
1567  *
1568  * Remove a subdirectory.
1569  *
1570  * @param dir The subdirectory to remove.
1571  *
1572  * @return 0 or -1.
1573  */
1575  SysRmdir,
1576  CSTRING, dir)
1577 {
1578  return rmdir(dir);
1579 }
1580 
1581 
1582 /**
1583  * Method: SysGetdirlist
1584  *
1585  * Return the list of files in a subdirectory.
1586  *
1587  * @param dir The subdirectory to use.
1588  *
1589  * @return RexxArrayObject.
1590  */
1592  SysGetdirlist,
1593  CSTRING, dir)
1594 {
1595  RexxArrayObject arr = context->NewArray(5);
1596  DIR *dirptr;
1597  struct dirent *direntry;
1598 
1599  dirptr = opendir(dir);
1600  if (dirptr != NULL) {
1601  direntry = readdir(dirptr);
1602  while (direntry != NULL) {
1603  context->ArrayAppendString(arr, direntry->d_name, strlen(direntry->d_name));
1604  direntry = readdir(dirptr);
1605  }
1606  closedir(dirptr);
1607  }
1608  return (RexxObjectPtr)arr;
1609 }
1610 
1611 
1612 /**
1613  * Method: SysGettzname1
1614  *
1615  * Return the timezone name.
1616  *
1617  * @return RexxStringObject.
1618  */
1620  SysGettzname1)
1621 {
1622 
1623  tzset();
1624  return (RexxObjectPtr)context->NewStringFromAsciiz(tzname[0]);
1625 }
1626 
1627 
1628 /**
1629  * Method: SysGettzname2
1630  *
1631  * Return the altername timezone name.
1632  *
1633  * @return RexxStringObject.
1634  */
1636  SysGettzname2)
1637 {
1638 
1639  tzset();
1640  return (RexxObjectPtr)context->NewStringFromAsciiz(tzname[1]);
1641 }
1642 
1643 
1644 // initialize the libvirt library
1645 static void orxnixclib_loader(RexxThreadContext *context) {
1646  }
1647 
1648 
1649 // build the actual entry list
1651  REXX_TYPED_ROUTINE(SysSignal, SysSignal),
1652  REXX_TYPED_ROUTINE(SysUname, SysUname),
1653  REXX_TYPED_ROUTINE(SysSetsid, SysSetsid),
1654  REXX_TYPED_ROUTINE(SysGetsid, SysGetsid),
1655  REXX_TYPED_ROUTINE(SysSetuid, SysSetuid),
1656  REXX_TYPED_ROUTINE(SysGetuid, SysGetuid),
1657  REXX_TYPED_ROUTINE(SysSeteuid, SysSeteuid),
1658  REXX_TYPED_ROUTINE(SysGeteuid, SysGeteuid),
1659  REXX_TYPED_ROUTINE(SysSetgid, SysSetgid),
1660  REXX_TYPED_ROUTINE(SysGetgid, SysGetgid),
1661  REXX_TYPED_ROUTINE(SysSetegid, SysSetegid),
1662  REXX_TYPED_ROUTINE(SysGetegid, SysGetegid),
1663  REXX_TYPED_ROUTINE(SysSetpgrp, SysSetpgrp),
1664  REXX_TYPED_ROUTINE(SysGetpgrp, SysGetpgrp),
1665  REXX_TYPED_ROUTINE(SysSetpgid, SysSetpgid),
1666  REXX_TYPED_ROUTINE(SysGetpgid, SysGetpgid),
1667  REXX_TYPED_ROUTINE(SysGetpid, SysGetpid),
1668  REXX_TYPED_ROUTINE(SysGetppid, SysGetppid),
1669  REXX_TYPED_ROUTINE(SysGettid, SysGettid),
1670  REXX_TYPED_ROUTINE(SysKill, SysKill),
1671  REXX_TYPED_ROUTINE(SysSymlink, SysSymlink),
1672  REXX_TYPED_ROUTINE(SysLink, SysLink),
1673  REXX_TYPED_ROUTINE(SysUnlink, SysUnlink),
1674  REXX_TYPED_ROUTINE(SysChown, SysChown),
1675  REXX_TYPED_ROUTINE(SysLchown, SysLchown),
1676  REXX_TYPED_ROUTINE(SysChroot, SysChroot),
1677  REXX_TYPED_ROUTINE(SysUmask, SysUmask),
1678  REXX_TYPED_ROUTINE(SysClose, SysClose),
1679  REXX_TYPED_ROUTINE(SysGetpwnam, SysGetpwnam),
1680  REXX_TYPED_ROUTINE(SysGetpwuid, SysGetpwuid),
1681  REXX_TYPED_ROUTINE(SysGetgrnam, SysGetgrnam),
1682  REXX_TYPED_ROUTINE(SysGetgrgid, SysGetgrgid),
1683  REXX_TYPED_ROUTINE(SysStat, SysStat),
1684  REXX_TYPED_ROUTINE(SysAccess, SysAccess),
1685 #if defined (HAVE_EUIDACCESS)
1686  REXX_TYPED_ROUTINE(SysEuidaccess, SysEuidaccess),
1687 #endif
1688  REXX_TYPED_ROUTINE(SysGetservbyname, SysGetservbyname),
1689  REXX_TYPED_ROUTINE(SysGetservbyport, SysGetservbyport),
1690 #ifdef HAVE_WORDEXP
1691  REXX_TYPED_ROUTINE(SysWordexp, SysWordexp),
1692 #endif
1693 #ifdef HAVE_XATTR
1694  REXX_TYPED_ROUTINE(SysSetxattr, SysSetxattr),
1695  REXX_TYPED_ROUTINE(SysGetxattr, SysGetxattr),
1696  REXX_TYPED_ROUTINE(SysListxattr, SysListxattr),
1697  REXX_TYPED_ROUTINE(SysRemovexattr, SysRemovexattr),
1698 #endif
1699  REXX_TYPED_ROUTINE(SysGetsizeofptr, SysGetsizeofptr),
1700  REXX_TYPED_ROUTINE(SysGethostname, SysGethostname),
1701  REXX_TYPED_ROUTINE(SysChmod, SysChmod),
1702  REXX_TYPED_ROUTINE(SysGeterrno, SysGeterrno),
1703  REXX_TYPED_ROUTINE(SysGeterrnomsg, SysGeterrnomsg),
1704  REXX_TYPED_ROUTINE(SysCrypt, SysCrypt),
1705  REXX_TYPED_ROUTINE(SysMkdirUnix, SysMkdir),
1706  REXX_TYPED_ROUTINE(SysRmdirUnix, SysRmdir),
1707  REXX_TYPED_ROUTINE(SysGetdirlist, SysGetdirlist),
1708  REXX_TYPED_ROUTINE(SysGettzname1, SysGettzname1),
1709  REXX_TYPED_ROUTINE(SysGettzname2, SysGettzname2),
1711 };
1712 
1713 
1714 // build the actual entry list
1717 };
1718 
1719 
1722  REXX_INTERPRETER_4_0_0, // anything after 4.0.0 will work
1723  "rxunixsys", // name of the package
1724  "1.0.0", // package information
1725  orxnixclib_loader, // load function
1726  NULL, // unload function
1727  orxnixclib_routines, // the exported routines
1728  orxnixclib_methods // the exported methods
1729 };
1730 
1731 // package loading stub.
#define REXX_INTERPRETER_4_0_0
Definition: oorexxapi.h:216
#define REXX_LAST_ROUTINE()
Definition: oorexxapi.h:193
#define REXX_LAST_METHOD()
Definition: oorexxapi.h:212
#define REXX_TYPED_ROUTINE(n, e)
Definition: oorexxapi.h:191
#define STANDARD_PACKAGE_HEADER
Definition: oorexxapi.h:230
#define Rexx_Error_Incorrect_call_null
Definition: oorexxerrors.h:382
const char * CSTRING
Definition: rexx.h:78
struct _RexxArrayObject * RexxArrayObject
Definition: rexx.h:130
struct _RexxObjectPtr * RexxObjectPtr
Definition: rexx.h:127
ssize_t wholenumber_t
Definition: rexx.h:230
RexxRoutine3(int, SysChown, CSTRING, path1, int, uid, int, gid)
Definition: rxunixsys.cpp:486
RexxMethodEntry orxnixclib_methods[]
Definition: rxunixsys.cpp:1715
RexxRoutineEntry orxnixclib_routines[]
Definition: rxunixsys.cpp:1650
RexxRoutine0(RexxObjectPtr, SysSetsid)
Definition: rxunixsys.cpp:120
RexxRoutine1(RexxObjectPtr, SysUname, OPTIONAL_CSTRING, ichar)
Definition: rxunixsys.cpp:86
RexxRoutine2(int, SysSignal, int, signum, CSTRING, sigact)
Definition: rxunixsys.cpp:53
static void orxnixclib_loader(RexxThreadContext *context)
Definition: rxunixsys.cpp:1645
RexxPackageEntry orxnixclib_package_entry
Definition: rxunixsys.cpp:1720
OOREXX_GET_PACKAGE(orxnixclib)
#define RemoveXattr
Definition: rxunixsys.h:94
#define ListXattr
Definition: rxunixsys.h:95
#define GetXattr
Definition: rxunixsys.h:92
#define SetXattr
Definition: rxunixsys.h:93
Definition: oorexxapi.h:198
Definition: oorexxapi.h:242
Definition: oorexxapi.h:177
SSIZE_T ssize_t
unsigned __int64 uint64_t