UnixOperatingSystem.st
changeset 17596 082b7d32692a
parent 17579 4d70eacfd5d7
child 17631 0441ae93a3e4
equal deleted inserted replaced
17595:3a744321aa74 17596:082b7d32692a
     1 "{ Encoding: utf8 }"
     1 "{ Encoding: utf8 }"
     2 
     2 
     3 "
     3 "
     4  COPYRIGHT (c) 1988 by Claus Gittinger
     4  COPYRIGHT (c) 1988 by Claus Gittinger
     5               All Rights Reserved
     5 	      All Rights Reserved
     6 
     6 
     7  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
     8  only in accordance with the terms of that license and with the
     8  only in accordance with the terms of that license and with the
     9  inclusion of the above copyright notice.   This software may not
     9  inclusion of the above copyright notice.   This software may not
    10  be provided or otherwise made available to, or used by, any
    10  be provided or otherwise made available to, or used by, any
   252 # ifdef __osx__
   252 # ifdef __osx__
   253 #  include <time.h>
   253 #  include <time.h>
   254 #  define HAS_TIMEGM
   254 #  define HAS_TIMEGM
   255 
   255 
   256 struct tm {
   256 struct tm {
   257         int     tm_sec;         /* seconds after the minute [0-60] */
   257 	int     tm_sec;         /* seconds after the minute [0-60] */
   258         int     tm_min;         /* minutes after the hour [0-59] */
   258 	int     tm_min;         /* minutes after the hour [0-59] */
   259         int     tm_hour;        /* hours since midnight [0-23] */
   259 	int     tm_hour;        /* hours since midnight [0-23] */
   260         int     tm_mday;        /* day of the month [1-31] */
   260 	int     tm_mday;        /* day of the month [1-31] */
   261         int     tm_mon;         /* months since January [0-11] */
   261 	int     tm_mon;         /* months since January [0-11] */
   262         int     tm_year;        /* years since 1900 */
   262 	int     tm_year;        /* years since 1900 */
   263         int     tm_wday;        /* days since Sunday [0-6] */
   263 	int     tm_wday;        /* days since Sunday [0-6] */
   264         int     tm_yday;        /* days since January 1 [0-365] */
   264 	int     tm_yday;        /* days since January 1 [0-365] */
   265         int     tm_isdst;       /* Daylight Savings Time flag */
   265 	int     tm_isdst;       /* Daylight Savings Time flag */
   266         long    tm_gmtoff;      /* offset from CUT in seconds */
   266 	long    tm_gmtoff;      /* offset from CUT in seconds */
   267         char    *tm_zone;       /* timezone abbreviation */
   267 	char    *tm_zone;       /* timezone abbreviation */
   268 };
   268 };
   269 
   269 
   270 #  include <crt_externs.h>
   270 #  include <crt_externs.h>
   271 #  include <net/if_dl.h>
   271 #  include <net/if_dl.h>
   272 
   272 
   641     pid_t pid;
   641     pid_t pid;
   642     struct sigaction sa, intr, quit;
   642     struct sigaction sa, intr, quit;
   643     sigset_t block, omask;
   643     sigset_t block, omask;
   644 
   644 
   645     if (line == NULL)
   645     if (line == NULL)
   646         return -1;
   646 	return -1;
   647 
   647 
   648     sa.sa_handler = SIG_IGN;
   648     sa.sa_handler = SIG_IGN;
   649     sa.sa_flags = 0;
   649     sa.sa_flags = 0;
   650     __sigemptyset (&sa.sa_mask);
   650     __sigemptyset (&sa.sa_mask);
   651 
   651 
   652     if (__sigaction (SIGINT, &sa, &intr) < 0) {
   652     if (__sigaction (SIGINT, &sa, &intr) < 0) {
   653         DPRINTF(("1: errno=%d\n", errno));
   653 	DPRINTF(("1: errno=%d\n", errno));
   654         return -1;
   654 	return -1;
   655     }
   655     }
   656     if (__sigaction (SIGQUIT, &sa, &quit) < 0) {
   656     if (__sigaction (SIGQUIT, &sa, &quit) < 0) {
   657         save = errno;
   657 	save = errno;
   658         (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
   658 	(void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
   659         errno = save;
   659 	errno = save;
   660         DPRINTF(("2: errno=%d\n", errno));
   660 	DPRINTF(("2: errno=%d\n", errno));
   661         return -1;
   661 	return -1;
   662     }
   662     }
   663 
   663 
   664     __sigemptyset (&block);
   664     __sigemptyset (&block);
   665     __sigaddset (&block, SIGCHLD);
   665     __sigaddset (&block, SIGCHLD);
   666     save = errno;
   666     save = errno;
   667     if (__sigprocmask(SIG_BLOCK, &block, &omask) < 0) {
   667     if (__sigprocmask(SIG_BLOCK, &block, &omask) < 0) {
   668         if (errno == ENOSYS)
   668 	if (errno == ENOSYS)
   669             errno = save;
   669 	    errno = save;
   670         else {
   670 	else {
   671             save = errno;
   671 	    save = errno;
   672             (void) __sigaction(SIGINT, &intr, (struct sigaction *) NULL);
   672 	    (void) __sigaction(SIGINT, &intr, (struct sigaction *) NULL);
   673             (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
   673 	    (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
   674             errno = save;
   674 	    errno = save;
   675             DPRINTF(("3: errno=%d\n", errno));
   675 	    DPRINTF(("3: errno=%d\n", errno));
   676             return -1;
   676 	    return -1;
   677         }
   677 	}
   678     }
   678     }
   679 
   679 
   680     pid = FORK ();
   680     pid = FORK ();
   681     if (pid == (pid_t) 0) {
   681     if (pid == (pid_t) 0) {
   682         /* Child side.  */
   682 	/* Child side.  */
   683         CONST char *new_argv[4];
   683 	CONST char *new_argv[4];
   684         new_argv[0] = SHELL_NAME;
   684 	new_argv[0] = SHELL_NAME;
   685         new_argv[1] = "-c";
   685 	new_argv[1] = "-c";
   686         new_argv[2] = line;
   686 	new_argv[2] = line;
   687         new_argv[3] = NULL;
   687 	new_argv[3] = NULL;
   688 
   688 
   689         /* Restore the signals.  */
   689 	/* Restore the signals.  */
   690         (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
   690 	(void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
   691         (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
   691 	(void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
   692         (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
   692 	(void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
   693 
   693 
   694         /* Exec the shell.  */
   694 	/* Exec the shell.  */
   695         (void) __execve (SHELL_PATH, (char *CONST *) new_argv, __environ);
   695 	(void) __execve (SHELL_PATH, (char *CONST *) new_argv, __environ);
   696         _exit (127);
   696 	_exit (127);
   697     } else {
   697     } else {
   698         if (pid < (pid_t) 0) {
   698 	if (pid < (pid_t) 0) {
   699             /* The fork failed.  */
   699 	    /* The fork failed.  */
   700             DPRINTF(("4: errno=%d\n", errno));
   700 	    DPRINTF(("4: errno=%d\n", errno));
   701             status = -1;
   701 	    status = -1;
   702         } else {
   702 	} else {
   703             /* Parent side.  */
   703 	    /* Parent side.  */
   704 #ifdef  NO_WAITPID
   704 #ifdef  NO_WAITPID
   705             pid_t child;
   705 	    pid_t child;
   706 
   706 
   707             do {
   707 	    do {
   708                 __BEGIN_INTERRUPTABLE__
   708 		__BEGIN_INTERRUPTABLE__
   709                 child = __wait (&status);
   709 		child = __wait (&status);
   710                 __END_INTERRUPTABLE__
   710 		__END_INTERRUPTABLE__
   711                 if (child < 0 && errno != EINTR) {
   711 		if (child < 0 && errno != EINTR) {
   712                     DPRINTF(("5: errno=%d\n", errno));
   712 		    DPRINTF(("5: errno=%d\n", errno));
   713                     status = -1;
   713 		    status = -1;
   714                     break;
   714 		    break;
   715                 }
   715 		}
   716             } while (child != pid);
   716 	    } while (child != pid);
   717 #else
   717 #else
   718             pid_t child;
   718 	    pid_t child;
   719 
   719 
   720             /* claus: the original did not care for EINTR here ... */
   720 	    /* claus: the original did not care for EINTR here ... */
   721             do {
   721 	    do {
   722                 __BEGIN_INTERRUPTABLE__
   722 		__BEGIN_INTERRUPTABLE__
   723                 child = __waitpid (pid, &status, 0);
   723 		child = __waitpid (pid, &status, 0);
   724                 __END_INTERRUPTABLE__
   724 		__END_INTERRUPTABLE__
   725             } while ((child != pid) && (errno == EINTR));
   725 	    } while ((child != pid) && (errno == EINTR));
   726             if (child != pid) {
   726 	    if (child != pid) {
   727                 DPRINTF(("6: errno=%d\n", errno));
   727 		DPRINTF(("6: errno=%d\n", errno));
   728                 status = -1;
   728 		status = -1;
   729             }
   729 	    }
   730 #endif /* NO_WAITPID */
   730 #endif /* NO_WAITPID */
   731         }
   731 	}
   732     }
   732     }
   733     save = errno;
   733     save = errno;
   734     if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
   734     if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
   735      | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)
   735      | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)
   736      | __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)) != 0) {
   736      | __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)) != 0) {
   737         if (errno == ENOSYS) {
   737 	if (errno == ENOSYS) {
   738             errno = save;
   738 	    errno = save;
   739         } else {
   739 	} else {
   740             status = -1;
   740 	    status = -1;
   741             DPRINTF(("7: errno=%d\n", errno));
   741 	    DPRINTF(("7: errno=%d\n", errno));
   742         }
   742 	}
   743     }
   743     }
   744 
   744 
   745     return status;
   745     return status;
   746 }
   746 }
   747 #else
   747 #else
   776 # endif
   776 # endif
   777 
   777 
   778 static char *
   778 static char *
   779 realpath(const char *path, char *resolved_path)
   779 realpath(const char *path, char *resolved_path)
   780 {
   780 {
   781         char copy_path[MAXPATHLEN];
   781 	char copy_path[MAXPATHLEN];
   782         char link_path[MAXPATHLEN];
   782 	char link_path[MAXPATHLEN];
   783         char *new_path, *max_path, *mallocedPath;
   783 	char *new_path, *max_path, *mallocedPath;
   784         int readlinks = 0;
   784 	int readlinks = 0;
   785         int n;
   785 	int n;
   786 
   786 
   787         if (resolved_path == NULL) {
   787 	if (resolved_path == NULL) {
   788             mallocedPath = resolved_path = malloc(MAXPATHLEN+1);
   788 	    mallocedPath = resolved_path = malloc(MAXPATHLEN+1);
   789         }
   789 	}
   790         new_path = resolved_path;
   790 	new_path = resolved_path;
   791 
   791 
   792         /* Make a copy of the source path since we may need to modify it. */
   792 	/* Make a copy of the source path since we may need to modify it. */
   793         strcpy(copy_path, path);
   793 	strcpy(copy_path, path);
   794         path = copy_path;
   794 	path = copy_path;
   795         max_path = copy_path + MAXPATHLEN - 2;
   795 	max_path = copy_path + MAXPATHLEN - 2;
   796         /* If it's a relative pathname use getwd for starters. */
   796 	/* If it's a relative pathname use getwd for starters. */
   797         if (*path != '/') {
   797 	if (*path != '/') {
   798 #ifdef HAS_GETCWD
   798 #ifdef HAS_GETCWD
   799                 new_path = getcwd(new_path, MAXPATHLEN - 1);
   799 		new_path = getcwd(new_path, MAXPATHLEN - 1);
   800 #else
   800 #else
   801                 new_path = getwd(new_path);
   801 		new_path = getwd(new_path);
   802 #endif
   802 #endif
   803                 if (new_path == NULL) {
   803 		if (new_path == NULL) {
   804                     if (mallocedPath) free(mallocedPath);
   804 		    if (mallocedPath) free(mallocedPath);
   805                     return(NULL);
   805 		    return(NULL);
   806                 }
   806 		}
   807 
   807 
   808                 new_path += strlen(new_path);
   808 		new_path += strlen(new_path);
   809                 if (new_path[-1] != '/')
   809 		if (new_path[-1] != '/')
   810                         *new_path++ = '/';
   810 			*new_path++ = '/';
   811         }
   811 	}
   812         else {
   812 	else {
   813                 *new_path++ = '/';
   813 		*new_path++ = '/';
   814                 path++;
   814 		path++;
   815         }
   815 	}
   816         /* Expand each slash-separated pathname component. */
   816 	/* Expand each slash-separated pathname component. */
   817         while (*path != '\0') {
   817 	while (*path != '\0') {
   818                 /* Ignore stray "/". */
   818 		/* Ignore stray "/". */
   819                 if (*path == '/') {
   819 		if (*path == '/') {
   820                         path++;
   820 			path++;
   821                         continue;
   821 			continue;
   822                 }
   822 		}
   823                 if (*path == '.') {
   823 		if (*path == '.') {
   824                         /* Ignore ".". */
   824 			/* Ignore ".". */
   825                         if (path[1] == '\0' || path[1] == '/') {
   825 			if (path[1] == '\0' || path[1] == '/') {
   826                                 path++;
   826 				path++;
   827                                 continue;
   827 				continue;
   828                         }
   828 			}
   829                         if (path[1] == '.') {
   829 			if (path[1] == '.') {
   830                                 if (path[2] == '\0' || path[2] == '/') {
   830 				if (path[2] == '\0' || path[2] == '/') {
   831                                         path += 2;
   831 					path += 2;
   832                                         /* Ignore ".." at root. */
   832 					/* Ignore ".." at root. */
   833                                         if (new_path == resolved_path + 1)
   833 					if (new_path == resolved_path + 1)
   834                                                 continue;
   834 						continue;
   835                                         /* Handle ".." by backing up. */
   835 					/* Handle ".." by backing up. */
   836                                         while ((--new_path)[-1] != '/')
   836 					while ((--new_path)[-1] != '/')
   837                                                 ;
   837 						;
   838                                         continue;
   838 					continue;
   839                                 }
   839 				}
   840                         }
   840 			}
   841                 }
   841 		}
   842                 /* Safely copy the next pathname component. */
   842 		/* Safely copy the next pathname component. */
   843                 while (*path != '\0' && *path != '/') {
   843 		while (*path != '\0' && *path != '/') {
   844                         if (path > max_path) {
   844 			if (path > max_path) {
   845                             if (mallocedPath) free(mallocedPath);
   845 			    if (mallocedPath) free(mallocedPath);
   846                             errno = ENAMETOOLONG;
   846 			    errno = ENAMETOOLONG;
   847                             return NULL;
   847 			    return NULL;
   848                         }
   848 			}
   849                         *new_path++ = *path++;
   849 			*new_path++ = *path++;
   850                 }
   850 		}
   851 #ifdef S_IFLNK
   851 #ifdef S_IFLNK
   852                 /* Protect against infinite loops. */
   852 		/* Protect against infinite loops. */
   853                 if (readlinks++ > MAX_READLINKS) {
   853 		if (readlinks++ > MAX_READLINKS) {
   854                     if (mallocedPath) free(mallocedPath);
   854 		    if (mallocedPath) free(mallocedPath);
   855                     errno = ELOOP;
   855 		    errno = ELOOP;
   856                     return NULL;
   856 		    return NULL;
   857                 }
   857 		}
   858                 /* See if latest pathname component is a symlink. */
   858 		/* See if latest pathname component is a symlink. */
   859                 *new_path = '\0';
   859 		*new_path = '\0';
   860                 n = readlink(resolved_path, link_path, MAXPATHLEN - 1);
   860 		n = readlink(resolved_path, link_path, MAXPATHLEN - 1);
   861                 if (n < 0) {
   861 		if (n < 0) {
   862                         /* EINVAL means the file exists but isn't a symlink. */
   862 			/* EINVAL means the file exists but isn't a symlink. */
   863                         if (errno != EINVAL) {
   863 			if (errno != EINVAL) {
   864                             if (mallocedPath) free(mallocedPath);
   864 			    if (mallocedPath) free(mallocedPath);
   865                             return NULL;
   865 			    return NULL;
   866                         }
   866 			}
   867                 }
   867 		}
   868                 else {
   868 		else {
   869                         /* Note: readlink doesn't add the null byte. */
   869 			/* Note: readlink doesn't add the null byte. */
   870                         link_path[n] = '\0';
   870 			link_path[n] = '\0';
   871                         if (*link_path == '/')
   871 			if (*link_path == '/')
   872                                 /* Start over for an absolute symlink. */
   872 				/* Start over for an absolute symlink. */
   873                                 new_path = resolved_path;
   873 				new_path = resolved_path;
   874                         else
   874 			else
   875                                 /* Otherwise back up over this component. */
   875 				/* Otherwise back up over this component. */
   876                                 while (*(--new_path) != '/')
   876 				while (*(--new_path) != '/')
   877                                         ;
   877 					;
   878                         /* Safe sex check. */
   878 			/* Safe sex check. */
   879                         if (strlen(path) + n >= MAXPATHLEN) {
   879 			if (strlen(path) + n >= MAXPATHLEN) {
   880                             if (mallocedPath) free(mallocedPath);
   880 			    if (mallocedPath) free(mallocedPath);
   881                             errno = ENAMETOOLONG;
   881 			    errno = ENAMETOOLONG;
   882                             return NULL;
   882 			    return NULL;
   883                         }
   883 			}
   884                         /* Insert symlink contents into path. */
   884 			/* Insert symlink contents into path. */
   885                         strcat(link_path, path);
   885 			strcat(link_path, path);
   886                         strcpy(copy_path, link_path);
   886 			strcpy(copy_path, link_path);
   887                         path = copy_path;
   887 			path = copy_path;
   888                 }
   888 		}
   889 #endif /* S_IFLNK */
   889 #endif /* S_IFLNK */
   890                 *new_path++ = '/';
   890 		*new_path++ = '/';
   891         }
   891 	}
   892         /* Delete trailing slash but don't whomp a lone slash. */
   892 	/* Delete trailing slash but don't whomp a lone slash. */
   893         if (new_path != resolved_path + 1 && new_path[-1] == '/')
   893 	if (new_path != resolved_path + 1 && new_path[-1] == '/')
   894                 new_path--;
   894 		new_path--;
   895         /* Make sure it's null terminated. */
   895 	/* Make sure it's null terminated. */
   896         *new_path = '\0';
   896 	*new_path = '\0';
   897         return resolved_path;
   897 	return resolved_path;
   898 }
   898 }
   899 # define HAS_REALPATH
   899 # define HAS_REALPATH
   900 #endif /* WANT_REALPATH && not HAS_REALPATH */
   900 #endif /* WANT_REALPATH && not HAS_REALPATH */
   901 
   901 
   902 %}
   902 %}
   905 !UnixOperatingSystem class methodsFor:'documentation'!
   905 !UnixOperatingSystem class methodsFor:'documentation'!
   906 
   906 
   907 copyright
   907 copyright
   908 "
   908 "
   909  COPYRIGHT (c) 1988 by Claus Gittinger
   909  COPYRIGHT (c) 1988 by Claus Gittinger
   910               All Rights Reserved
   910 	      All Rights Reserved
   911 
   911 
   912  This software is furnished under a license and may be used
   912  This software is furnished under a license and may be used
   913  only in accordance with the terms of that license and with the
   913  only in accordance with the terms of that license and with the
   914  inclusion of the above copyright notice.   This software may not
   914  inclusion of the above copyright notice.   This software may not
   915  be provided or otherwise made available to, or used by, any
   915  be provided or otherwise made available to, or used by, any
   930      able to get down to a select or fork system call easily (at least on Unix systems).
   930      able to get down to a select or fork system call easily (at least on Unix systems).
   931      You decide - portability vs. functionality)
   931      You decide - portability vs. functionality)
   932 
   932 
   933     [Class variables:]
   933     [Class variables:]
   934 
   934 
   935         HostName        <String>        remembered hostname
   935 	HostName        <String>        remembered hostname
   936 
   936 
   937         DomainName      <String>        remembered domainname
   937 	DomainName      <String>        remembered domainname
   938 
   938 
   939         SlowFork        <Boolean>       if set, fork and popen are avoided;
   939 	SlowFork        <Boolean>       if set, fork and popen are avoided;
   940                                         (more or less obsolete now)
   940 					(more or less obsolete now)
   941 
   941 
   942 
   942 
   943         CurrentDirectory <String>       remembered currentDirectories path
   943 	CurrentDirectory <String>       remembered currentDirectories path
   944 
   944 
   945     [author:]
   945     [author:]
   946         Claus Gittinger
   946 	Claus Gittinger
   947 
   947 
   948     [see also:]
   948     [see also:]
   949         OSProcessStatus
   949 	OSProcessStatus
   950         Filename Date Time
   950 	Filename Date Time
   951         ExternalStream FileStream PipeStream Socket
   951 	ExternalStream FileStream PipeStream Socket
   952 "
   952 "
   953 !
   953 !
   954 
   954 
   955 examples
   955 examples
   956 "
   956 "
   957   various queries
   957   various queries
   958                                                                 [exBegin]
   958 								[exBegin]
   959     Transcript
   959     Transcript
   960         showCR:'hello ' , (OperatingSystem getLoginName)
   960 	showCR:'hello ' , (OperatingSystem getLoginName)
   961                                                                 [exEnd]
   961 								[exEnd]
   962 
   962 
   963                                                                 [exBegin]
   963 								[exBegin]
   964     OperatingSystem isUNIXlike ifTrue:[
   964     OperatingSystem isUNIXlike ifTrue:[
   965         Transcript showCR:'this is some UNIX-like OS'
   965 	Transcript showCR:'this is some UNIX-like OS'
   966     ] ifFalse:[
   966     ] ifFalse:[
   967         Transcript showCR:'this OS is not UNIX-like'
   967 	Transcript showCR:'this OS is not UNIX-like'
   968     ]
   968     ]
   969                                                                 [exEnd]
   969 								[exEnd]
   970 
   970 
   971                                                                 [exBegin]
   971 								[exBegin]
   972     Transcript
   972     Transcript
   973         showCR:'this machine is called ' , OperatingSystem getHostName
   973 	showCR:'this machine is called ' , OperatingSystem getHostName
   974                                                                 [exEnd]
   974 								[exEnd]
   975 
   975 
   976                                                                 [exBegin]
   976 								[exBegin]
   977     Transcript
   977     Transcript
   978         showCR:('this machine is in the '
   978 	showCR:('this machine is in the '
   979                , OperatingSystem getDomainName
   979 	       , OperatingSystem getDomainName
   980                , ' domain')
   980 	       , ' domain')
   981                                                                 [exEnd]
   981 								[exEnd]
   982 
   982 
   983                                                                 [exBegin]
   983 								[exBegin]
   984     Transcript
   984     Transcript
   985         showCR:('this machine''s CPU is a '
   985 	showCR:('this machine''s CPU is a '
   986                , OperatingSystem getCPUType
   986 	       , OperatingSystem getCPUType
   987                )
   987 	       )
   988                                                                 [exEnd]
   988 								[exEnd]
   989 
   989 
   990                                                                 [exBegin]
   990 								[exBegin]
   991     Transcript showCR:'executing ls command ...'.
   991     Transcript showCR:'executing ls command ...'.
   992     OperatingSystem executeCommand:'ls'.
   992     OperatingSystem executeCommand:'ls'.
   993     Transcript showCR:'... done.'.
   993     Transcript showCR:'... done.'.
   994                                                                 [exEnd]
   994 								[exEnd]
   995 
   995 
   996   locking a file
   996   locking a file
   997   (should be executed on two running smalltalks - not in two threads):
   997   (should be executed on two running smalltalks - not in two threads):
   998                                                                 [exBegin]
   998 								[exBegin]
   999     |f|
   999     |f|
  1000 
  1000 
  1001     f := 'testFile' asFilename readWriteStream.
  1001     f := 'testFile' asFilename readWriteStream.
  1002 
  1002 
  1003     10 timesRepeat:[
  1003     10 timesRepeat:[
  1004         'about to lock ...' printCR.
  1004 	'about to lock ...' printCR.
  1005         [
  1005 	[
  1006           OperatingSystem
  1006 	  OperatingSystem
  1007             lockFD:(f fileDescriptor)
  1007 	    lockFD:(f fileDescriptor)
  1008             shared:false
  1008 	    shared:false
  1009             blocking:false
  1009 	    blocking:false
  1010         ] whileFalse:[
  1010 	] whileFalse:[
  1011             'process ' print. OperatingSystem getProcessId print. ' is waiting' printCR.
  1011 	    'process ' print. OperatingSystem getProcessId print. ' is waiting' printCR.
  1012             Delay waitForSeconds:1
  1012 	    Delay waitForSeconds:1
  1013         ].
  1013 	].
  1014         'LOCKED ...' printCR.
  1014 	'LOCKED ...' printCR.
  1015         Delay waitForSeconds:10.
  1015 	Delay waitForSeconds:10.
  1016         'unlock ...' printCR.
  1016 	'unlock ...' printCR.
  1017         (OperatingSystem
  1017 	(OperatingSystem
  1018             unlockFD:(f fileDescriptor)) printCR.
  1018 	    unlockFD:(f fileDescriptor)) printCR.
  1019         Delay waitForSeconds:3.
  1019 	Delay waitForSeconds:3.
  1020     ]
  1020     ]
  1021                                                                 [exBegin]
  1021 								[exBegin]
  1022 "
  1022 "
  1023 ! !
  1023 ! !
  1024 
  1024 
  1025 !UnixOperatingSystem class methodsFor:'initialization'!
  1025 !UnixOperatingSystem class methodsFor:'initialization'!
  1026 
  1026 
  1027 initialize
  1027 initialize
  1028     "initialize the class"
  1028     "initialize the class"
  1029 
  1029 
  1030     "/ protect against double initialization
  1030     "/ protect against double initialization
  1031     Initialized isNil ifTrue:[
  1031     Initialized isNil ifTrue:[
  1032         ObjectMemory addDependent:self.
  1032 	ObjectMemory addDependent:self.
  1033         self initializeCachedData.
  1033 	self initializeCachedData.
  1034         Initialized := true.
  1034 	Initialized := true.
  1035     ].
  1035     ].
  1036 !
  1036 !
  1037 
  1037 
  1038 initializeCachedData
  1038 initializeCachedData
  1039     HostName := nil.
  1039     HostName := nil.
  1058     char *__codeset;
  1058     char *__codeset;
  1059 
  1059 
  1060     setlocale(LC_CTYPE, "");
  1060     setlocale(LC_CTYPE, "");
  1061     __codeset = nl_langinfo(CODESET);
  1061     __codeset = nl_langinfo(CODESET);
  1062     if (strlen(__codeset) > 0) {
  1062     if (strlen(__codeset) > 0) {
  1063         codeset = __MKSTRING(__codeset);
  1063 	codeset = __MKSTRING(__codeset);
  1064     }
  1064     }
  1065 %}.
  1065 %}.
  1066     codeset notNil ifTrue:[
  1066     codeset notNil ifTrue:[
  1067         codeset := codeset asLowercase.
  1067 	codeset := codeset asLowercase.
  1068         codeset = 'utf-8' ifTrue:[
  1068 	codeset = 'utf-8' ifTrue:[
  1069             codeset := #utf8.
  1069 	    codeset := #utf8.
  1070         ] ifFalse:[
  1070 	] ifFalse:[
  1071             codeset := codeset asSymbol.
  1071 	    codeset := codeset asSymbol.
  1072         ].
  1072 	].
  1073     ].
  1073     ].
  1074     Codeset := codeset.
  1074     Codeset := codeset.
  1075     ^ codeset.
  1075     ^ codeset.
  1076 
  1076 
  1077     "
  1077     "
  1081 
  1081 
  1082 update:something with:aParameter from:changedObject
  1082 update:something with:aParameter from:changedObject
  1083     "catch image restart and flush some cached data"
  1083     "catch image restart and flush some cached data"
  1084 
  1084 
  1085     something == #earlyRestart ifTrue:[
  1085     something == #earlyRestart ifTrue:[
  1086         self initializeCachedData
  1086 	self initializeCachedData
  1087     ]
  1087     ]
  1088 
  1088 
  1089     "Created: / 15.6.1996 / 15:22:37 / cg"
  1089     "Created: / 15.6.1996 / 15:22:37 / cg"
  1090     "Modified: / 7.1.1997 / 19:36:11 / stefan"
  1090     "Modified: / 7.1.1997 / 19:36:11 / stefan"
  1091     "Modified: / 11.12.1998 / 16:22:48 / cg"
  1091     "Modified: / 11.12.1998 / 16:22:48 / cg"
  1583       therefore do not remember or hardcode those numbers in the application)"
  1583       therefore do not remember or hardcode those numbers in the application)"
  1584 
  1584 
  1585 %{  /* NOCONTEXT */
  1585 %{  /* NOCONTEXT */
  1586 #ifdef SIGABRT
  1586 #ifdef SIGABRT
  1587     if (signalName == @symbol(SIGABRT)) {
  1587     if (signalName == @symbol(SIGABRT)) {
  1588         RETURN ( __mkSmallInteger(SIGABRT) );
  1588 	RETURN ( __mkSmallInteger(SIGABRT) );
  1589     }
  1589     }
  1590 #endif
  1590 #endif
  1591 #ifdef SIGALRM
  1591 #ifdef SIGALRM
  1592     if (signalName == @symbol(SIGALRM)) {
  1592     if (signalName == @symbol(SIGALRM)) {
  1593         RETURN ( __mkSmallInteger(SIGALRM) );
  1593 	RETURN ( __mkSmallInteger(SIGALRM) );
  1594     }
  1594     }
  1595 #endif
  1595 #endif
  1596 #ifdef SIGBREAK
  1596 #ifdef SIGBREAK
  1597     if (signalName == @symbol(SIGBREAK)) {
  1597     if (signalName == @symbol(SIGBREAK)) {
  1598         RETURN ( __mkSmallInteger(SIGBREAK) );
  1598 	RETURN ( __mkSmallInteger(SIGBREAK) );
  1599     }
  1599     }
  1600 #endif
  1600 #endif
  1601 #ifdef SIGBUS
  1601 #ifdef SIGBUS
  1602     if (signalName == @symbol(SIGBUS)) {
  1602     if (signalName == @symbol(SIGBUS)) {
  1603         RETURN ( __mkSmallInteger(SIGBUS) );
  1603 	RETURN ( __mkSmallInteger(SIGBUS) );
  1604     }
  1604     }
  1605 #endif
  1605 #endif
  1606 #ifdef SIGCHLD
  1606 #ifdef SIGCHLD
  1607     if ((signalName == @symbol(SIGCHLD))
  1607     if ((signalName == @symbol(SIGCHLD))
  1608      || (signalName == @symbol(SIGCLD)) ) {
  1608      || (signalName == @symbol(SIGCLD)) ) {
  1609         RETURN ( __mkSmallInteger(SIGCHLD) );
  1609 	RETURN ( __mkSmallInteger(SIGCHLD) );
  1610     }
  1610     }
  1611 #else
  1611 #else
  1612 # if defined(SIGCLD)
  1612 # if defined(SIGCLD)
  1613     if ((signalName == @symbol(SIGCHLD))
  1613     if ((signalName == @symbol(SIGCHLD))
  1614      || (signalName == @symbol(SIGCLD)) ) {
  1614      || (signalName == @symbol(SIGCLD)) ) {
  1615         RETURN ( __mkSmallInteger(SIGCLD) );
  1615 	RETURN ( __mkSmallInteger(SIGCLD) );
  1616     }
  1616     }
  1617 # endif
  1617 # endif
  1618 #endif
  1618 #endif
  1619 #ifdef SIGCONT
  1619 #ifdef SIGCONT
  1620     if (signalName == @symbol(SIGCONT)) {
  1620     if (signalName == @symbol(SIGCONT)) {
  1621         RETURN ( __mkSmallInteger(SIGCONT) );
  1621 	RETURN ( __mkSmallInteger(SIGCONT) );
  1622     }
  1622     }
  1623 #endif
  1623 #endif
  1624 #ifdef SIGDANGER
  1624 #ifdef SIGDANGER
  1625     if (signalName == @symbol(SIGDANGER)) {
  1625     if (signalName == @symbol(SIGDANGER)) {
  1626         RETURN ( __mkSmallInteger(SIGDANGER) );
  1626 	RETURN ( __mkSmallInteger(SIGDANGER) );
  1627     }
  1627     }
  1628 #endif
  1628 #endif
  1629 #ifdef SIGEMT
  1629 #ifdef SIGEMT
  1630     if (signalName == @symbol(SIGEMT)) {
  1630     if (signalName == @symbol(SIGEMT)) {
  1631         RETURN ( __mkSmallInteger(SIGEMT) );
  1631 	RETURN ( __mkSmallInteger(SIGEMT) );
  1632     }
  1632     }
  1633 #endif
  1633 #endif
  1634 #ifdef SIGFPE
  1634 #ifdef SIGFPE
  1635     if (signalName == @symbol(SIGFPE)) {
  1635     if (signalName == @symbol(SIGFPE)) {
  1636         RETURN ( __mkSmallInteger(SIGFPE) );
  1636 	RETURN ( __mkSmallInteger(SIGFPE) );
  1637     }
  1637     }
  1638 #endif
  1638 #endif
  1639 #ifdef SIGGRANT
  1639 #ifdef SIGGRANT
  1640     if (signalName == @symbol(SIGGRANT)) {
  1640     if (signalName == @symbol(SIGGRANT)) {
  1641         RETURN ( __mkSmallInteger(SIGGRANT) );
  1641 	RETURN ( __mkSmallInteger(SIGGRANT) );
  1642     }
  1642     }
  1643 #endif
  1643 #endif
  1644 #ifdef SIGHUP
  1644 #ifdef SIGHUP
  1645     if (signalName == @symbol(SIGHUP)) {
  1645     if (signalName == @symbol(SIGHUP)) {
  1646         RETURN ( __mkSmallInteger(SIGHUP) );
  1646 	RETURN ( __mkSmallInteger(SIGHUP) );
  1647     }
  1647     }
  1648 #endif
  1648 #endif
  1649 #ifdef SIGILL
  1649 #ifdef SIGILL
  1650     if (signalName == @symbol(SIGILL)) {
  1650     if (signalName == @symbol(SIGILL)) {
  1651         RETURN ( __mkSmallInteger(SIGILL) );
  1651 	RETURN ( __mkSmallInteger(SIGILL) );
  1652     }
  1652     }
  1653 #endif
  1653 #endif
  1654 #ifdef SIGINT
  1654 #ifdef SIGINT
  1655     if (signalName == @symbol(SIGINT)) {
  1655     if (signalName == @symbol(SIGINT)) {
  1656         RETURN ( __mkSmallInteger(SIGINT) );
  1656 	RETURN ( __mkSmallInteger(SIGINT) );
  1657     }
  1657     }
  1658 #endif
  1658 #endif
  1659 #ifdef SIGIO
  1659 #ifdef SIGIO
  1660     if (signalName == @symbol(SIGIO)) {
  1660     if (signalName == @symbol(SIGIO)) {
  1661         RETURN ( __mkSmallInteger(SIGIO) );
  1661 	RETURN ( __mkSmallInteger(SIGIO) );
  1662     }
  1662     }
  1663 #endif
  1663 #endif
  1664 #ifdef SIGIOT
  1664 #ifdef SIGIOT
  1665     if (signalName == @symbol(SIGIOT)) {
  1665     if (signalName == @symbol(SIGIOT)) {
  1666         RETURN ( __mkSmallInteger(SIGIOT) );
  1666 	RETURN ( __mkSmallInteger(SIGIOT) );
  1667     }
  1667     }
  1668 #endif
  1668 #endif
  1669 #ifdef SIGKILL
  1669 #ifdef SIGKILL
  1670     if (signalName == @symbol(SIGKILL)) {
  1670     if (signalName == @symbol(SIGKILL)) {
  1671         RETURN ( __mkSmallInteger(SIGKILL) );
  1671 	RETURN ( __mkSmallInteger(SIGKILL) );
  1672     }
  1672     }
  1673 #endif
  1673 #endif
  1674 #ifdef SIGLOST
  1674 #ifdef SIGLOST
  1675     if (signalName == @symbol(SIGLOST)) {
  1675     if (signalName == @symbol(SIGLOST)) {
  1676         RETURN ( __mkSmallInteger(SIGLOST) );
  1676 	RETURN ( __mkSmallInteger(SIGLOST) );
  1677     }
  1677     }
  1678 #endif
  1678 #endif
  1679 #ifdef SIGMIGRATE
  1679 #ifdef SIGMIGRATE
  1680     if (signalName == @symbol(SIGMIGRATE)) {
  1680     if (signalName == @symbol(SIGMIGRATE)) {
  1681         RETURN ( __mkSmallInteger(SIGMIGRATE) );
  1681 	RETURN ( __mkSmallInteger(SIGMIGRATE) );
  1682     }
  1682     }
  1683 #endif
  1683 #endif
  1684 #ifdef SIGMSG
  1684 #ifdef SIGMSG
  1685     if (signalName == @symbol(SIGMSG)) {
  1685     if (signalName == @symbol(SIGMSG)) {
  1686         RETURN ( __mkSmallInteger(SIGMSG) );
  1686 	RETURN ( __mkSmallInteger(SIGMSG) );
  1687     }
  1687     }
  1688 #endif
  1688 #endif
  1689 #ifdef SIGPIPE
  1689 #ifdef SIGPIPE
  1690     if (signalName == @symbol(SIGPIPE)) {
  1690     if (signalName == @symbol(SIGPIPE)) {
  1691         RETURN ( __mkSmallInteger(SIGPIPE) );
  1691 	RETURN ( __mkSmallInteger(SIGPIPE) );
  1692     }
  1692     }
  1693 #endif
  1693 #endif
  1694 #ifdef SIGPOLL
  1694 #ifdef SIGPOLL
  1695     if (signalName == @symbol(SIGPOLL)) {
  1695     if (signalName == @symbol(SIGPOLL)) {
  1696         RETURN ( __mkSmallInteger(SIGPOLL) );
  1696 	RETURN ( __mkSmallInteger(SIGPOLL) );
  1697     }
  1697     }
  1698 #endif
  1698 #endif
  1699 #ifdef SIGPRE
  1699 #ifdef SIGPRE
  1700     if (signalName == @symbol(SIGPRE)) {
  1700     if (signalName == @symbol(SIGPRE)) {
  1701         RETURN ( __mkSmallInteger(SIGPRE) );
  1701 	RETURN ( __mkSmallInteger(SIGPRE) );
  1702     }
  1702     }
  1703 #endif
  1703 #endif
  1704 #ifdef SIGPROF
  1704 #ifdef SIGPROF
  1705     if (signalName == @symbol(SIGPROF)) {
  1705     if (signalName == @symbol(SIGPROF)) {
  1706         RETURN ( __mkSmallInteger(SIGPROF) );
  1706 	RETURN ( __mkSmallInteger(SIGPROF) );
  1707     }
  1707     }
  1708 #endif
  1708 #endif
  1709 #ifdef SIGPWR
  1709 #ifdef SIGPWR
  1710     if (signalName == @symbol(SIGPWR)) {
  1710     if (signalName == @symbol(SIGPWR)) {
  1711         RETURN ( __mkSmallInteger(SIGPWR) );
  1711 	RETURN ( __mkSmallInteger(SIGPWR) );
  1712     }
  1712     }
  1713 #endif
  1713 #endif
  1714 #ifdef SIGQUIT
  1714 #ifdef SIGQUIT
  1715     if (signalName == @symbol(SIGQUIT)) {
  1715     if (signalName == @symbol(SIGQUIT)) {
  1716         RETURN ( __mkSmallInteger(SIGQUIT) );
  1716 	RETURN ( __mkSmallInteger(SIGQUIT) );
  1717     }
  1717     }
  1718 #endif
  1718 #endif
  1719 #ifdef SIGRETRACT
  1719 #ifdef SIGRETRACT
  1720     if (signalName == @symbol(SIGRETRACT)) {
  1720     if (signalName == @symbol(SIGRETRACT)) {
  1721         RETURN ( __mkSmallInteger(SIGRETRACT) );
  1721 	RETURN ( __mkSmallInteger(SIGRETRACT) );
  1722     }
  1722     }
  1723 #endif
  1723 #endif
  1724 #ifdef SIGSAK
  1724 #ifdef SIGSAK
  1725     if (signalName == @symbol(SIGSAK)) {
  1725     if (signalName == @symbol(SIGSAK)) {
  1726         RETURN ( __mkSmallInteger(SIGSAK) );
  1726 	RETURN ( __mkSmallInteger(SIGSAK) );
  1727     }
  1727     }
  1728 #endif
  1728 #endif
  1729 #ifdef SIGSEGV
  1729 #ifdef SIGSEGV
  1730     if (signalName == @symbol(SIGSEGV)) {
  1730     if (signalName == @symbol(SIGSEGV)) {
  1731         RETURN ( __mkSmallInteger(SIGSEGV) );
  1731 	RETURN ( __mkSmallInteger(SIGSEGV) );
  1732     }
  1732     }
  1733 #endif
  1733 #endif
  1734 #ifdef SIGSOUND
  1734 #ifdef SIGSOUND
  1735     if (signalName == @symbol(SIGSOUND)) {
  1735     if (signalName == @symbol(SIGSOUND)) {
  1736         RETURN ( __mkSmallInteger(SIGSOUND) );
  1736 	RETURN ( __mkSmallInteger(SIGSOUND) );
  1737     }
  1737     }
  1738 #endif
  1738 #endif
  1739 #ifdef SIGSTOP
  1739 #ifdef SIGSTOP
  1740     if (signalName == @symbol(SIGSTOP)) {
  1740     if (signalName == @symbol(SIGSTOP)) {
  1741         RETURN ( __mkSmallInteger(SIGSTOP) );
  1741 	RETURN ( __mkSmallInteger(SIGSTOP) );
  1742     }
  1742     }
  1743 #endif
  1743 #endif
  1744 #ifdef SIGSYS
  1744 #ifdef SIGSYS
  1745     if (signalName == @symbol(SIGSYS)) {
  1745     if (signalName == @symbol(SIGSYS)) {
  1746         RETURN ( __mkSmallInteger(SIGSYS) );
  1746 	RETURN ( __mkSmallInteger(SIGSYS) );
  1747     }
  1747     }
  1748 #endif
  1748 #endif
  1749 #ifdef SIGTERM
  1749 #ifdef SIGTERM
  1750     if (signalName == @symbol(SIGTERM)) {
  1750     if (signalName == @symbol(SIGTERM)) {
  1751         RETURN ( __mkSmallInteger(SIGTERM) );
  1751 	RETURN ( __mkSmallInteger(SIGTERM) );
  1752     }
  1752     }
  1753 #endif
  1753 #endif
  1754 #ifdef SIGTRAP
  1754 #ifdef SIGTRAP
  1755     if (signalName == @symbol(SIGTRAP)) {
  1755     if (signalName == @symbol(SIGTRAP)) {
  1756         RETURN ( __mkSmallInteger(SIGTRAP) );
  1756 	RETURN ( __mkSmallInteger(SIGTRAP) );
  1757     }
  1757     }
  1758 #endif
  1758 #endif
  1759 #ifdef SIGTSTP
  1759 #ifdef SIGTSTP
  1760     if (signalName == @symbol(SIGTSTP)) {
  1760     if (signalName == @symbol(SIGTSTP)) {
  1761         RETURN ( __mkSmallInteger(SIGTSTP) );
  1761 	RETURN ( __mkSmallInteger(SIGTSTP) );
  1762     }
  1762     }
  1763 #endif
  1763 #endif
  1764 #ifdef SIGTTIN
  1764 #ifdef SIGTTIN
  1765     if (signalName == @symbol(SIGTTIN)) {
  1765     if (signalName == @symbol(SIGTTIN)) {
  1766         RETURN ( __mkSmallInteger(SIGTTIN) );
  1766 	RETURN ( __mkSmallInteger(SIGTTIN) );
  1767     }
  1767     }
  1768 #endif
  1768 #endif
  1769 #ifdef SIGTTOU
  1769 #ifdef SIGTTOU
  1770     if (signalName == @symbol(SIGTTOU)) {
  1770     if (signalName == @symbol(SIGTTOU)) {
  1771         RETURN ( __mkSmallInteger(SIGTTOU) );
  1771 	RETURN ( __mkSmallInteger(SIGTTOU) );
  1772     }
  1772     }
  1773 #endif
  1773 #endif
  1774 #ifdef SIGURG
  1774 #ifdef SIGURG
  1775     if (signalName == @symbol(SIGURG)) {
  1775     if (signalName == @symbol(SIGURG)) {
  1776         RETURN ( __mkSmallInteger(SIGURG) );
  1776 	RETURN ( __mkSmallInteger(SIGURG) );
  1777     }
  1777     }
  1778 #endif
  1778 #endif
  1779 #ifdef SIGUSR1
  1779 #ifdef SIGUSR1
  1780     if (signalName == @symbol(SIGUSR1)) {
  1780     if (signalName == @symbol(SIGUSR1)) {
  1781         RETURN ( __mkSmallInteger(SIGUSR1) );
  1781 	RETURN ( __mkSmallInteger(SIGUSR1) );
  1782     }
  1782     }
  1783 #endif
  1783 #endif
  1784 #ifdef SIGUSR2
  1784 #ifdef SIGUSR2
  1785     if (signalName == @symbol(SIGUSR2)) {
  1785     if (signalName == @symbol(SIGUSR2)) {
  1786         RETURN ( __mkSmallInteger(SIGUSR2) );
  1786 	RETURN ( __mkSmallInteger(SIGUSR2) );
  1787     }
  1787     }
  1788 #endif
  1788 #endif
  1789 #ifdef SIGVTALRM
  1789 #ifdef SIGVTALRM
  1790     if (signalName == @symbol(SIGVTALRM)) {
  1790     if (signalName == @symbol(SIGVTALRM)) {
  1791         RETURN ( __mkSmallInteger(SIGVTALRM) );
  1791 	RETURN ( __mkSmallInteger(SIGVTALRM) );
  1792     }
  1792     }
  1793 #endif
  1793 #endif
  1794 #ifdef SIGWINCH
  1794 #ifdef SIGWINCH
  1795     if (signalName == @symbol(SIGWINCH)) {
  1795     if (signalName == @symbol(SIGWINCH)) {
  1796         RETURN ( __mkSmallInteger(SIGWINCH) );
  1796 	RETURN ( __mkSmallInteger(SIGWINCH) );
  1797     }
  1797     }
  1798 #endif
  1798 #endif
  1799 #ifdef SIGXCPU
  1799 #ifdef SIGXCPU
  1800     if (signalName == @symbol(SIGXCPU)) {
  1800     if (signalName == @symbol(SIGXCPU)) {
  1801         RETURN ( __mkSmallInteger(SIGXCPU) );
  1801 	RETURN ( __mkSmallInteger(SIGXCPU) );
  1802     }
  1802     }
  1803 #endif
  1803 #endif
  1804 #ifdef SIGXFSZ
  1804 #ifdef SIGXFSZ
  1805     if (signalName == @symbol(SIGXFSZ)) {
  1805     if (signalName == @symbol(SIGXFSZ)) {
  1806         RETURN ( __mkSmallInteger(SIGXFSZ) );
  1806 	RETURN ( __mkSmallInteger(SIGXFSZ) );
  1807     }
  1807     }
  1808 #endif
  1808 #endif
  1809 #ifdef SIGINFO
  1809 #ifdef SIGINFO
  1810     if (signalName == @symbol(SIGINFO)) {
  1810     if (signalName == @symbol(SIGINFO)) {
  1811         RETURN ( __mkSmallInteger(SIGINFO) );
  1811 	RETURN ( __mkSmallInteger(SIGINFO) );
  1812     }
  1812     }
  1813 #endif
  1813 #endif
  1814 
  1814 
  1815     RETURN ( __mkSmallInteger(0) );
  1815     RETURN ( __mkSmallInteger(0) );
  1816 %}
  1816 %}
  1828     "low level close of a directoryStream"
  1828     "low level close of a directoryStream"
  1829 
  1829 
  1830 %{
  1830 %{
  1831 #ifdef HAS_OPENDIR
  1831 #ifdef HAS_OPENDIR
  1832     if (__isExternalAddressLike(dirPointer)) {
  1832     if (__isExternalAddressLike(dirPointer)) {
  1833         closedir( (DIR *)(__FILEVal(dirPointer)) );
  1833 	closedir( (DIR *)(__FILEVal(dirPointer)) );
  1834     }
  1834     }
  1835 #endif
  1835 #endif
  1836 %}
  1836 %}
  1837 !
  1837 !
  1838 
  1838 
  1849     DIR *d;
  1849     DIR *d;
  1850     DIRENT_STRUCT *dp;
  1850     DIRENT_STRUCT *dp;
  1851 
  1851 
  1852     if ((dirPointer != nil)
  1852     if ((dirPointer != nil)
  1853      && __isExternalAddressLike(dirPointer)) {
  1853      && __isExternalAddressLike(dirPointer)) {
  1854         d = (DIR *)__FILEVal(dirPointer);
  1854 	d = (DIR *)__FILEVal(dirPointer);
  1855 
  1855 
  1856         __BEGIN_INTERRUPTABLE__
  1856 	__BEGIN_INTERRUPTABLE__
  1857         do {
  1857 	do {
  1858             do {
  1858 	    do {
  1859                 __threadErrno = 0;
  1859 		__threadErrno = 0;
  1860                 dp = readdir(d);
  1860 		dp = readdir(d);
  1861                 /*
  1861 		/*
  1862                  * for compatibility with ST-80,
  1862 		 * for compatibility with ST-80,
  1863                  * skip entries for '.' and '..'.
  1863 		 * skip entries for '.' and '..'.
  1864                  * If wanted, these must be added synthetically.
  1864 		 * If wanted, these must be added synthetically.
  1865                  */
  1865 		 */
  1866             } while (dp && ((strcmp(dp->d_name, ".")==0) || (strcmp(dp->d_name, "..")==0)));
  1866 	    } while (dp && ((strcmp(dp->d_name, ".")==0) || (strcmp(dp->d_name, "..")==0)));
  1867         } while ((dp == NULL) && (__threadErrno == EINTR));
  1867 	} while ((dp == NULL) && (__threadErrno == EINTR));
  1868         __END_INTERRUPTABLE__
  1868 	__END_INTERRUPTABLE__
  1869 
  1869 
  1870         if (dp != NULL) {
  1870 	if (dp != NULL) {
  1871             entry = __MKSTRING((char *)(dp->d_name));
  1871 	    entry = __MKSTRING((char *)(dp->d_name));
  1872         } else {
  1872 	} else {
  1873             if (__threadErrno) {
  1873 	    if (__threadErrno) {
  1874                 error = __mkSmallInteger(__threadErrno);
  1874 		error = __mkSmallInteger(__threadErrno);
  1875             }
  1875 	    }
  1876        }
  1876        }
  1877     }
  1877     }
  1878 #endif /* HAS_OPENDIR */
  1878 #endif /* HAS_OPENDIR */
  1879 %}.
  1879 %}.
  1880     error notNil ifTrue:[
  1880     error notNil ifTrue:[
  1881         ^ StreamIOError newException
  1881 	^ StreamIOError newException
  1882             errorCode:error;
  1882 	    errorCode:error;
  1883             osErrorHolder:(OperatingSystem errorHolderForNumber:error);
  1883 	    osErrorHolder:(OperatingSystem errorHolderForNumber:error);
  1884             parameter:aDirectoryStream;
  1884 	    parameter:aDirectoryStream;
  1885             raiseRequest
  1885 	    raiseRequest
  1886     ].
  1886     ].
  1887     entry notNil ifTrue:[
  1887     entry notNil ifTrue:[
  1888         ^ FileStatusInfo new sourcePath:(self decodePath:entry).
  1888 	^ FileStatusInfo new sourcePath:(self decodePath:entry).
  1889     ].
  1889     ].
  1890     ^ aDirectoryStream pastEndRead
  1890     ^ aDirectoryStream pastEndRead
  1891 ! !
  1891 ! !
  1892 
  1892 
  1893 !UnixOperatingSystem class methodsFor:'dummy shell operations'!
  1893 !UnixOperatingSystem class methodsFor:'dummy shell operations'!
  1894 
  1894 
  1895 openApplicationForDocument:aFilenameOrString operation:operationSymbol mimeType:mimeTypeStringArgOrNil ifNone:exceptionBlock
  1895 openApplicationForDocument:aFilenameOrString operation:operationSymbol mimeType:mimeTypeStringArgOrNil ifNone:exceptionBlock
  1896     "open a windows-shell/mac finder/desktop application to present the document contained in aFilenameOrString.
  1896     "open a windows-shell/mac finder/desktop application to present the document contained in aFilenameOrString.
  1897      This is typically used to present help-files, html documents, pdf documents etc.
  1897      This is typically used to present help-files, html documents, pdf documents etc.
  1898      operationSymbol is one of:
  1898      operationSymbol is one of:
  1899         open
  1899 	open
  1900         edit
  1900 	edit
  1901         explore
  1901 	explore
  1902      mimeTypeStringArgOrNil is e.g. 'text/html' or: 'application/pdf';
  1902      mimeTypeStringArgOrNil is e.g. 'text/html' or: 'application/pdf';
  1903      if nil is passed in, the file's suffix is used to guess it.
  1903      if nil is passed in, the file's suffix is used to guess it.
  1904     "
  1904     "
  1905 
  1905 
  1906     | cmd |
  1906     | cmd |
  1907 
  1907 
  1908     cmd := self openApplicationHelperCommand.
  1908     cmd := self openApplicationHelperCommand.
  1909     cmd notNil ifTrue:[
  1909     cmd notNil ifTrue:[
  1910         (cmd includesSubString:'%1') ifTrue:[
  1910 	(cmd includesSubString:'%1') ifTrue:[
  1911             cmd := cmd bindWith:aFilenameOrString asString.
  1911 	    cmd := cmd bindWith:aFilenameOrString asString.
  1912         ] ifFalse:[
  1912 	] ifFalse:[
  1913             cmd := cmd, ' "', aFilenameOrString asString, '"'.
  1913 	    cmd := cmd, ' "', aFilenameOrString asString, '"'.
  1914         ].
  1914 	].
  1915         (self
  1915 	(self
  1916                 startProcess:cmd
  1916 		startProcess:cmd
  1917                 inputFrom:nil outputTo:nil
  1917 		inputFrom:nil outputTo:nil
  1918                 errorTo:nil auxFrom:nil
  1918 		errorTo:nil auxFrom:nil
  1919                 environment: self getEnvironment inDirectory:nil) notNil ifTrue:[ ^ self ]
  1919 		environment: self getEnvironment inDirectory:nil) notNil ifTrue:[ ^ self ]
  1920     ].
  1920     ].
  1921     ^ super openApplicationForDocument:aFilenameOrString operation:operationSymbol mimeType:mimeTypeStringArgOrNil ifNone:exceptionBlock
  1921     ^ super openApplicationForDocument:aFilenameOrString operation:operationSymbol mimeType:mimeTypeStringArgOrNil ifNone:exceptionBlock
  1922 
  1922 
  1923 
  1923 
  1924     "
  1924     "
  1937 
  1937 
  1938     | xdgCurrentDesktop |
  1938     | xdgCurrentDesktop |
  1939 
  1939 
  1940     xdgCurrentDesktop := self getEnvironment: 'XDG_CURRENT_DESKTOP'.
  1940     xdgCurrentDesktop := self getEnvironment: 'XDG_CURRENT_DESKTOP'.
  1941     ((xdgCurrentDesktop = 'GNOME') and:[self canExecuteCommand: 'gnome-open']) ifTrue:[
  1941     ((xdgCurrentDesktop = 'GNOME') and:[self canExecuteCommand: 'gnome-open']) ifTrue:[
  1942         ^ 'gnome-open'
  1942 	^ 'gnome-open'
  1943     ].
  1943     ].
  1944     "/ Guess...
  1944     "/ Guess...
  1945     ((xdgCurrentDesktop = 'KDE') and:[self canExecuteCommand: 'kde-open']) ifTrue:[
  1945     ((xdgCurrentDesktop = 'KDE') and:[self canExecuteCommand: 'kde-open']) ifTrue:[
  1946         ^ 'kde-open'
  1946 	^ 'kde-open'
  1947     ].
  1947     ].
  1948     (self canExecuteCommand: 'xdg-open') ifTrue:[
  1948     (self canExecuteCommand: 'xdg-open') ifTrue:[
  1949         ^ 'xdg-open'
  1949 	^ 'xdg-open'
  1950     ].
  1950     ].
  1951     ^ nil
  1951     ^ nil
  1952 
  1952 
  1953     "
  1953     "
  1954      self openApplicationHelperCommand
  1954      self openApplicationHelperCommand
  1990      * I made this primitive code, since errnos are not
  1990      * I made this primitive code, since errnos are not
  1991      * standard across unixes
  1991      * standard across unixes
  1992      */
  1992      */
  1993 
  1993 
  1994     if (__isSmallInteger(errNr)) {
  1994     if (__isSmallInteger(errNr)) {
  1995         switch ( __intVal(errNr)) {
  1995 	switch ( __intVal(errNr)) {
  1996             /*
  1996 	    /*
  1997              * POSIX errnos - these should be defined
  1997 	     * POSIX errnos - these should be defined
  1998              */
  1998 	     */
  1999 #ifdef EPERM
  1999 #ifdef EPERM
  2000             case EPERM:
  2000 	    case EPERM:
  2001                 sym = @symbol(EPERM);
  2001 		sym = @symbol(EPERM);
  2002                 typ = @symbol(noPermissionsSignal);
  2002 		typ = @symbol(noPermissionsSignal);
  2003                 break;
  2003 		break;
  2004 #endif
  2004 #endif
  2005 #ifdef ENOENT
  2005 #ifdef ENOENT
  2006             case ENOENT:
  2006 	    case ENOENT:
  2007                 sym = @symbol(ENOENT);
  2007 		sym = @symbol(ENOENT);
  2008                 typ = @symbol(nonexistentSignal);
  2008 		typ = @symbol(nonexistentSignal);
  2009                 break;
  2009 		break;
  2010 #endif
  2010 #endif
  2011 #ifdef ESRCH
  2011 #ifdef ESRCH
  2012             case ESRCH:
  2012 	    case ESRCH:
  2013                 sym = @symbol(ESRCH);
  2013 		sym = @symbol(ESRCH);
  2014                 typ = @symbol(unavailableReferentSignal);
  2014 		typ = @symbol(unavailableReferentSignal);
  2015                 break;
  2015 		break;
  2016 #endif
  2016 #endif
  2017 #ifdef EINTR
  2017 #ifdef EINTR
  2018             case EINTR:
  2018 	    case EINTR:
  2019                 sym = @symbol(EINTR);
  2019 		sym = @symbol(EINTR);
  2020                 typ = @symbol(transientErrorSignal);
  2020 		typ = @symbol(transientErrorSignal);
  2021                 break;
  2021 		break;
  2022 #endif
  2022 #endif
  2023 #ifdef EIO
  2023 #ifdef EIO
  2024             case EIO:
  2024 	    case EIO:
  2025                 sym = @symbol(EIO);
  2025 		sym = @symbol(EIO);
  2026                 typ = @symbol(transferFaultSignal);
  2026 		typ = @symbol(transferFaultSignal);
  2027                 break;
  2027 		break;
  2028 #endif
  2028 #endif
  2029 #ifdef ENXIO
  2029 #ifdef ENXIO
  2030             case ENXIO:
  2030 	    case ENXIO:
  2031                 sym = @symbol(ENXIO);
  2031 		sym = @symbol(ENXIO);
  2032                 typ = @symbol(unavailableReferentSignal);
  2032 		typ = @symbol(unavailableReferentSignal);
  2033                 break;
  2033 		break;
  2034 #endif
  2034 #endif
  2035 #ifdef E2BIG
  2035 #ifdef E2BIG
  2036             case E2BIG:
  2036 	    case E2BIG:
  2037                 sym = @symbol(E2BIG);
  2037 		sym = @symbol(E2BIG);
  2038                 typ = @symbol(invalidArgumentsSignal);
  2038 		typ = @symbol(invalidArgumentsSignal);
  2039                 break;
  2039 		break;
  2040 #endif
  2040 #endif
  2041 #ifdef ENOEXEC
  2041 #ifdef ENOEXEC
  2042             case ENOEXEC:
  2042 	    case ENOEXEC:
  2043                 sym = @symbol(ENOEXEC);
  2043 		sym = @symbol(ENOEXEC);
  2044                 typ = @symbol(inappropriateOperationSignal);
  2044 		typ = @symbol(inappropriateOperationSignal);
  2045                 break;
  2045 		break;
  2046 #endif
  2046 #endif
  2047 #ifdef EBADF
  2047 #ifdef EBADF
  2048             case EBADF:
  2048 	    case EBADF:
  2049                 sym = @symbol(EBADF);
  2049 		sym = @symbol(EBADF);
  2050                 typ = @symbol(badAccessorSignal);
  2050 		typ = @symbol(badAccessorSignal);
  2051                 break;
  2051 		break;
  2052 #endif
  2052 #endif
  2053 #ifdef ECHILD
  2053 #ifdef ECHILD
  2054             case ECHILD:
  2054 	    case ECHILD:
  2055                 sym = @symbol(ECHILD);
  2055 		sym = @symbol(ECHILD);
  2056                 typ = @symbol(informationSignal);
  2056 		typ = @symbol(informationSignal);
  2057                 break;
  2057 		break;
  2058 #endif
  2058 #endif
  2059 #if !defined(EWOULDBLOCK) && defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
  2059 #if !defined(EWOULDBLOCK) && defined(EAGAIN) && (EWOULDBLOCK != EAGAIN)
  2060             case EAGAIN:
  2060 	    case EAGAIN:
  2061                 sym = @symbol(EAGAIN);
  2061 		sym = @symbol(EAGAIN);
  2062                 typ = @symbol(notReadySignal);
  2062 		typ = @symbol(notReadySignal);
  2063                 break;
  2063 		break;
  2064 #endif
  2064 #endif
  2065 #ifdef EOVERFLOW
  2065 #ifdef EOVERFLOW
  2066             case EOVERFLOW:
  2066 	    case EOVERFLOW:
  2067                 sym = @symbol(EOVERFLOW);
  2067 		sym = @symbol(EOVERFLOW);
  2068                 typ = @symbol(rangeErrorSignal);
  2068 		typ = @symbol(rangeErrorSignal);
  2069                 break;
  2069 		break;
  2070 #endif
  2070 #endif
  2071 #ifdef ENOMEM
  2071 #ifdef ENOMEM
  2072             case ENOMEM:
  2072 	    case ENOMEM:
  2073                 sym = @symbol(ENOMEM);
  2073 		sym = @symbol(ENOMEM);
  2074                 typ = @symbol(noMemorySignal);
  2074 		typ = @symbol(noMemorySignal);
  2075                 break;
  2075 		break;
  2076 #endif
  2076 #endif
  2077 #ifdef EACCES
  2077 #ifdef EACCES
  2078             case EACCES:
  2078 	    case EACCES:
  2079                 sym = @symbol(EACCES);
  2079 		sym = @symbol(EACCES);
  2080                 typ = @symbol(noPermissionsSignal);
  2080 		typ = @symbol(noPermissionsSignal);
  2081                 break;
  2081 		break;
  2082 #endif
  2082 #endif
  2083 #ifdef EFAULT
  2083 #ifdef EFAULT
  2084             case EFAULT:
  2084 	    case EFAULT:
  2085                 sym = @symbol(EFAULT);
  2085 		sym = @symbol(EFAULT);
  2086                 typ = @symbol(invalidArgumentsSignal);
  2086 		typ = @symbol(invalidArgumentsSignal);
  2087                 break;
  2087 		break;
  2088 #endif
  2088 #endif
  2089 #ifdef EBUSY
  2089 #ifdef EBUSY
  2090             case EBUSY:
  2090 	    case EBUSY:
  2091                 sym = @symbol(EBUSY);
  2091 		sym = @symbol(EBUSY);
  2092                 typ = @symbol(unavailableReferentSignal);
  2092 		typ = @symbol(unavailableReferentSignal);
  2093                 break;
  2093 		break;
  2094 #endif
  2094 #endif
  2095 #ifdef EEXIST
  2095 #ifdef EEXIST
  2096             case EEXIST:
  2096 	    case EEXIST:
  2097                 sym = @symbol(EEXIST);
  2097 		sym = @symbol(EEXIST);
  2098                 typ = @symbol(existingReferentSignal);
  2098 		typ = @symbol(existingReferentSignal);
  2099                 break;
  2099 		break;
  2100 #endif
  2100 #endif
  2101 #ifdef EXDEV
  2101 #ifdef EXDEV
  2102             case EXDEV:
  2102 	    case EXDEV:
  2103                 sym = @symbol(EXDEV);
  2103 		sym = @symbol(EXDEV);
  2104                 typ = @symbol(inappropriateReferentSignal);
  2104 		typ = @symbol(inappropriateReferentSignal);
  2105                 break;
  2105 		break;
  2106 #endif
  2106 #endif
  2107 #ifdef ENODEV
  2107 #ifdef ENODEV
  2108             case ENODEV:
  2108 	    case ENODEV:
  2109                 sym = @symbol(ENODEV);
  2109 		sym = @symbol(ENODEV);
  2110                 typ = @symbol(inaccessibleSignal);
  2110 		typ = @symbol(inaccessibleSignal);
  2111                 break;
  2111 		break;
  2112 #endif
  2112 #endif
  2113 #ifdef ENOTDIR
  2113 #ifdef ENOTDIR
  2114             case ENOTDIR:
  2114 	    case ENOTDIR:
  2115                 sym = @symbol(ENOTDIR);
  2115 		sym = @symbol(ENOTDIR);
  2116                 typ = @symbol(inappropriateOperationSignal);
  2116 		typ = @symbol(inappropriateOperationSignal);
  2117                 break;
  2117 		break;
  2118 #endif
  2118 #endif
  2119 #ifdef EISDIR
  2119 #ifdef EISDIR
  2120             case EISDIR:
  2120 	    case EISDIR:
  2121                 sym = @symbol(EISDIR);
  2121 		sym = @symbol(EISDIR);
  2122                 typ = @symbol(inappropriateOperationSignal);
  2122 		typ = @symbol(inappropriateOperationSignal);
  2123                 break;
  2123 		break;
  2124 #endif
  2124 #endif
  2125 #ifdef EINVAL
  2125 #ifdef EINVAL
  2126             case EINVAL:
  2126 	    case EINVAL:
  2127                 sym = @symbol(EINVAL);
  2127 		sym = @symbol(EINVAL);
  2128                 typ = @symbol(invalidArgumentsSignal);
  2128 		typ = @symbol(invalidArgumentsSignal);
  2129                 break;
  2129 		break;
  2130 #endif
  2130 #endif
  2131 #ifdef ENFILE
  2131 #ifdef ENFILE
  2132             case ENFILE:
  2132 	    case ENFILE:
  2133                 sym = @symbol(ENFILE);
  2133 		sym = @symbol(ENFILE);
  2134                 typ = @symbol(noResourcesSignal);
  2134 		typ = @symbol(noResourcesSignal);
  2135                 break;
  2135 		break;
  2136 #endif
  2136 #endif
  2137 #ifdef EMFILE
  2137 #ifdef EMFILE
  2138             case EMFILE:
  2138 	    case EMFILE:
  2139                 sym = @symbol(EMFILE);
  2139 		sym = @symbol(EMFILE);
  2140                 typ = @symbol(noResourcesSignal);
  2140 		typ = @symbol(noResourcesSignal);
  2141                 break;
  2141 		break;
  2142 #endif
  2142 #endif
  2143 #ifdef ENOTTY
  2143 #ifdef ENOTTY
  2144             case ENOTTY:
  2144 	    case ENOTTY:
  2145                 sym = @symbol(ENOTTY);
  2145 		sym = @symbol(ENOTTY);
  2146                 typ = @symbol(inappropriateOperationSignal);
  2146 		typ = @symbol(inappropriateOperationSignal);
  2147                 break;
  2147 		break;
  2148 #endif
  2148 #endif
  2149 #ifdef EFBIG
  2149 #ifdef EFBIG
  2150             case EFBIG:
  2150 	    case EFBIG:
  2151                 sym = @symbol(EFBIG);
  2151 		sym = @symbol(EFBIG);
  2152                 typ = @symbol(noResourcesSignal);
  2152 		typ = @symbol(noResourcesSignal);
  2153                 break;
  2153 		break;
  2154 #endif
  2154 #endif
  2155 #ifdef ENOSPC
  2155 #ifdef ENOSPC
  2156             case ENOSPC:
  2156 	    case ENOSPC:
  2157                 sym = @symbol(ENOSPC);
  2157 		sym = @symbol(ENOSPC);
  2158                 typ = @symbol(noResourcesSignal);
  2158 		typ = @symbol(noResourcesSignal);
  2159                 break;
  2159 		break;
  2160 #endif
  2160 #endif
  2161 #ifdef ESPIPE
  2161 #ifdef ESPIPE
  2162             case ESPIPE:
  2162 	    case ESPIPE:
  2163                 sym = @symbol(ESPIPE);
  2163 		sym = @symbol(ESPIPE);
  2164                 typ = @symbol(inappropriateOperationSignal);
  2164 		typ = @symbol(inappropriateOperationSignal);
  2165                 break;
  2165 		break;
  2166 #endif
  2166 #endif
  2167 #ifdef EROFS
  2167 #ifdef EROFS
  2168             case EROFS:
  2168 	    case EROFS:
  2169                 sym = @symbol(EROFS);
  2169 		sym = @symbol(EROFS);
  2170                 typ = @symbol(inappropriateOperationSignal);
  2170 		typ = @symbol(inappropriateOperationSignal);
  2171                 break;
  2171 		break;
  2172 #endif
  2172 #endif
  2173 #ifdef EMLINK
  2173 #ifdef EMLINK
  2174             case EMLINK:
  2174 	    case EMLINK:
  2175                 sym = @symbol(EMLINK);
  2175 		sym = @symbol(EMLINK);
  2176                 typ = @symbol(rangeErrorSignal);
  2176 		typ = @symbol(rangeErrorSignal);
  2177                 break;
  2177 		break;
  2178 #endif
  2178 #endif
  2179 #ifdef EPIPE
  2179 #ifdef EPIPE
  2180             case EPIPE:
  2180 	    case EPIPE:
  2181                 sym = @symbol(EPIPE);
  2181 		sym = @symbol(EPIPE);
  2182                 typ = @symbol(peerFaultSignal);
  2182 		typ = @symbol(peerFaultSignal);
  2183                 break;
  2183 		break;
  2184 #endif
  2184 #endif
  2185 #ifdef EDOM
  2185 #ifdef EDOM
  2186             case EDOM:
  2186 	    case EDOM:
  2187                 sym = @symbol(EDOM);
  2187 		sym = @symbol(EDOM);
  2188                 typ = @symbol(rangeErrorSignal);
  2188 		typ = @symbol(rangeErrorSignal);
  2189                 break;
  2189 		break;
  2190 #endif
  2190 #endif
  2191 #ifdef ERANGE
  2191 #ifdef ERANGE
  2192             case ERANGE:
  2192 	    case ERANGE:
  2193                 sym = @symbol(ERANGE);
  2193 		sym = @symbol(ERANGE);
  2194                 typ = @symbol(rangeErrorSignal);
  2194 		typ = @symbol(rangeErrorSignal);
  2195                 break;
  2195 		break;
  2196 #endif
  2196 #endif
  2197 #ifdef EDEADLK
  2197 #ifdef EDEADLK
  2198 # if EDEADLK != EWOULDBLOCK
  2198 # if EDEADLK != EWOULDBLOCK
  2199             case EDEADLK:
  2199 	    case EDEADLK:
  2200                 sym = @symbol(EDEADLK);
  2200 		sym = @symbol(EDEADLK);
  2201                 typ = @symbol(noResourcesSignal);
  2201 		typ = @symbol(noResourcesSignal);
  2202                 break;
  2202 		break;
  2203 # endif
  2203 # endif
  2204 #endif
  2204 #endif
  2205 #ifdef ENAMETOOLONG
  2205 #ifdef ENAMETOOLONG
  2206             case ENAMETOOLONG:
  2206 	    case ENAMETOOLONG:
  2207                 sym = @symbol(ENAMETOOLONG);
  2207 		sym = @symbol(ENAMETOOLONG);
  2208                 typ = @symbol(rangeErrorSignal);
  2208 		typ = @symbol(rangeErrorSignal);
  2209                 break;
  2209 		break;
  2210 #endif
  2210 #endif
  2211 #ifdef ENOLCK
  2211 #ifdef ENOLCK
  2212             case ENOLCK:
  2212 	    case ENOLCK:
  2213                 sym = @symbol(ENOLCK);
  2213 		sym = @symbol(ENOLCK);
  2214                 typ = @symbol(inappropriateOperationSignal);
  2214 		typ = @symbol(inappropriateOperationSignal);
  2215                 break;
  2215 		break;
  2216 #endif
  2216 #endif
  2217 #ifdef ENOSYS
  2217 #ifdef ENOSYS
  2218             case ENOSYS:
  2218 	    case ENOSYS:
  2219                 sym = @symbol(ENOSYS);
  2219 		sym = @symbol(ENOSYS);
  2220                 typ = @symbol(inappropriateOperationSignal);
  2220 		typ = @symbol(inappropriateOperationSignal);
  2221                 break;
  2221 		break;
  2222 #endif
  2222 #endif
  2223 #if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST)
  2223 #if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST)
  2224             case ENOTEMPTY:
  2224 	    case ENOTEMPTY:
  2225                 sym = @symbol(ENOTEMPTY);
  2225 		sym = @symbol(ENOTEMPTY);
  2226                 typ = @symbol(inappropriateReferentSignal);
  2226 		typ = @symbol(inappropriateReferentSignal);
  2227                 break;
  2227 		break;
  2228 #endif
  2228 #endif
  2229 #ifdef EILSEQ
  2229 #ifdef EILSEQ
  2230             case EILSEQ:
  2230 	    case EILSEQ:
  2231                 sym = @symbol(EILSEQ);
  2231 		sym = @symbol(EILSEQ);
  2232                 typ = @symbol(transferFaultSignal);
  2232 		typ = @symbol(transferFaultSignal);
  2233                 break;
  2233 		break;
  2234 #endif
  2234 #endif
  2235             /*
  2235 	    /*
  2236              * XPG3 errnos - defined on most systems
  2236 	     * XPG3 errnos - defined on most systems
  2237              */
  2237 	     */
  2238 #ifdef ENOTBLK
  2238 #ifdef ENOTBLK
  2239             case ENOTBLK:
  2239 	    case ENOTBLK:
  2240                 sym = @symbol(ENOTBLK);
  2240 		sym = @symbol(ENOTBLK);
  2241                 typ = @symbol(inappropriateReferentSignal);
  2241 		typ = @symbol(inappropriateReferentSignal);
  2242                 break;
  2242 		break;
  2243 #endif
  2243 #endif
  2244 #ifdef ETXTBSY
  2244 #ifdef ETXTBSY
  2245             case ETXTBSY:
  2245 	    case ETXTBSY:
  2246                 sym = @symbol(ETXTBSY);
  2246 		sym = @symbol(ETXTBSY);
  2247                 typ = @symbol(inaccessibleSignal);
  2247 		typ = @symbol(inaccessibleSignal);
  2248                 break;
  2248 		break;
  2249 #endif
  2249 #endif
  2250             /*
  2250 	    /*
  2251              * some others
  2251 	     * some others
  2252              */
  2252 	     */
  2253 #ifdef EWOULDBLOCK
  2253 #ifdef EWOULDBLOCK
  2254             case EWOULDBLOCK:
  2254 	    case EWOULDBLOCK:
  2255                 sym = @symbol(EWOULDBLOCK);
  2255 		sym = @symbol(EWOULDBLOCK);
  2256                 typ = @symbol(notReadySignal);
  2256 		typ = @symbol(notReadySignal);
  2257                 break;
  2257 		break;
  2258 #endif
  2258 #endif
  2259 #ifdef ENOMSG
  2259 #ifdef ENOMSG
  2260             case ENOMSG:
  2260 	    case ENOMSG:
  2261                 sym = @symbol(ENOMSG);
  2261 		sym = @symbol(ENOMSG);
  2262                 typ = @symbol(noDataSignal);
  2262 		typ = @symbol(noDataSignal);
  2263                 break;
  2263 		break;
  2264 #endif
  2264 #endif
  2265 #ifdef ELOOP
  2265 #ifdef ELOOP
  2266             case ELOOP:
  2266 	    case ELOOP:
  2267                 sym = @symbol(ELOOP);
  2267 		sym = @symbol(ELOOP);
  2268                 typ = @symbol(rangeErrorSignal);
  2268 		typ = @symbol(rangeErrorSignal);
  2269                 break;
  2269 		break;
  2270 #endif
  2270 #endif
  2271 
  2271 
  2272             /*
  2272 	    /*
  2273              * some stream errors
  2273 	     * some stream errors
  2274              */
  2274 	     */
  2275 #ifdef ETIME
  2275 #ifdef ETIME
  2276             case ETIME:
  2276 	    case ETIME:
  2277                 sym = @symbol(ETIME);
  2277 		sym = @symbol(ETIME);
  2278                 typ = @symbol(peerFaultSignal);
  2278 		typ = @symbol(peerFaultSignal);
  2279                 break;
  2279 		break;
  2280 #endif
  2280 #endif
  2281 #ifdef ENOSR
  2281 #ifdef ENOSR
  2282             case ENOSR:
  2282 	    case ENOSR:
  2283                 sym = @symbol(ENOSR);
  2283 		sym = @symbol(ENOSR);
  2284                 typ = @symbol(noResourcesSignal);
  2284 		typ = @symbol(noResourcesSignal);
  2285                 break;
  2285 		break;
  2286 #endif
  2286 #endif
  2287 #ifdef ENOSTR
  2287 #ifdef ENOSTR
  2288             case ENOSTR:
  2288 	    case ENOSTR:
  2289                 sym = @symbol(ENOSTR);
  2289 		sym = @symbol(ENOSTR);
  2290                 typ = @symbol(inappropriateReferentSignal);
  2290 		typ = @symbol(inappropriateReferentSignal);
  2291                 break;
  2291 		break;
  2292 #endif
  2292 #endif
  2293 #ifdef ECOMM
  2293 #ifdef ECOMM
  2294             case ECOMM:
  2294 	    case ECOMM:
  2295                 sym = @symbol(ECOMM);
  2295 		sym = @symbol(ECOMM);
  2296                 typ = @symbol(transferFaultSignal);
  2296 		typ = @symbol(transferFaultSignal);
  2297                 break;
  2297 		break;
  2298 #endif
  2298 #endif
  2299 #ifdef EPROTO
  2299 #ifdef EPROTO
  2300             case EPROTO:
  2300 	    case EPROTO:
  2301                 sym = @symbol(EPROTO);
  2301 		sym = @symbol(EPROTO);
  2302                 typ = @symbol(inappropriateOperationSignal);
  2302 		typ = @symbol(inappropriateOperationSignal);
  2303                 break;
  2303 		break;
  2304 #endif
  2304 #endif
  2305             /*
  2305 	    /*
  2306              * nfs errors
  2306 	     * nfs errors
  2307              */
  2307 	     */
  2308 #ifdef ESTALE
  2308 #ifdef ESTALE
  2309             case ESTALE:
  2309 	    case ESTALE:
  2310                 sym = @symbol(ESTALE);
  2310 		sym = @symbol(ESTALE);
  2311                 typ = @symbol(unavailableReferentSignal);
  2311 		typ = @symbol(unavailableReferentSignal);
  2312                 break;
  2312 		break;
  2313 #endif
  2313 #endif
  2314 #ifdef EREMOTE
  2314 #ifdef EREMOTE
  2315             case EREMOTE:
  2315 	    case EREMOTE:
  2316                 sym = @symbol(EREMOTE);
  2316 		sym = @symbol(EREMOTE);
  2317                 typ = @symbol(rangeErrorSignal);
  2317 		typ = @symbol(rangeErrorSignal);
  2318                 break;
  2318 		break;
  2319 #endif
  2319 #endif
  2320             /*
  2320 	    /*
  2321              * some networking errors
  2321 	     * some networking errors
  2322              */
  2322 	     */
  2323 #ifdef EINPROGRESS
  2323 #ifdef EINPROGRESS
  2324             case EINPROGRESS:
  2324 	    case EINPROGRESS:
  2325                 sym = @symbol(EINPROGRESS);
  2325 		sym = @symbol(EINPROGRESS);
  2326                 typ = @symbol(operationStartedSignal);
  2326 		typ = @symbol(operationStartedSignal);
  2327                 break;
  2327 		break;
  2328 #endif
  2328 #endif
  2329 #ifdef EALREADY
  2329 #ifdef EALREADY
  2330             case EALREADY:
  2330 	    case EALREADY:
  2331                 sym = @symbol(EALREADY);
  2331 		sym = @symbol(EALREADY);
  2332                 typ = @symbol(operationStartedSignal);
  2332 		typ = @symbol(operationStartedSignal);
  2333                 break;
  2333 		break;
  2334 #endif
  2334 #endif
  2335 #ifdef ENOTSOCK
  2335 #ifdef ENOTSOCK
  2336             case ENOTSOCK:
  2336 	    case ENOTSOCK:
  2337                 sym = @symbol(ENOTSOCK);
  2337 		sym = @symbol(ENOTSOCK);
  2338                 typ = @symbol(inappropriateOperationSignal);
  2338 		typ = @symbol(inappropriateOperationSignal);
  2339                 break;
  2339 		break;
  2340 #endif
  2340 #endif
  2341 #ifdef EDESTADDRREQ
  2341 #ifdef EDESTADDRREQ
  2342             case EDESTADDRREQ:
  2342 	    case EDESTADDRREQ:
  2343                 sym = @symbol(EDESTADDRREQ);
  2343 		sym = @symbol(EDESTADDRREQ);
  2344                 typ = @symbol(underspecifiedSignal);
  2344 		typ = @symbol(underspecifiedSignal);
  2345                 break;
  2345 		break;
  2346 #endif
  2346 #endif
  2347 #ifdef EMSGSIZE
  2347 #ifdef EMSGSIZE
  2348             case EMSGSIZE:
  2348 	    case EMSGSIZE:
  2349                 sym = @symbol(EMSGSIZE);
  2349 		sym = @symbol(EMSGSIZE);
  2350                 typ = @symbol(rangeErrorSignal);
  2350 		typ = @symbol(rangeErrorSignal);
  2351                 break;
  2351 		break;
  2352 #endif
  2352 #endif
  2353 #ifdef EPROTOTYPE
  2353 #ifdef EPROTOTYPE
  2354             case EPROTOTYPE:
  2354 	    case EPROTOTYPE:
  2355                 sym = @symbol(EPROTOTYPE);
  2355 		sym = @symbol(EPROTOTYPE);
  2356                 typ = @symbol(wrongSubtypeForOperationSignal);
  2356 		typ = @symbol(wrongSubtypeForOperationSignal);
  2357                 break;
  2357 		break;
  2358 #endif
  2358 #endif
  2359 #ifdef ENOPROTOOPT
  2359 #ifdef ENOPROTOOPT
  2360             case ENOPROTOOPT:
  2360 	    case ENOPROTOOPT:
  2361                 sym = @symbol(ENOPROTOOPT);
  2361 		sym = @symbol(ENOPROTOOPT);
  2362                 typ = @symbol(unsupportedOperationSignal);
  2362 		typ = @symbol(unsupportedOperationSignal);
  2363                 break;
  2363 		break;
  2364 #endif
  2364 #endif
  2365 #ifdef EPROTONOSUPPORT
  2365 #ifdef EPROTONOSUPPORT
  2366             case EPROTONOSUPPORT:
  2366 	    case EPROTONOSUPPORT:
  2367                 sym = @symbol(EPROTONOSUPPORT);
  2367 		sym = @symbol(EPROTONOSUPPORT);
  2368                 typ = @symbol(unsupportedOperationSignal);
  2368 		typ = @symbol(unsupportedOperationSignal);
  2369                 break;
  2369 		break;
  2370 #endif
  2370 #endif
  2371 #ifdef ESOCKTNOSUPPORT
  2371 #ifdef ESOCKTNOSUPPORT
  2372             case ESOCKTNOSUPPORT:
  2372 	    case ESOCKTNOSUPPORT:
  2373                 sym = @symbol(ESOCKTNOSUPPORT);
  2373 		sym = @symbol(ESOCKTNOSUPPORT);
  2374                 typ = @symbol(unsupportedOperationSignal);
  2374 		typ = @symbol(unsupportedOperationSignal);
  2375                 break;
  2375 		break;
  2376 #endif
  2376 #endif
  2377 #ifdef EOPNOTSUPP
  2377 #ifdef EOPNOTSUPP
  2378             case EOPNOTSUPP:
  2378 	    case EOPNOTSUPP:
  2379                 sym = @symbol(EOPNOTSUPP);
  2379 		sym = @symbol(EOPNOTSUPP);
  2380                 typ = @symbol(inappropriateOperationSignal);
  2380 		typ = @symbol(inappropriateOperationSignal);
  2381                 break;
  2381 		break;
  2382 #endif
  2382 #endif
  2383 #ifdef EPFNOSUPPORT
  2383 #ifdef EPFNOSUPPORT
  2384             case EPFNOSUPPORT:
  2384 	    case EPFNOSUPPORT:
  2385                 sym = @symbol(EPFNOSUPPORT);
  2385 		sym = @symbol(EPFNOSUPPORT);
  2386                 typ = @symbol(unsupportedOperationSignal);
  2386 		typ = @symbol(unsupportedOperationSignal);
  2387                 break;
  2387 		break;
  2388 #endif
  2388 #endif
  2389 #ifdef EAFNOSUPPORT
  2389 #ifdef EAFNOSUPPORT
  2390             case EAFNOSUPPORT:
  2390 	    case EAFNOSUPPORT:
  2391                 sym = @symbol(EAFNOSUPPORT);
  2391 		sym = @symbol(EAFNOSUPPORT);
  2392                 typ = @symbol(unsupportedOperationSignal);
  2392 		typ = @symbol(unsupportedOperationSignal);
  2393                 break;
  2393 		break;
  2394 #endif
  2394 #endif
  2395 #ifdef EADDRINUSE
  2395 #ifdef EADDRINUSE
  2396             case EADDRINUSE:
  2396 	    case EADDRINUSE:
  2397                 sym = @symbol(EADDRINUSE);
  2397 		sym = @symbol(EADDRINUSE);
  2398                 typ = @symbol(existingReferentSignal);
  2398 		typ = @symbol(existingReferentSignal);
  2399                 break;
  2399 		break;
  2400 #endif
  2400 #endif
  2401 #ifdef EADDRNOTAVAIL
  2401 #ifdef EADDRNOTAVAIL
  2402             case EADDRNOTAVAIL:
  2402 	    case EADDRNOTAVAIL:
  2403                 sym = @symbol(EADDRNOTAVAIL);
  2403 		sym = @symbol(EADDRNOTAVAIL);
  2404                 typ = @symbol(noPermissionsSignal);
  2404 		typ = @symbol(noPermissionsSignal);
  2405                 break;
  2405 		break;
  2406 #endif
  2406 #endif
  2407 #ifdef ETIMEDOUT
  2407 #ifdef ETIMEDOUT
  2408             case ETIMEDOUT:
  2408 	    case ETIMEDOUT:
  2409                 sym = @symbol(ETIMEDOUT);
  2409 		sym = @symbol(ETIMEDOUT);
  2410                 typ = @symbol(peerFaultSignal);
  2410 		typ = @symbol(peerFaultSignal);
  2411                 break;
  2411 		break;
  2412 #endif
  2412 #endif
  2413 #ifdef ECONNREFUSED
  2413 #ifdef ECONNREFUSED
  2414             case ECONNREFUSED:
  2414 	    case ECONNREFUSED:
  2415                 sym = @symbol(ECONNREFUSED);
  2415 		sym = @symbol(ECONNREFUSED);
  2416                 typ = @symbol(peerFaultSignal);
  2416 		typ = @symbol(peerFaultSignal);
  2417                 break;
  2417 		break;
  2418 #endif
  2418 #endif
  2419 #ifdef ENETDOWN
  2419 #ifdef ENETDOWN
  2420             case ENETDOWN:
  2420 	    case ENETDOWN:
  2421                 sym = @symbol(ENETDOWN);
  2421 		sym = @symbol(ENETDOWN);
  2422                 typ = @symbol(peerFaultSignal);
  2422 		typ = @symbol(peerFaultSignal);
  2423                 break;
  2423 		break;
  2424 #endif
  2424 #endif
  2425 #ifdef ENETUNREACH
  2425 #ifdef ENETUNREACH
  2426             case ENETUNREACH:
  2426 	    case ENETUNREACH:
  2427                 sym = @symbol(ENETUNREACH);
  2427 		sym = @symbol(ENETUNREACH);
  2428                 typ = @symbol(peerFaultSignal);
  2428 		typ = @symbol(peerFaultSignal);
  2429                 break;
  2429 		break;
  2430 #endif
  2430 #endif
  2431 #ifdef ENETRESET
  2431 #ifdef ENETRESET
  2432             case ENETRESET:
  2432 	    case ENETRESET:
  2433                 sym = @symbol(ENETRESET);
  2433 		sym = @symbol(ENETRESET);
  2434                 typ = @symbol(peerFaultSignal);
  2434 		typ = @symbol(peerFaultSignal);
  2435                 break;
  2435 		break;
  2436 #endif
  2436 #endif
  2437 #ifdef ECONNABORTED
  2437 #ifdef ECONNABORTED
  2438             case ECONNABORTED:
  2438 	    case ECONNABORTED:
  2439                 sym = @symbol(ECONNABORTED);
  2439 		sym = @symbol(ECONNABORTED);
  2440                 typ = @symbol(peerFaultSignal);
  2440 		typ = @symbol(peerFaultSignal);
  2441                 break;
  2441 		break;
  2442 #endif
  2442 #endif
  2443 #ifdef ECONNRESET
  2443 #ifdef ECONNRESET
  2444             case ECONNRESET:
  2444 	    case ECONNRESET:
  2445                 sym = @symbol(ECONNRESET);
  2445 		sym = @symbol(ECONNRESET);
  2446                 typ = @symbol(peerFaultSignal);
  2446 		typ = @symbol(peerFaultSignal);
  2447                 break;
  2447 		break;
  2448 #endif
  2448 #endif
  2449 #ifdef EISCONN
  2449 #ifdef EISCONN
  2450             case EISCONN:
  2450 	    case EISCONN:
  2451                 sym = @symbol(EISCONN);
  2451 		sym = @symbol(EISCONN);
  2452                 typ = @symbol(unpreparedOperationSignal);
  2452 		typ = @symbol(unpreparedOperationSignal);
  2453                 break;
  2453 		break;
  2454 #endif
  2454 #endif
  2455 #ifdef ENOTCONN
  2455 #ifdef ENOTCONN
  2456             case ENOTCONN:
  2456 	    case ENOTCONN:
  2457                 sym = @symbol(ENOTCONN);
  2457 		sym = @symbol(ENOTCONN);
  2458                 typ = @symbol(unpreparedOperationSignal);
  2458 		typ = @symbol(unpreparedOperationSignal);
  2459                 break;
  2459 		break;
  2460 #endif
  2460 #endif
  2461 #ifdef ESHUTDOWN
  2461 #ifdef ESHUTDOWN
  2462             case ESHUTDOWN:
  2462 	    case ESHUTDOWN:
  2463                 sym = @symbol(ESHUTDOWN);
  2463 		sym = @symbol(ESHUTDOWN);
  2464                 typ = @symbol(unpreparedOperationSignal);
  2464 		typ = @symbol(unpreparedOperationSignal);
  2465                 break;
  2465 		break;
  2466 #endif
  2466 #endif
  2467 #ifdef EHOSTDOWN
  2467 #ifdef EHOSTDOWN
  2468             case EHOSTDOWN:
  2468 	    case EHOSTDOWN:
  2469                 sym = @symbol(EHOSTDOWN);
  2469 		sym = @symbol(EHOSTDOWN);
  2470                 typ = @symbol(peerFaultSignal);
  2470 		typ = @symbol(peerFaultSignal);
  2471                 break;
  2471 		break;
  2472 #endif
  2472 #endif
  2473 #ifdef EHOSTUNREACH
  2473 #ifdef EHOSTUNREACH
  2474             case EHOSTUNREACH:
  2474 	    case EHOSTUNREACH:
  2475                 sym = @symbol(EHOSTUNREACH);
  2475 		sym = @symbol(EHOSTUNREACH);
  2476                 typ = @symbol(peerFaultSignal);
  2476 		typ = @symbol(peerFaultSignal);
  2477                 break;
  2477 		break;
  2478 #endif
  2478 #endif
  2479 #ifdef EDQUOT
  2479 #ifdef EDQUOT
  2480             case EDQUOT:
  2480 	    case EDQUOT:
  2481                 sym = @symbol(EDQUOT);
  2481 		sym = @symbol(EDQUOT);
  2482                 typ = @symbol(noResourcesSignal);
  2482 		typ = @symbol(noResourcesSignal);
  2483                 break;
  2483 		break;
  2484 #endif
  2484 #endif
  2485 
  2485 
  2486 #ifdef ENOMEDIUM
  2486 #ifdef ENOMEDIUM
  2487             case ENOMEDIUM:
  2487 	    case ENOMEDIUM:
  2488                 sym = @symbol(ENOMEDIUM);
  2488 		sym = @symbol(ENOMEDIUM);
  2489                 typ = @symbol(noResourcesSignal);
  2489 		typ = @symbol(noResourcesSignal);
  2490                 break;
  2490 		break;
  2491 #endif
  2491 #endif
  2492 #ifdef EMEDIUMTYPE
  2492 #ifdef EMEDIUMTYPE
  2493             case EMEDIUMTYPE:
  2493 	    case EMEDIUMTYPE:
  2494                 sym = @symbol(EMEDIUMTYPE);
  2494 		sym = @symbol(EMEDIUMTYPE);
  2495                 typ = @symbol(noResourcesSignal);
  2495 		typ = @symbol(noResourcesSignal);
  2496                 break;
  2496 		break;
  2497 #endif
  2497 #endif
  2498 
  2498 
  2499             default:
  2499 	    default:
  2500                 break;
  2500 		break;
  2501         }
  2501 	}
  2502     }
  2502     }
  2503 %}.
  2503 %}.
  2504     holder := OSErrorHolder new.
  2504     holder := OSErrorHolder new.
  2505     sym isNil ifTrue:[
  2505     sym isNil ifTrue:[
  2506         sym := #ERROR_OTHER.
  2506 	sym := #ERROR_OTHER.
  2507         errNr notNil ifTrue:[
  2507 	errNr notNil ifTrue:[
  2508             "keep symbols as symbols"
  2508 	    "keep symbols as symbols"
  2509             holder parameter:(errNr isString ifTrue:[errNr] ifFalse:[errNr asString]).
  2509 	    holder parameter:(errNr isString ifTrue:[errNr] ifFalse:[errNr asString]).
  2510         ].
  2510 	].
  2511     ].
  2511     ].
  2512     holder errorSymbol:sym errorCategory:(typ ? #defaultOsErrorSignal).
  2512     holder errorSymbol:sym errorCategory:(typ ? #defaultOsErrorSignal).
  2513     ^ holder
  2513     ^ holder
  2514 
  2514 
  2515 
  2515 
  2534     /*
  2534     /*
  2535      * POSIX errnos - these should be defined
  2535      * POSIX errnos - these should be defined
  2536      */
  2536      */
  2537 #ifdef EPERM
  2537 #ifdef EPERM
  2538     if (sym == @symbol(EPERM)) {
  2538     if (sym == @symbol(EPERM)) {
  2539         RETURN ( __mkSmallInteger(EPERM) );
  2539 	RETURN ( __mkSmallInteger(EPERM) );
  2540     }
  2540     }
  2541 #endif
  2541 #endif
  2542 
  2542 
  2543 #ifdef ENOENT
  2543 #ifdef ENOENT
  2544     /* ERROR_FILE_NOT_FOUND is originally windows, but referd to in ExternalStream>>#openError: */
  2544     /* ERROR_FILE_NOT_FOUND is originally windows, but referd to in ExternalStream>>#openError: */
  2545     if (sym == @symbol(ENOENT) || sym == @symbol(ERROR_FILE_NOT_FOUND)) {
  2545     if (sym == @symbol(ENOENT) || sym == @symbol(ERROR_FILE_NOT_FOUND)) {
  2546         RETURN ( __mkSmallInteger(ENOENT) );
  2546 	RETURN ( __mkSmallInteger(ENOENT) );
  2547     }
  2547     }
  2548 #endif
  2548 #endif
  2549 
  2549 
  2550 #ifdef ESRCH
  2550 #ifdef ESRCH
  2551     if (sym == @symbol(ESRCH)) {
  2551     if (sym == @symbol(ESRCH)) {
  2552         RETURN ( __mkSmallInteger(ESRCH) );
  2552 	RETURN ( __mkSmallInteger(ESRCH) );
  2553     }
  2553     }
  2554 #endif
  2554 #endif
  2555 
  2555 
  2556 #ifdef EINTR
  2556 #ifdef EINTR
  2557     if (sym == @symbol(EINTR)) {
  2557     if (sym == @symbol(EINTR)) {
  2558         RETURN ( __mkSmallInteger(EINTR) );
  2558 	RETURN ( __mkSmallInteger(EINTR) );
  2559     }
  2559     }
  2560 #endif
  2560 #endif
  2561 
  2561 
  2562 #ifdef EIO
  2562 #ifdef EIO
  2563     if (sym == @symbol(EIO)) {
  2563     if (sym == @symbol(EIO)) {
  2564         RETURN ( __mkSmallInteger(EIO) );
  2564 	RETURN ( __mkSmallInteger(EIO) );
  2565     }
  2565     }
  2566 #endif
  2566 #endif
  2567 
  2567 
  2568 #ifdef ENXIO
  2568 #ifdef ENXIO
  2569     if (sym == @symbol(ENXIO)) {
  2569     if (sym == @symbol(ENXIO)) {
  2570         RETURN ( __mkSmallInteger(ENXIO) );
  2570 	RETURN ( __mkSmallInteger(ENXIO) );
  2571     }
  2571     }
  2572 #endif
  2572 #endif
  2573 
  2573 
  2574 #ifdef E2BIG
  2574 #ifdef E2BIG
  2575     if (sym == @symbol(E2BIG)) {
  2575     if (sym == @symbol(E2BIG)) {
  2576         RETURN ( __mkSmallInteger(E2BIG) );
  2576 	RETURN ( __mkSmallInteger(E2BIG) );
  2577     }
  2577     }
  2578 #endif
  2578 #endif
  2579 
  2579 
  2580 #ifdef ENOEXEC
  2580 #ifdef ENOEXEC
  2581     if (sym == @symbol(ENOEXEC)) {
  2581     if (sym == @symbol(ENOEXEC)) {
  2582         RETURN ( __mkSmallInteger(ENOEXEC) );
  2582 	RETURN ( __mkSmallInteger(ENOEXEC) );
  2583     }
  2583     }
  2584 #endif
  2584 #endif
  2585 
  2585 
  2586 #ifdef EBADF
  2586 #ifdef EBADF
  2587     if (sym == @symbol(EBADF)) {
  2587     if (sym == @symbol(EBADF)) {
  2588         RETURN ( __mkSmallInteger(EBADF) );
  2588 	RETURN ( __mkSmallInteger(EBADF) );
  2589     }
  2589     }
  2590 #endif
  2590 #endif
  2591 
  2591 
  2592 #ifdef ECHILD
  2592 #ifdef ECHILD
  2593     if (sym == @symbol(ECHILD)) {
  2593     if (sym == @symbol(ECHILD)) {
  2594         RETURN ( __mkSmallInteger(ECHILD) );
  2594 	RETURN ( __mkSmallInteger(ECHILD) );
  2595     }
  2595     }
  2596 #endif
  2596 #endif
  2597 
  2597 
  2598 #if defined(EAGAIN)
  2598 #if defined(EAGAIN)
  2599     if (sym == @symbol(EAGAIN)) {
  2599     if (sym == @symbol(EAGAIN)) {
  2600         RETURN ( __mkSmallInteger(EAGAIN) );
  2600 	RETURN ( __mkSmallInteger(EAGAIN) );
  2601     }
  2601     }
  2602 #endif
  2602 #endif
  2603 
  2603 
  2604 #ifdef ENOMEM
  2604 #ifdef ENOMEM
  2605     if (sym == @symbol(ENOMEM)) {
  2605     if (sym == @symbol(ENOMEM)) {
  2606         RETURN ( __mkSmallInteger(ENOMEM) );
  2606 	RETURN ( __mkSmallInteger(ENOMEM) );
  2607     }
  2607     }
  2608 #endif
  2608 #endif
  2609 
  2609 
  2610 #ifdef EACCES
  2610 #ifdef EACCES
  2611     if (sym == @symbol(EACCES)) {
  2611     if (sym == @symbol(EACCES)) {
  2612         RETURN ( __mkSmallInteger(EACCES) );
  2612 	RETURN ( __mkSmallInteger(EACCES) );
  2613     }
  2613     }
  2614 #endif
  2614 #endif
  2615 
  2615 
  2616 #ifdef EFAULT
  2616 #ifdef EFAULT
  2617     if (sym == @symbol(EFAULT)) {
  2617     if (sym == @symbol(EFAULT)) {
  2618         RETURN ( __mkSmallInteger(EFAULT) );
  2618 	RETURN ( __mkSmallInteger(EFAULT) );
  2619     }
  2619     }
  2620 #endif
  2620 #endif
  2621 
  2621 
  2622 #ifdef EBUSY
  2622 #ifdef EBUSY
  2623     if (sym == @symbol(EBUSY)) {
  2623     if (sym == @symbol(EBUSY)) {
  2624         RETURN ( __mkSmallInteger(EBUSY) );
  2624 	RETURN ( __mkSmallInteger(EBUSY) );
  2625     }
  2625     }
  2626 #endif
  2626 #endif
  2627 
  2627 
  2628 #ifdef EXDEV
  2628 #ifdef EXDEV
  2629     if (sym == @symbol(EXDEV)) {
  2629     if (sym == @symbol(EXDEV)) {
  2630         RETURN ( __mkSmallInteger(EXDEV) );
  2630 	RETURN ( __mkSmallInteger(EXDEV) );
  2631     }
  2631     }
  2632 #endif
  2632 #endif
  2633 
  2633 
  2634 #ifdef ENODEV
  2634 #ifdef ENODEV
  2635     if (sym == @symbol(ENODEV)) {
  2635     if (sym == @symbol(ENODEV)) {
  2636         RETURN ( __mkSmallInteger(ENODEV) );
  2636 	RETURN ( __mkSmallInteger(ENODEV) );
  2637     }
  2637     }
  2638 #endif
  2638 #endif
  2639 
  2639 
  2640 #ifdef ENOTDIR
  2640 #ifdef ENOTDIR
  2641     if (sym == @symbol(ENOTDIR)) {
  2641     if (sym == @symbol(ENOTDIR)) {
  2642         RETURN ( __mkSmallInteger(ENOTDIR) );
  2642 	RETURN ( __mkSmallInteger(ENOTDIR) );
  2643     }
  2643     }
  2644 #endif
  2644 #endif
  2645 
  2645 
  2646 #ifdef EISDIR
  2646 #ifdef EISDIR
  2647     if (sym == @symbol(EISDIR)) {
  2647     if (sym == @symbol(EISDIR)) {
  2648         RETURN ( __mkSmallInteger(EISDIR) );
  2648 	RETURN ( __mkSmallInteger(EISDIR) );
  2649     }
  2649     }
  2650 #endif
  2650 #endif
  2651 
  2651 
  2652 #ifdef EINVAL
  2652 #ifdef EINVAL
  2653     if (sym == @symbol(EINVAL)) {
  2653     if (sym == @symbol(EINVAL)) {
  2654         RETURN ( __mkSmallInteger(EINVAL) );
  2654 	RETURN ( __mkSmallInteger(EINVAL) );
  2655     }
  2655     }
  2656 #endif
  2656 #endif
  2657 
  2657 
  2658 #ifdef ENFILE
  2658 #ifdef ENFILE
  2659     if (sym == @symbol(ENFILE)) {
  2659     if (sym == @symbol(ENFILE)) {
  2660         RETURN ( __mkSmallInteger(ENFILE) );
  2660 	RETURN ( __mkSmallInteger(ENFILE) );
  2661     }
  2661     }
  2662 #endif
  2662 #endif
  2663 
  2663 
  2664 #ifdef EMFILE
  2664 #ifdef EMFILE
  2665     if (sym == @symbol(EMFILE)) {
  2665     if (sym == @symbol(EMFILE)) {
  2666         RETURN ( __mkSmallInteger(EMFILE) );
  2666 	RETURN ( __mkSmallInteger(EMFILE) );
  2667     }
  2667     }
  2668 #endif
  2668 #endif
  2669 
  2669 
  2670 #ifdef ENOTTY
  2670 #ifdef ENOTTY
  2671     if (sym == @symbol(ENOTTY)) {
  2671     if (sym == @symbol(ENOTTY)) {
  2672         RETURN ( __mkSmallInteger(ENOTTY) );
  2672 	RETURN ( __mkSmallInteger(ENOTTY) );
  2673     }
  2673     }
  2674 #endif
  2674 #endif
  2675 
  2675 
  2676 #ifdef EFBIG
  2676 #ifdef EFBIG
  2677     if (sym == @symbol(EFBIG)) {
  2677     if (sym == @symbol(EFBIG)) {
  2678         RETURN ( __mkSmallInteger(EFBIG) );
  2678 	RETURN ( __mkSmallInteger(EFBIG) );
  2679     }
  2679     }
  2680 #endif
  2680 #endif
  2681 
  2681 
  2682 #ifdef ENOSPC
  2682 #ifdef ENOSPC
  2683     if (sym == @symbol(ENOSPC)) {
  2683     if (sym == @symbol(ENOSPC)) {
  2684         RETURN ( __mkSmallInteger(ENOSPC) );
  2684 	RETURN ( __mkSmallInteger(ENOSPC) );
  2685     }
  2685     }
  2686 #endif
  2686 #endif
  2687 
  2687 
  2688 #ifdef ESPIPE
  2688 #ifdef ESPIPE
  2689     if (sym == @symbol(ESPIPE)) {
  2689     if (sym == @symbol(ESPIPE)) {
  2690         RETURN ( __mkSmallInteger(ESPIPE) );
  2690 	RETURN ( __mkSmallInteger(ESPIPE) );
  2691     }
  2691     }
  2692 #endif
  2692 #endif
  2693 
  2693 
  2694 #ifdef EROFS
  2694 #ifdef EROFS
  2695     if (sym == @symbol(EROFS)) {
  2695     if (sym == @symbol(EROFS)) {
  2696         RETURN ( __mkSmallInteger(EROFS) );
  2696 	RETURN ( __mkSmallInteger(EROFS) );
  2697     }
  2697     }
  2698 #endif
  2698 #endif
  2699 
  2699 
  2700 #ifdef EMLINK
  2700 #ifdef EMLINK
  2701     if (sym == @symbol(EMLINK)) {
  2701     if (sym == @symbol(EMLINK)) {
  2702         RETURN ( __mkSmallInteger(EMLINK) );
  2702 	RETURN ( __mkSmallInteger(EMLINK) );
  2703     }
  2703     }
  2704 #endif
  2704 #endif
  2705 
  2705 
  2706 #ifdef EPIPE
  2706 #ifdef EPIPE
  2707     if (sym == @symbol(EPIPE)) {
  2707     if (sym == @symbol(EPIPE)) {
  2708         RETURN ( __mkSmallInteger(EPIPE) );
  2708 	RETURN ( __mkSmallInteger(EPIPE) );
  2709     }
  2709     }
  2710 #endif
  2710 #endif
  2711 
  2711 
  2712 #ifdef EDOM
  2712 #ifdef EDOM
  2713     if (sym == @symbol(EDOM)) {
  2713     if (sym == @symbol(EDOM)) {
  2714         RETURN ( __mkSmallInteger(EDOM) );
  2714 	RETURN ( __mkSmallInteger(EDOM) );
  2715     }
  2715     }
  2716 #endif
  2716 #endif
  2717 
  2717 
  2718 #ifdef ERANGE
  2718 #ifdef ERANGE
  2719     if (sym == @symbol(ERANGE)) {
  2719     if (sym == @symbol(ERANGE)) {
  2720         RETURN ( __mkSmallInteger(ERANGE) );
  2720 	RETURN ( __mkSmallInteger(ERANGE) );
  2721     }
  2721     }
  2722 #endif
  2722 #endif
  2723 
  2723 
  2724 #ifdef EDEADLK
  2724 #ifdef EDEADLK
  2725     if (sym == @symbol(EDEADLK)) {
  2725     if (sym == @symbol(EDEADLK)) {
  2726         RETURN ( __mkSmallInteger(EDEADLK) );
  2726 	RETURN ( __mkSmallInteger(EDEADLK) );
  2727     }
  2727     }
  2728 #endif
  2728 #endif
  2729 
  2729 
  2730 #ifdef ENAMETOOLONG
  2730 #ifdef ENAMETOOLONG
  2731     if (sym == @symbol(ENAMETOOLONG)) {
  2731     if (sym == @symbol(ENAMETOOLONG)) {
  2732         RETURN ( __mkSmallInteger(ENAMETOOLONG) );
  2732 	RETURN ( __mkSmallInteger(ENAMETOOLONG) );
  2733     }
  2733     }
  2734 #endif
  2734 #endif
  2735 
  2735 
  2736 #ifdef ENOLCK
  2736 #ifdef ENOLCK
  2737     if (sym == @symbol(ENOLCK)) {
  2737     if (sym == @symbol(ENOLCK)) {
  2738         RETURN ( __mkSmallInteger(ENOLCK) );
  2738 	RETURN ( __mkSmallInteger(ENOLCK) );
  2739     }
  2739     }
  2740 #endif
  2740 #endif
  2741 
  2741 
  2742 #ifdef ENOSYS
  2742 #ifdef ENOSYS
  2743     if (sym == @symbol(ENOSYS)) {
  2743     if (sym == @symbol(ENOSYS)) {
  2744         RETURN ( __mkSmallInteger(ENOSYS) );
  2744 	RETURN ( __mkSmallInteger(ENOSYS) );
  2745     }
  2745     }
  2746 #endif
  2746 #endif
  2747 
  2747 
  2748 #ifdef ENOTEMPTY
  2748 #ifdef ENOTEMPTY
  2749     if (sym == @symbol(ENOTEMPTY)) {
  2749     if (sym == @symbol(ENOTEMPTY)) {
  2750         RETURN ( __mkSmallInteger(ENOTEMPTY) );
  2750 	RETURN ( __mkSmallInteger(ENOTEMPTY) );
  2751     }
  2751     }
  2752 #endif
  2752 #endif
  2753 
  2753 
  2754 #ifdef EEXIST
  2754 #ifdef EEXIST
  2755     if (sym == @symbol(EEXIST)) {
  2755     if (sym == @symbol(EEXIST)) {
  2756         RETURN ( __mkSmallInteger(EEXIST) );
  2756 	RETURN ( __mkSmallInteger(EEXIST) );
  2757     }
  2757     }
  2758 #endif
  2758 #endif
  2759 
  2759 
  2760 #ifdef EILSEQ
  2760 #ifdef EILSEQ
  2761     if (sym == @symbol(EILSEQ)) {
  2761     if (sym == @symbol(EILSEQ)) {
  2762         RETURN ( __mkSmallInteger(EILSEQ) );
  2762 	RETURN ( __mkSmallInteger(EILSEQ) );
  2763     }
  2763     }
  2764 #endif
  2764 #endif
  2765 
  2765 
  2766     /*
  2766     /*
  2767      * XPG3 errnos - defined on most systems
  2767      * XPG3 errnos - defined on most systems
  2768      */
  2768      */
  2769 #ifdef ENOTBLK
  2769 #ifdef ENOTBLK
  2770     if (sym == @symbol(ENOTBLK)) {
  2770     if (sym == @symbol(ENOTBLK)) {
  2771         RETURN ( __mkSmallInteger(ENOTBLK) );
  2771 	RETURN ( __mkSmallInteger(ENOTBLK) );
  2772     }
  2772     }
  2773 #endif
  2773 #endif
  2774 
  2774 
  2775 #ifdef ETXTBSY
  2775 #ifdef ETXTBSY
  2776     if (sym == @symbol(ETXTBSY)) {
  2776     if (sym == @symbol(ETXTBSY)) {
  2777         RETURN ( __mkSmallInteger(ETXTBSY) );
  2777 	RETURN ( __mkSmallInteger(ETXTBSY) );
  2778     }
  2778     }
  2779 #endif
  2779 #endif
  2780 
  2780 
  2781     /*
  2781     /*
  2782      * some others
  2782      * some others
  2783      */
  2783      */
  2784 #ifdef EWOULDBLOCK
  2784 #ifdef EWOULDBLOCK
  2785     if (sym == @symbol(EWOULDBLOCK)) {
  2785     if (sym == @symbol(EWOULDBLOCK)) {
  2786         RETURN ( __mkSmallInteger(EWOULDBLOCK) );
  2786 	RETURN ( __mkSmallInteger(EWOULDBLOCK) );
  2787     }
  2787     }
  2788 #endif
  2788 #endif
  2789 
  2789 
  2790 #ifdef EOVERFLOW
  2790 #ifdef EOVERFLOW
  2791     if (sym == @symbol(EOVERFLOW)) {
  2791     if (sym == @symbol(EOVERFLOW)) {
  2792         RETURN ( __mkSmallInteger(EOVERFLOW) );
  2792 	RETURN ( __mkSmallInteger(EOVERFLOW) );
  2793     }
  2793     }
  2794 #endif
  2794 #endif
  2795 
  2795 
  2796 #ifdef ENOMSG
  2796 #ifdef ENOMSG
  2797     if (sym == @symbol(ENOMSG)) {
  2797     if (sym == @symbol(ENOMSG)) {
  2798         RETURN ( __mkSmallInteger(ENOMSG) );
  2798 	RETURN ( __mkSmallInteger(ENOMSG) );
  2799     }
  2799     }
  2800 #endif
  2800 #endif
  2801 
  2801 
  2802 #ifdef ELOOP
  2802 #ifdef ELOOP
  2803     if (sym == @symbol(ELOOP)) {
  2803     if (sym == @symbol(ELOOP)) {
  2804         RETURN ( __mkSmallInteger(ELOOP) );
  2804 	RETURN ( __mkSmallInteger(ELOOP) );
  2805     }
  2805     }
  2806 #endif
  2806 #endif
  2807 
  2807 
  2808     /*
  2808     /*
  2809      * some stream errors
  2809      * some stream errors
  2810      */
  2810      */
  2811 #ifdef ETIME
  2811 #ifdef ETIME
  2812     if (sym == @symbol(ETIME)) {
  2812     if (sym == @symbol(ETIME)) {
  2813         RETURN ( __mkSmallInteger(ETIME) );
  2813 	RETURN ( __mkSmallInteger(ETIME) );
  2814     }
  2814     }
  2815 #endif
  2815 #endif
  2816 
  2816 
  2817 #ifdef ENOSR
  2817 #ifdef ENOSR
  2818     if (sym == @symbol(ENOSR)) {
  2818     if (sym == @symbol(ENOSR)) {
  2819         RETURN ( __mkSmallInteger(ENOSR) );
  2819 	RETURN ( __mkSmallInteger(ENOSR) );
  2820     }
  2820     }
  2821 #endif
  2821 #endif
  2822 
  2822 
  2823 #ifdef ENOSTR
  2823 #ifdef ENOSTR
  2824     if (sym == @symbol(ENOSTR)) {
  2824     if (sym == @symbol(ENOSTR)) {
  2825         RETURN ( __mkSmallInteger(ENOSTR) );
  2825 	RETURN ( __mkSmallInteger(ENOSTR) );
  2826     }
  2826     }
  2827 #endif
  2827 #endif
  2828 
  2828 
  2829 #ifdef ECOMM
  2829 #ifdef ECOMM
  2830     if (sym == @symbol(ECOMM)) {
  2830     if (sym == @symbol(ECOMM)) {
  2831         RETURN ( __mkSmallInteger(ECOMM) );
  2831 	RETURN ( __mkSmallInteger(ECOMM) );
  2832     }
  2832     }
  2833 #endif
  2833 #endif
  2834 
  2834 
  2835 #ifdef EPROTO
  2835 #ifdef EPROTO
  2836     if (sym == @symbol(EPROTO)) {
  2836     if (sym == @symbol(EPROTO)) {
  2837         RETURN ( __mkSmallInteger(EPROTO) );
  2837 	RETURN ( __mkSmallInteger(EPROTO) );
  2838     }
  2838     }
  2839 #endif
  2839 #endif
  2840 
  2840 
  2841     /*
  2841     /*
  2842      * nfs errors
  2842      * nfs errors
  2843      */
  2843      */
  2844 #ifdef ESTALE
  2844 #ifdef ESTALE
  2845     if (sym == @symbol(ESTALE)) {
  2845     if (sym == @symbol(ESTALE)) {
  2846         RETURN ( __mkSmallInteger(ESTALE) );
  2846 	RETURN ( __mkSmallInteger(ESTALE) );
  2847     }
  2847     }
  2848 #endif
  2848 #endif
  2849 
  2849 
  2850 #ifdef EREMOTE
  2850 #ifdef EREMOTE
  2851     if (sym == @symbol(EREMOTE)) {
  2851     if (sym == @symbol(EREMOTE)) {
  2852         RETURN ( __mkSmallInteger(EREMOTE) );
  2852 	RETURN ( __mkSmallInteger(EREMOTE) );
  2853     }
  2853     }
  2854 #endif
  2854 #endif
  2855 
  2855 
  2856     /*
  2856     /*
  2857      * some networking errors
  2857      * some networking errors
  2858      */
  2858      */
  2859 #ifdef EINPROGRESS
  2859 #ifdef EINPROGRESS
  2860     if (sym == @symbol(EINPROGRESS)) {
  2860     if (sym == @symbol(EINPROGRESS)) {
  2861         RETURN ( __mkSmallInteger(EINPROGRESS) );
  2861 	RETURN ( __mkSmallInteger(EINPROGRESS) );
  2862     }
  2862     }
  2863 #endif
  2863 #endif
  2864 
  2864 
  2865 #ifdef EALREADY
  2865 #ifdef EALREADY
  2866     if (sym == @symbol(EALREADY)) {
  2866     if (sym == @symbol(EALREADY)) {
  2867         RETURN ( __mkSmallInteger(EALREADY) );
  2867 	RETURN ( __mkSmallInteger(EALREADY) );
  2868     }
  2868     }
  2869 #endif
  2869 #endif
  2870 
  2870 
  2871 #ifdef ENOTSOCK
  2871 #ifdef ENOTSOCK
  2872     if (sym == @symbol(ENOTSOCK)) {
  2872     if (sym == @symbol(ENOTSOCK)) {
  2873         RETURN ( __mkSmallInteger(ENOTSOCK) );
  2873 	RETURN ( __mkSmallInteger(ENOTSOCK) );
  2874     }
  2874     }
  2875 #endif
  2875 #endif
  2876 
  2876 
  2877 #ifdef EDESTADDRREQ
  2877 #ifdef EDESTADDRREQ
  2878     if (sym == @symbol(EDESTADDRREQ)) {
  2878     if (sym == @symbol(EDESTADDRREQ)) {
  2879         RETURN ( __mkSmallInteger(EDESTADDRREQ) );
  2879 	RETURN ( __mkSmallInteger(EDESTADDRREQ) );
  2880     }
  2880     }
  2881 #endif
  2881 #endif
  2882 
  2882 
  2883 #ifdef EMSGSIZE
  2883 #ifdef EMSGSIZE
  2884     if (sym == @symbol(EMSGSIZE)) {
  2884     if (sym == @symbol(EMSGSIZE)) {
  2885         RETURN ( __mkSmallInteger(EMSGSIZE) );
  2885 	RETURN ( __mkSmallInteger(EMSGSIZE) );
  2886     }
  2886     }
  2887 #endif
  2887 #endif
  2888 
  2888 
  2889 #ifdef EPROTOTYPE
  2889 #ifdef EPROTOTYPE
  2890     if (sym == @symbol(EPROTOTYPE)) {
  2890     if (sym == @symbol(EPROTOTYPE)) {
  2891         RETURN ( __mkSmallInteger(EPROTOTYPE) );
  2891 	RETURN ( __mkSmallInteger(EPROTOTYPE) );
  2892     }
  2892     }
  2893 #endif
  2893 #endif
  2894 
  2894 
  2895 #ifdef ENOPROTOOPT
  2895 #ifdef ENOPROTOOPT
  2896     if (sym == @symbol(ENOPROTOOPT)) {
  2896     if (sym == @symbol(ENOPROTOOPT)) {
  2897         RETURN ( __mkSmallInteger(ENOPROTOOPT) );
  2897 	RETURN ( __mkSmallInteger(ENOPROTOOPT) );
  2898     }
  2898     }
  2899 #endif
  2899 #endif
  2900 
  2900 
  2901 #ifdef EPROTONOSUPPORT
  2901 #ifdef EPROTONOSUPPORT
  2902     if (sym == @symbol(EPROTONOSUPPORT)) {
  2902     if (sym == @symbol(EPROTONOSUPPORT)) {
  2903         RETURN ( __mkSmallInteger(EPROTONOSUPPORT) );
  2903 	RETURN ( __mkSmallInteger(EPROTONOSUPPORT) );
  2904     }
  2904     }
  2905 #endif
  2905 #endif
  2906 
  2906 
  2907 #ifdef ESOCKTNOSUPPORT
  2907 #ifdef ESOCKTNOSUPPORT
  2908     if (sym == @symbol(ESOCKTNOSUPPORT)) {
  2908     if (sym == @symbol(ESOCKTNOSUPPORT)) {
  2909         RETURN ( __mkSmallInteger(ESOCKTNOSUPPORT) );
  2909 	RETURN ( __mkSmallInteger(ESOCKTNOSUPPORT) );
  2910     }
  2910     }
  2911 #endif
  2911 #endif
  2912 
  2912 
  2913 #ifdef EOPNOTSUPP
  2913 #ifdef EOPNOTSUPP
  2914     if (sym == @symbol(EOPNOTSUPP)) {
  2914     if (sym == @symbol(EOPNOTSUPP)) {
  2915         RETURN ( __mkSmallInteger(EOPNOTSUPP) );
  2915 	RETURN ( __mkSmallInteger(EOPNOTSUPP) );
  2916     }
  2916     }
  2917 #endif
  2917 #endif
  2918 
  2918 
  2919 #ifdef EPFNOSUPPORT
  2919 #ifdef EPFNOSUPPORT
  2920     if (sym == @symbol(EPFNOSUPPORT)) {
  2920     if (sym == @symbol(EPFNOSUPPORT)) {
  2921         RETURN ( __mkSmallInteger(EPFNOSUPPORT) );
  2921 	RETURN ( __mkSmallInteger(EPFNOSUPPORT) );
  2922     }
  2922     }
  2923 #endif
  2923 #endif
  2924 
  2924 
  2925 #ifdef EAFNOSUPPORT
  2925 #ifdef EAFNOSUPPORT
  2926     if (sym == @symbol(EAFNOSUPPORT)) {
  2926     if (sym == @symbol(EAFNOSUPPORT)) {
  2927         RETURN ( __mkSmallInteger(EAFNOSUPPORT) );
  2927 	RETURN ( __mkSmallInteger(EAFNOSUPPORT) );
  2928     }
  2928     }
  2929 #endif
  2929 #endif
  2930 
  2930 
  2931 #ifdef EADDRINUSE
  2931 #ifdef EADDRINUSE
  2932     if (sym == @symbol(EADDRINUSE)) {
  2932     if (sym == @symbol(EADDRINUSE)) {
  2933         RETURN ( __mkSmallInteger(EADDRINUSE) );
  2933 	RETURN ( __mkSmallInteger(EADDRINUSE) );
  2934     }
  2934     }
  2935 #endif
  2935 #endif
  2936 
  2936 
  2937 #ifdef EADDRNOTAVAIL
  2937 #ifdef EADDRNOTAVAIL
  2938     if (sym == @symbol(EADDRNOTAVAIL)) {
  2938     if (sym == @symbol(EADDRNOTAVAIL)) {
  2939         RETURN ( __mkSmallInteger(EADDRNOTAVAIL) );
  2939 	RETURN ( __mkSmallInteger(EADDRNOTAVAIL) );
  2940     }
  2940     }
  2941 #endif
  2941 #endif
  2942 
  2942 
  2943 #ifdef ETIMEDOUT
  2943 #ifdef ETIMEDOUT
  2944     if (sym == @symbol(ETIMEDOUT)) {
  2944     if (sym == @symbol(ETIMEDOUT)) {
  2945         RETURN ( __mkSmallInteger(ETIMEDOUT) );
  2945 	RETURN ( __mkSmallInteger(ETIMEDOUT) );
  2946     }
  2946     }
  2947 #endif
  2947 #endif
  2948 
  2948 
  2949 #ifdef ECONNREFUSED
  2949 #ifdef ECONNREFUSED
  2950     if (sym == @symbol(ECONNREFUSED)) {
  2950     if (sym == @symbol(ECONNREFUSED)) {
  2951         RETURN ( __mkSmallInteger(ECONNREFUSED) );
  2951 	RETURN ( __mkSmallInteger(ECONNREFUSED) );
  2952     }
  2952     }
  2953 #endif
  2953 #endif
  2954 
  2954 
  2955 #ifdef ENETDOWN
  2955 #ifdef ENETDOWN
  2956     if (sym == @symbol(ENETDOWN)) {
  2956     if (sym == @symbol(ENETDOWN)) {
  2957         RETURN ( __mkSmallInteger(ENETDOWN) );
  2957 	RETURN ( __mkSmallInteger(ENETDOWN) );
  2958     }
  2958     }
  2959 #endif
  2959 #endif
  2960 
  2960 
  2961 #ifdef ENETUNREACH
  2961 #ifdef ENETUNREACH
  2962     if (sym == @symbol(ENETUNREACH)) {
  2962     if (sym == @symbol(ENETUNREACH)) {
  2963         RETURN ( __mkSmallInteger(ENETUNREACH) );
  2963 	RETURN ( __mkSmallInteger(ENETUNREACH) );
  2964     }
  2964     }
  2965 #endif
  2965 #endif
  2966 
  2966 
  2967 #ifdef ENETRESET
  2967 #ifdef ENETRESET
  2968     if (sym == @symbol(ENETRESET)) {
  2968     if (sym == @symbol(ENETRESET)) {
  2969         RETURN ( __mkSmallInteger(ENETRESET) );
  2969 	RETURN ( __mkSmallInteger(ENETRESET) );
  2970     }
  2970     }
  2971 #endif
  2971 #endif
  2972 
  2972 
  2973 #ifdef ECONNABORTED
  2973 #ifdef ECONNABORTED
  2974     if (sym == @symbol(ECONNABORTED)) {
  2974     if (sym == @symbol(ECONNABORTED)) {
  2975         RETURN ( __mkSmallInteger(ECONNABORTED) );
  2975 	RETURN ( __mkSmallInteger(ECONNABORTED) );
  2976     }
  2976     }
  2977 #endif
  2977 #endif
  2978 
  2978 
  2979 #ifdef ECONNRESET
  2979 #ifdef ECONNRESET
  2980     if (sym == @symbol(ECONNRESET)) {
  2980     if (sym == @symbol(ECONNRESET)) {
  2981         RETURN ( __mkSmallInteger(ECONNRESET) );
  2981 	RETURN ( __mkSmallInteger(ECONNRESET) );
  2982     }
  2982     }
  2983 #endif
  2983 #endif
  2984 
  2984 
  2985 #ifdef EISCONN
  2985 #ifdef EISCONN
  2986     if (sym == @symbol(EISCONN)) {
  2986     if (sym == @symbol(EISCONN)) {
  2987         RETURN ( __mkSmallInteger(EISCONN) );
  2987 	RETURN ( __mkSmallInteger(EISCONN) );
  2988     }
  2988     }
  2989 #endif
  2989 #endif
  2990 
  2990 
  2991 #ifdef ENOTCONN
  2991 #ifdef ENOTCONN
  2992     if (sym == @symbol(ENOTCONN)) {
  2992     if (sym == @symbol(ENOTCONN)) {
  2993         RETURN ( __mkSmallInteger(ENOTCONN) );
  2993 	RETURN ( __mkSmallInteger(ENOTCONN) );
  2994     }
  2994     }
  2995 #endif
  2995 #endif
  2996 
  2996 
  2997 #ifdef ESHUTDOWN
  2997 #ifdef ESHUTDOWN
  2998     if (sym == @symbol(ESHUTDOWN)) {
  2998     if (sym == @symbol(ESHUTDOWN)) {
  2999         RETURN ( __mkSmallInteger(ESHUTDOWN) );
  2999 	RETURN ( __mkSmallInteger(ESHUTDOWN) );
  3000     }
  3000     }
  3001 #endif
  3001 #endif
  3002 
  3002 
  3003 #ifdef EHOSTDOWN
  3003 #ifdef EHOSTDOWN
  3004     if (sym == @symbol(EHOSTDOWN)) {
  3004     if (sym == @symbol(EHOSTDOWN)) {
  3005         RETURN ( __mkSmallInteger(EHOSTDOWN) );
  3005 	RETURN ( __mkSmallInteger(EHOSTDOWN) );
  3006     }
  3006     }
  3007 #endif
  3007 #endif
  3008 
  3008 
  3009 #ifdef EHOSTUNREACH
  3009 #ifdef EHOSTUNREACH
  3010     if (sym == @symbol(EHOSTUNREACH)) {
  3010     if (sym == @symbol(EHOSTUNREACH)) {
  3011         RETURN ( __mkSmallInteger(EHOSTUNREACH) );
  3011 	RETURN ( __mkSmallInteger(EHOSTUNREACH) );
  3012     }
  3012     }
  3013 #endif
  3013 #endif
  3014 
  3014 
  3015 #ifdef EREMOTEIO
  3015 #ifdef EREMOTEIO
  3016     if (sym == @symbol(EREMOTEIO)) {
  3016     if (sym == @symbol(EREMOTEIO)) {
  3017         RETURN ( __mkSmallInteger(EREMOTEIO) );
  3017 	RETURN ( __mkSmallInteger(EREMOTEIO) );
  3018     }
  3018     }
  3019 #endif
  3019 #endif
  3020 #ifdef EDQUOT
  3020 #ifdef EDQUOT
  3021     if (sym == @symbol(EDQUOT)) {
  3021     if (sym == @symbol(EDQUOT)) {
  3022         RETURN ( __mkSmallInteger(EDQUOT) );
  3022 	RETURN ( __mkSmallInteger(EDQUOT) );
  3023     }
  3023     }
  3024 #endif
  3024 #endif
  3025 #ifdef ENOMEDIUM
  3025 #ifdef ENOMEDIUM
  3026     if (sym == @symbol(ENOMEDIUM)) {
  3026     if (sym == @symbol(ENOMEDIUM)) {
  3027         RETURN ( __mkSmallInteger(ENOMEDIUM) );
  3027 	RETURN ( __mkSmallInteger(ENOMEDIUM) );
  3028     }
  3028     }
  3029 #endif
  3029 #endif
  3030 #ifdef EMEDIUMTYPE
  3030 #ifdef EMEDIUMTYPE
  3031     if (sym == @symbol(EMEDIUMTYPE)) {
  3031     if (sym == @symbol(EMEDIUMTYPE)) {
  3032         RETURN ( __mkSmallInteger(EMEDIUMTYPE) );
  3032 	RETURN ( __mkSmallInteger(EMEDIUMTYPE) );
  3033     }
  3033     }
  3034 #endif
  3034 #endif
  3035 
  3035 
  3036 %}.
  3036 %}.
  3037     ^ -1
  3037     ^ -1
  3047     fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory
  3047     fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory
  3048 
  3048 
  3049     "Internal lowLevel entry for combined fork & exec;
  3049     "Internal lowLevel entry for combined fork & exec;
  3050 
  3050 
  3051      If fork is false (chain a command):
  3051      If fork is false (chain a command):
  3052          execute the OS command specified by the argument, aCommandPath, with
  3052 	 execute the OS command specified by the argument, aCommandPath, with
  3053          arguments in argArray (no arguments, if nil).
  3053 	 arguments in argArray (no arguments, if nil).
  3054          If successful, this method does not return and smalltalk is gone.
  3054 	 If successful, this method does not return and smalltalk is gone.
  3055          If not successful, it does return.
  3055 	 If not successful, it does return.
  3056          Normal use is with forkForCommand.
  3056 	 Normal use is with forkForCommand.
  3057 
  3057 
  3058      If fork is true (subprocess command execution):
  3058      If fork is true (subprocess command execution):
  3059         fork a child to do the above.
  3059 	fork a child to do the above.
  3060         The process id of the child process is returned; nil if the fork failed.
  3060 	The process id of the child process is returned; nil if the fork failed.
  3061 
  3061 
  3062      fdColl contains the filedescriptors, to be used for the child (if fork is true).
  3062      fdColl contains the filedescriptors, to be used for the child (if fork is true).
  3063         fdArray[1] = 15 -> use fd 15 as stdin.
  3063 	fdArray[1] = 15 -> use fd 15 as stdin.
  3064         If an element of the array is set to nil, the corresponding filedescriptor
  3064 	If an element of the array is set to nil, the corresponding filedescriptor
  3065         will be closed for the child.
  3065 	will be closed for the child.
  3066         fdArray[1] == StdIn for child
  3066 	fdArray[1] == StdIn for child
  3067         fdArray[2] == StdOut for child
  3067 	fdArray[2] == StdOut for child
  3068         fdArray[3] == StdErr for child
  3068 	fdArray[3] == StdErr for child
  3069         on VMS, these must be channels as returned by createMailBox.
  3069 	on VMS, these must be channels as returned by createMailBox.
  3070         All filedescriptors not present in fdColl will be closed for the child.
  3070 	All filedescriptors not present in fdColl will be closed for the child.
  3071 
  3071 
  3072      If newPgrp is true, the subprocess will be established in a new process group.
  3072      If newPgrp is true, the subprocess will be established in a new process group.
  3073         The processgroup will be equal to id.
  3073 	The processgroup will be equal to id.
  3074         newPgrp is not used on WIN32 and VMS systems.
  3074 	newPgrp is not used on WIN32 and VMS systems.
  3075 
  3075 
  3076      environmentDictionary specifies environment variables which are passed differently from
  3076      environmentDictionary specifies environment variables which are passed differently from
  3077      the current environment. If non-nil, it must be a dictionary providing
  3077      the current environment. If non-nil, it must be a dictionary providing
  3078      key-value pairs for changed/added environment variables.
  3078      key-value pairs for changed/added environment variables.
  3079      To pass a variable as empty (i.e. unset), pass a nil value.
  3079      To pass a variable as empty (i.e. unset), pass a nil value.
  3080 
  3080 
  3081      Notice: this used to be two separate ST-methods; however, in order to use
  3081      Notice: this used to be two separate ST-methods; however, in order to use
  3082             vfork on some machines, it had to be merged into one, to avoid write
  3082 	    vfork on some machines, it had to be merged into one, to avoid write
  3083             accesses to ST/X memory from the vforked-child.
  3083 	    accesses to ST/X memory from the vforked-child.
  3084             The code below only does read accesses."
  3084 	    The code below only does read accesses."
  3085 
  3085 
  3086     |envArray argArray fdArray dirName cnt aCommandPath|
  3086     |envArray argArray fdArray dirName cnt aCommandPath|
  3087 
  3087 
  3088     environmentDictionary notEmptyOrNil ifTrue:[
  3088     environmentDictionary notEmptyOrNil ifTrue:[
  3089         envArray := Array new:environmentDictionary size.
  3089 	envArray := Array new:environmentDictionary size.
  3090         cnt := 1.
  3090 	cnt := 1.
  3091         environmentDictionary keysAndValuesDo:[:key :val |
  3091 	environmentDictionary keysAndValuesDo:[:key :val |
  3092             val isNil ifTrue:[
  3092 	    val isNil ifTrue:[
  3093                 envArray at:cnt put:((self encodePath:key), '=')
  3093 		envArray at:cnt put:((self encodePath:key), '=')
  3094             ] ifFalse:[
  3094 	    ] ifFalse:[
  3095                 envArray at:cnt put:((self encodePath:key), '=', (self encodePath:val))
  3095 		envArray at:cnt put:((self encodePath:key), '=', (self encodePath:val))
  3096             ].
  3096 	    ].
  3097             cnt := cnt + 1.
  3097 	    cnt := cnt + 1.
  3098         ].
  3098 	].
  3099     ].
  3099     ].
  3100     argColl notNil ifTrue:[
  3100     argColl notNil ifTrue:[
  3101         argArray := argColl asArray collect:[:eachArg| self encodePath:eachArg].
  3101 	argArray := argColl asArray collect:[:eachArg| self encodePath:eachArg].
  3102     ].
  3102     ].
  3103     fdColl notNil ifTrue:[
  3103     fdColl notNil ifTrue:[
  3104         fdArray := fdColl asArray
  3104 	fdArray := fdColl asArray
  3105     ].
  3105     ].
  3106     aDirectory notNil ifTrue:[
  3106     aDirectory notNil ifTrue:[
  3107         dirName := aDirectory asFilename osNameForFile.
  3107 	dirName := aDirectory asFilename osNameForFile.
  3108         dirName := self encodePath:dirName.
  3108 	dirName := self encodePath:dirName.
  3109     ].
  3109     ].
  3110     aCommandPath := self encodePath:aCommandPathArg.
  3110     aCommandPath := self encodePath:aCommandPathArg.
  3111 
  3111 
  3112 %{  /* STACK: 16000 */
  3112 %{  /* STACK: 16000 */
  3113     char **argv;
  3113     char **argv;
  3119     extern char **environ;
  3119     extern char **environ;
  3120 #endif
  3120 #endif
  3121     char **_env, **_nEnv;
  3121     char **_env, **_nEnv;
  3122 
  3122 
  3123     if (__isStringLike(aCommandPath) &&
  3123     if (__isStringLike(aCommandPath) &&
  3124         ((argArray == nil) || __isArrayLike(argArray)) &&
  3124 	((argArray == nil) || __isArrayLike(argArray)) &&
  3125         ((fdArray == nil) || __isArrayLike(fdArray))
  3125 	((fdArray == nil) || __isArrayLike(fdArray))
  3126     ) {
  3126     ) {
  3127         nargs = argArray == nil ? 0 : __arraySize(argArray);
  3127 	nargs = argArray == nil ? 0 : __arraySize(argArray);
  3128         argv = (char **) malloc(sizeof(char *) * (nargs + 1));
  3128 	argv = (char **) malloc(sizeof(char *) * (nargs + 1));
  3129         if (argv) {
  3129 	if (argv) {
  3130             int nOldEnv, nNewEnv;
  3130 	    int nOldEnv, nNewEnv;
  3131 
  3131 
  3132             for (i=0; i < nargs; i++) {
  3132 	    for (i=0; i < nargs; i++) {
  3133                 arg = __ArrayInstPtr(argArray)->a_element[i];
  3133 		arg = __ArrayInstPtr(argArray)->a_element[i];
  3134                 if (__isStringLike(arg)) {
  3134 		if (__isStringLike(arg)) {
  3135                     argv[i] = (char *) __stringVal(arg);
  3135 		    argv[i] = (char *) __stringVal(arg);
  3136                 } else {
  3136 		} else {
  3137                     argv[i] = "";
  3137 		    argv[i] = "";
  3138                 }
  3138 		}
  3139             }
  3139 	    }
  3140             argv[i] = NULL;
  3140 	    argv[i] = NULL;
  3141 
  3141 
  3142             /*
  3142 	    /*
  3143              * number of new items in environment ..
  3143 	     * number of new items in environment ..
  3144              */
  3144 	     */
  3145             nNewEnv = 0;
  3145 	    nNewEnv = 0;
  3146             if ((envArray != nil) && __isArrayLike(envArray)) {
  3146 	    if ((envArray != nil) && __isArrayLike(envArray)) {
  3147                 nNewEnv = __arraySize(envArray);
  3147 		nNewEnv = __arraySize(envArray);
  3148             }
  3148 	    }
  3149 
  3149 
  3150             if (nNewEnv == 0) {
  3150 	    if (nNewEnv == 0) {
  3151                 _nEnv = environ;
  3151 		_nEnv = environ;
  3152             } else {
  3152 	    } else {
  3153                 _env = environ;
  3153 		_env = environ;
  3154                 /*
  3154 		/*
  3155                  * get size of environment
  3155 		 * get size of environment
  3156                  */
  3156 		 */
  3157                 nOldEnv = 0;
  3157 		nOldEnv = 0;
  3158                 if (_env) {
  3158 		if (_env) {
  3159                     while (*_env) {
  3159 		    while (*_env) {
  3160                         nOldEnv++;
  3160 			nOldEnv++;
  3161                         _env++;
  3161 			_env++;
  3162                     }
  3162 		    }
  3163                 }
  3163 		}
  3164 
  3164 
  3165                 /*
  3165 		/*
  3166                  * generate a new environment
  3166 		 * generate a new environment
  3167                  * I have not found a spec which defines if
  3167 		 * I have not found a spec which defines if
  3168                  * items at the end overwrite previous definitions,
  3168 		 * items at the end overwrite previous definitions,
  3169                  * or if the first encountered definition is valid.
  3169 		 * or if the first encountered definition is valid.
  3170                  * To be prepared for any case, simply add the new definitions
  3170 		 * To be prepared for any case, simply add the new definitions
  3171                  * at both ends - that should do it in any case.
  3171 		 * at both ends - that should do it in any case.
  3172                  * Someone with more know-how may want to fix this.
  3172 		 * Someone with more know-how may want to fix this.
  3173                  * getenv() searches for the first entry.
  3173 		 * getenv() searches for the first entry.
  3174                  * But maybe someone creates a Dictionary from the environment.
  3174 		 * But maybe someone creates a Dictionary from the environment.
  3175                  * In this case the last entry would overwrite previous entries.
  3175 		 * In this case the last entry would overwrite previous entries.
  3176                  */
  3176 		 */
  3177                 _nEnv = (char **)malloc(sizeof(char *) * (nNewEnv + nOldEnv + nNewEnv + 1));
  3177 		_nEnv = (char **)malloc(sizeof(char *) * (nNewEnv + nOldEnv + nNewEnv + 1));
  3178                 if (_nEnv) {
  3178 		if (_nEnv) {
  3179                     char **eO, **eN;
  3179 		    char **eO, **eN;
  3180 
  3180 
  3181                     eN = _nEnv;
  3181 		    eN = _nEnv;
  3182                     if (nNewEnv) {
  3182 		    if (nNewEnv) {
  3183                         /*
  3183 			/*
  3184                          * add new items at the front ...
  3184 			 * add new items at the front ...
  3185                          */
  3185 			 */
  3186                         int i;
  3186 			int i;
  3187                         OBJ *t;
  3187 			OBJ *t;
  3188 
  3188 
  3189                         for (i=0, t = __arrayVal(envArray);
  3189 			for (i=0, t = __arrayVal(envArray);
  3190                              i < __arraySize(envArray);
  3190 			     i < __arraySize(envArray);
  3191                              i++, t++) {
  3191 			     i++, t++) {
  3192 
  3192 
  3193                             if (__isStringLike(*t)) {
  3193 			    if (__isStringLike(*t)) {
  3194                                 *eN++ = (char *)__stringVal(*t);
  3194 				*eN++ = (char *)__stringVal(*t);
  3195                             }
  3195 			    }
  3196                         }
  3196 			}
  3197                     }
  3197 		    }
  3198 
  3198 
  3199                     if (nOldEnv) {
  3199 		    if (nOldEnv) {
  3200                         /*
  3200 			/*
  3201                          * append old environment
  3201 			 * append old environment
  3202                          */
  3202 			 */
  3203                         for (eO = environ; *eO; *eN++ = *eO++)
  3203 			for (eO = environ; *eO; *eN++ = *eO++)
  3204                             continue;
  3204 			    continue;
  3205                     }
  3205 		    }
  3206 
  3206 
  3207                     if (nNewEnv) {
  3207 		    if (nNewEnv) {
  3208                         /*
  3208 			/*
  3209                          * append new items again at the end
  3209 			 * append new items again at the end
  3210                          */
  3210 			 */
  3211                         for (eO = _nEnv, i=0; i<nNewEnv; i++) {
  3211 			for (eO = _nEnv, i=0; i<nNewEnv; i++) {
  3212                             *eN++ = *eO++;
  3212 			    *eN++ = *eO++;
  3213                         }
  3213 			}
  3214                     }
  3214 		    }
  3215                     *eN = NULL;
  3215 		    *eN = NULL;
  3216                 }
  3216 		}
  3217             }
  3217 	    }
  3218 
  3218 
  3219             if (doFork == true) {
  3219 	    if (doFork == true) {
  3220                 /*
  3220 		/*
  3221                  * fork a subprocess.
  3221 		 * fork a subprocess.
  3222                  */
  3222 		 */
  3223                 int nfd;
  3223 		int nfd;
  3224 
  3224 
  3225                 nfd = fdArray == nil ? 0 : __arraySize(fdArray);
  3225 		nfd = fdArray == nil ? 0 : __arraySize(fdArray);
  3226                 id = FORK ();
  3226 		id = FORK ();
  3227                 if (id == 0) {
  3227 		if (id == 0) {
  3228                     /*
  3228 		    /*
  3229                     ** In child.
  3229 		    ** In child.
  3230                     ** first: dup filedescriptors.
  3230 		    ** first: dup filedescriptors.
  3231                     */
  3231 		    */
  3232                     for (i = 0; i < nfd; i++) {
  3232 		    for (i = 0; i < nfd; i++) {
  3233                         OBJ fd;
  3233 			OBJ fd;
  3234                         int rslt;
  3234 			int rslt;
  3235 
  3235 
  3236                         fd = __arrayVal(fdArray)[i];
  3236 			fd = __arrayVal(fdArray)[i];
  3237                         if (__isSmallInteger(fd) && (__intVal(fd) != i)) {
  3237 			if (__isSmallInteger(fd) && (__intVal(fd) != i)) {
  3238                             do {
  3238 			    do {
  3239                                 rslt = dup2(__intVal(fd), i);
  3239 				rslt = dup2(__intVal(fd), i);
  3240                             } while ((rslt < 0) && (errno == EINTR));
  3240 			    } while ((rslt < 0) && (errno == EINTR));
  3241                         }
  3241 			}
  3242                     }
  3242 		    }
  3243                     /*
  3243 		    /*
  3244                     ** Second: close descriptors
  3244 		    ** Second: close descriptors
  3245                     **         marked as unwanted
  3245 		    **         marked as unwanted
  3246                     ** (extra loop to allow duping of low filedescriptor numbers to
  3246 		    ** (extra loop to allow duping of low filedescriptor numbers to
  3247                     **  higher fd numbers)
  3247 		    **  higher fd numbers)
  3248                     */
  3248 		    */
  3249                     for (i = 0; i < nfd; i++) {
  3249 		    for (i = 0; i < nfd; i++) {
  3250                         if (__arrayVal(fdArray)[i] == nil) {
  3250 			if (__arrayVal(fdArray)[i] == nil) {
  3251                             close(i);
  3251 			    close(i);
  3252                         }
  3252 			}
  3253                     }
  3253 		    }
  3254 
  3254 
  3255                     /*
  3255 		    /*
  3256                     ** third: close all filedescriptors larger
  3256 		    ** third: close all filedescriptors larger
  3257                     ** then the explicitely closed or duped
  3257 		    ** then the explicitely closed or duped
  3258                     ** filedescriptors
  3258 		    ** filedescriptors
  3259                     */
  3259 		    */
  3260 #ifndef OPEN_MAX
  3260 #ifndef OPEN_MAX
  3261 # define OPEN_MAX       256
  3261 # define OPEN_MAX       256
  3262 #endif
  3262 #endif
  3263                     for ( ;i < OPEN_MAX; i++) {
  3263 		    for ( ;i < OPEN_MAX; i++) {
  3264                         close(i);
  3264 			close(i);
  3265                     }
  3265 		    }
  3266 
  3266 
  3267                     if (newPgrp == true) {
  3267 		    if (newPgrp == true) {
  3268 #ifndef NEXT
  3268 #ifndef NEXT
  3269                         setsid();
  3269 			setsid();
  3270 #endif
  3270 #endif
  3271 #if defined(TIOCSCTTY)
  3271 #if defined(TIOCSCTTY)
  3272                         ioctl(0, TIOCSCTTY, 0) ;
  3272 			ioctl(0, TIOCSCTTY, 0) ;
  3273 #endif
  3273 #endif
  3274 
  3274 
  3275 #if defined(TIOCSPGRP)
  3275 #if defined(TIOCSPGRP)
  3276                         {
  3276 			{
  3277                             int pgrp = getpid();
  3277 			    int pgrp = getpid();
  3278 
  3278 
  3279                             ioctl(0, TIOCSPGRP, (char *)&pgrp);
  3279 			    ioctl(0, TIOCSPGRP, (char *)&pgrp);
  3280                         }
  3280 			}
  3281 #endif
  3281 #endif
  3282 #if defined(_POSIX_JOB_CONTROL)
  3282 #if defined(_POSIX_JOB_CONTROL)
  3283                         (void) setpgid(0, 0);
  3283 			(void) setpgid(0, 0);
  3284 #else
  3284 #else
  3285 # if defined(BSD) || defined(LINUX)
  3285 # if defined(BSD) || defined(LINUX)
  3286                         (void) setpgrp(0);
  3286 			(void) setpgrp(0);
  3287 # endif
  3287 # endif
  3288 #endif
  3288 #endif
  3289                     }
  3289 		    }
  3290 
  3290 
  3291                     if (dirName == nil || chdir((char *)__stringVal(dirName)) == 0) {
  3291 		    if (dirName == nil || chdir((char *)__stringVal(dirName)) == 0) {
  3292                         execve((char *)__stringVal(aCommandPath), argv, _nEnv);
  3292 			execve((char *)__stringVal(aCommandPath), argv, _nEnv);
  3293                     }
  3293 		    }
  3294                     /* reached if chdir failed or aCommandPathh cannot be executed */
  3294 		    /* reached if chdir failed or aCommandPathh cannot be executed */
  3295                     _exit(127);                 /* POSIX 2 compatible exit value */
  3295 		    _exit(127);                 /* POSIX 2 compatible exit value */
  3296                 }
  3296 		}
  3297             } else {
  3297 	    } else {
  3298                 /*
  3298 		/*
  3299                  * no subprocess (i.e. transfer to another program)
  3299 		 * no subprocess (i.e. transfer to another program)
  3300                  */
  3300 		 */
  3301                 if (dirName == nil || chdir((char *)__stringVal(dirName)) == 0) {
  3301 		if (dirName == nil || chdir((char *)__stringVal(dirName)) == 0) {
  3302                     execve((char *)__stringVal(aCommandPath), argv, _nEnv);
  3302 		    execve((char *)__stringVal(aCommandPath), argv, _nEnv);
  3303                 }
  3303 		}
  3304                 /*
  3304 		/*
  3305                  * reached if chdir failed or command-path cannot be executed
  3305 		 * reached if chdir failed or command-path cannot be executed
  3306                  */
  3306 		 */
  3307                 id = -1;
  3307 		id = -1;
  3308             }
  3308 	    }
  3309 
  3309 
  3310             if (nNewEnv && (_nEnv != NULL)) {
  3310 	    if (nNewEnv && (_nEnv != NULL)) {
  3311                 /*
  3311 		/*
  3312                  * free new environment stuff
  3312 		 * free new environment stuff
  3313                  */
  3313 		 */
  3314                 free(_nEnv);
  3314 		free(_nEnv);
  3315             }
  3315 	    }
  3316 
  3316 
  3317             free(argv);
  3317 	    free(argv);
  3318 
  3318 
  3319             /*
  3319 	    /*
  3320              * In parent: succes or failure
  3320 	     * In parent: succes or failure
  3321              */
  3321 	     */
  3322             if (id == -1) {
  3322 	    if (id == -1) {
  3323                 RETURN (nil);
  3323 		RETURN (nil);
  3324             } else {
  3324 	    } else {
  3325                 RETURN (__mkSmallInteger(id));
  3325 		RETURN (__mkSmallInteger(id));
  3326             }
  3326 	    }
  3327         }
  3327 	}
  3328     }
  3328     }
  3329 %}.
  3329 %}.
  3330     "
  3330     "
  3331      path-argument not string
  3331      path-argument not string
  3332      or argArray not an array/nil
  3332      or argArray not an array/nil
  3338     "
  3338     "
  3339      |id|
  3339      |id|
  3340 
  3340 
  3341      id := OperatingSystem fork.
  3341      id := OperatingSystem fork.
  3342      id == 0 ifTrue:[
  3342      id == 0 ifTrue:[
  3343         'I am the child'.
  3343 	'I am the child'.
  3344         OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp').
  3344 	OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp').
  3345         'not reached'.
  3345 	'not reached'.
  3346      ]
  3346      ]
  3347     "
  3347     "
  3348     "
  3348     "
  3349      |id|
  3349      |id|
  3350 
  3350 
  3351      id := OperatingSystem fork.
  3351      id := OperatingSystem fork.
  3352      id == 0 ifTrue:[
  3352      id == 0 ifTrue:[
  3353         'I am the child'.
  3353 	'I am the child'.
  3354         OperatingSystem
  3354 	OperatingSystem
  3355            exec:'/bin/sh'
  3355 	   exec:'/bin/sh'
  3356            withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2').
  3356 	   withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2').
  3357         'not reached'.
  3357 	'not reached'.
  3358      ].
  3358      ].
  3359      id printNL.
  3359      id printNL.
  3360      (Delay forSeconds:3.5) wait.
  3360      (Delay forSeconds:3.5) wait.
  3361      'killing ...' printNL.
  3361      'killing ...' printNL.
  3362      OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id.
  3362      OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id.
  3390     "
  3390     "
  3391      |id|
  3391      |id|
  3392 
  3392 
  3393      id := OperatingSystem fork.
  3393      id := OperatingSystem fork.
  3394      id == 0 ifTrue:[
  3394      id == 0 ifTrue:[
  3395         'I am the child process' printCR.
  3395 	'I am the child process' printCR.
  3396         OperatingSystem exit
  3396 	OperatingSystem exit
  3397      ]
  3397      ]
  3398     "
  3398     "
  3399 !
  3399 !
  3400 
  3400 
  3401 startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
  3401 startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
  3417     |nullStream in out err shellAndArgs rslt auxFd|
  3417     |nullStream in out err shellAndArgs rslt auxFd|
  3418 
  3418 
  3419     aCommandString isNil ifTrue:[^ nil].
  3419     aCommandString isNil ifTrue:[^ nil].
  3420 
  3420 
  3421     (in := anExternalInStream) isNil ifTrue:[
  3421     (in := anExternalInStream) isNil ifTrue:[
  3422         nullStream := Filename nullDevice readWriteStream.
  3422 	nullStream := Filename nullDevice readWriteStream.
  3423         in := nullStream.
  3423 	in := nullStream.
  3424     ].
  3424     ].
  3425     (out := anExternalOutStream) isNil ifTrue:[
  3425     (out := anExternalOutStream) isNil ifTrue:[
  3426         nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
  3426 	nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
  3427         out := nullStream.
  3427 	out := nullStream.
  3428     ].
  3428     ].
  3429     (err := anExternalErrStream) isNil ifTrue:[
  3429     (err := anExternalErrStream) isNil ifTrue:[
  3430         err := out
  3430 	err := out
  3431     ].
  3431     ].
  3432     anAuxiliaryStream notNil ifTrue:[
  3432     anAuxiliaryStream notNil ifTrue:[
  3433         auxFd := anAuxiliaryStream fileDescriptor
  3433 	auxFd := anAuxiliaryStream fileDescriptor
  3434     ].
  3434     ].
  3435 
  3435 
  3436     shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
  3436     shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
  3437 
  3437 
  3438     rslt := self
  3438     rslt := self
  3439         exec:(shellAndArgs at:1)
  3439 	exec:(shellAndArgs at:1)
  3440         withArguments:(shellAndArgs at:2)
  3440 	withArguments:(shellAndArgs at:2)
  3441         environment:anEvironmentDictionary
  3441 	environment:anEvironmentDictionary
  3442         fileDescriptors:(Array with:in fileDescriptor
  3442 	fileDescriptors:(Array with:in fileDescriptor
  3443                                with:out fileDescriptor
  3443 			       with:out fileDescriptor
  3444                                with:err fileDescriptor
  3444 			       with:err fileDescriptor
  3445                                with:auxFd)
  3445 			       with:auxFd)
  3446         fork:true
  3446 	fork:true
  3447         newPgrp:true "/ false
  3447 	newPgrp:true "/ false
  3448         inDirectory:dir.
  3448 	inDirectory:dir.
  3449 
  3449 
  3450     nullStream notNil ifTrue:[
  3450     nullStream notNil ifTrue:[
  3451         nullStream close.
  3451 	nullStream close.
  3452     ].
  3452     ].
  3453 
  3453 
  3454     ^ rslt
  3454     ^ rslt
  3455 
  3455 
  3456     "blocking at current prio (i.e. only higher prio threads execute):
  3456     "blocking at current prio (i.e. only higher prio threads execute):
  3471      pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
  3471      pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
  3472 
  3472 
  3473      The following will no longer work. monitorPid has disappeared
  3473      The following will no longer work. monitorPid has disappeared
  3474 
  3474 
  3475      pid notNil ifTrue:[
  3475      pid notNil ifTrue:[
  3476          Processor monitorPid:pid action:[:OSstatus | sema signal ].
  3476 	 Processor monitorPid:pid action:[:OSstatus | sema signal ].
  3477      ].
  3477      ].
  3478      in close.
  3478      in close.
  3479      out close.
  3479      out close.
  3480      err close.
  3480      err close.
  3481      sema wait.
  3481      sema wait.
  3496      - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
  3496      - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
  3497      If aCommandString is an Array, the first element is the command to be executed,
  3497      If aCommandString is an Array, the first element is the command to be executed,
  3498      and the other elements are the arguments to the command. No shell is invoked in this case."
  3498      and the other elements are the arguments to the command. No shell is invoked in this case."
  3499 
  3499 
  3500     aCommandStringOrArray isNonByteCollection ifTrue:[
  3500     aCommandStringOrArray isNonByteCollection ifTrue:[
  3501         "if an array is passed, the command string has already been parsed an no shell is invoked"
  3501 	"if an array is passed, the command string has already been parsed an no shell is invoked"
  3502         ^ Array with:aCommandStringOrArray first with:aCommandStringOrArray.
  3502 	^ Array with:aCommandStringOrArray first with:aCommandStringOrArray.
  3503     ].
  3503     ].
  3504 
  3504 
  3505     "/
  3505     "/
  3506     "/ '/bin/sh -c <command>'
  3506     "/ '/bin/sh -c <command>'
  3507     "/
  3507     "/
  3521 
  3521 
  3522     "shortcut - use the /proc filesystem (if present).
  3522     "shortcut - use the /proc filesystem (if present).
  3523      Here we get an absolute path to the running executable."
  3523      Here we get an absolute path to the running executable."
  3524     info := '/proc/self/exe' asFilename linkInfo.
  3524     info := '/proc/self/exe' asFilename linkInfo.
  3525     info notNil ifTrue:[
  3525     info notNil ifTrue:[
  3526         path := info path.
  3526 	path := info path.
  3527         path notEmptyOrNil ifTrue:[
  3527 	path notEmptyOrNil ifTrue:[
  3528             ^ path
  3528 	    ^ path
  3529         ].
  3529 	].
  3530      ].
  3530      ].
  3531 
  3531 
  3532     "Fall back - do it the hard way"
  3532     "Fall back - do it the hard way"
  3533 
  3533 
  3534     ^ super nameOfSTXExecutable
  3534     ^ super nameOfSTXExecutable
  3545 
  3545 
  3546     |path f fExt commandFilename|
  3546     |path f fExt commandFilename|
  3547 
  3547 
  3548     commandFilename := aCommand asFilename.
  3548     commandFilename := aCommand asFilename.
  3549     commandFilename isAbsolute ifTrue:[
  3549     commandFilename isAbsolute ifTrue:[
  3550         ^ commandFilename pathName
  3550 	^ commandFilename pathName
  3551     ].
  3551     ].
  3552     commandFilename isExplicitRelative ifTrue:[
  3552     commandFilename isExplicitRelative ifTrue:[
  3553          ^ commandFilename pathName
  3553 	 ^ commandFilename pathName
  3554     ].
  3554     ].
  3555 
  3555 
  3556     path := self getEnvironment:'PATH'.
  3556     path := self getEnvironment:'PATH'.
  3557     path notEmptyOrNil ifTrue:[
  3557     path notEmptyOrNil ifTrue:[
  3558         (path asCollectionOfSubstringsSeparatedBy:self pathSeparator) do:[:eachPathComponent |
  3558 	(path asCollectionOfSubstringsSeparatedBy:self pathSeparator) do:[:eachPathComponent |
  3559             eachPathComponent isEmpty ifTrue:[
  3559 	    eachPathComponent isEmpty ifTrue:[
  3560                 f := commandFilename
  3560 		f := commandFilename
  3561             ] ifFalse:[
  3561 	    ] ifFalse:[
  3562                 f := eachPathComponent asFilename construct:aCommand.
  3562 		f := eachPathComponent asFilename construct:aCommand.
  3563             ].
  3563 	    ].
  3564             self executableFileExtensions do:[:eachExtension |
  3564 	    self executableFileExtensions do:[:eachExtension |
  3565                 eachExtension notEmpty ifTrue:[
  3565 		eachExtension notEmpty ifTrue:[
  3566                     fExt := f addSuffix:eachExtension.
  3566 		    fExt := f addSuffix:eachExtension.
  3567                 ] ifFalse:[
  3567 		] ifFalse:[
  3568                     fExt := f.
  3568 		    fExt := f.
  3569                 ].
  3569 		].
  3570                 fExt isExecutable ifTrue:[
  3570 		fExt isExecutable ifTrue:[
  3571                     ^ fExt pathName
  3571 		    ^ fExt pathName
  3572                 ].
  3572 		].
  3573             ].
  3573 	    ].
  3574         ].
  3574 	].
  3575     ].
  3575     ].
  3576     ^ nil
  3576     ^ nil
  3577 
  3577 
  3578     "unix:
  3578     "unix:
  3579 
  3579 
  3596 closeFd:anInteger
  3596 closeFd:anInteger
  3597     "low level close of a filedescriptor"
  3597     "low level close of a filedescriptor"
  3598 
  3598 
  3599 %{
  3599 %{
  3600      if (__isSmallInteger(anInteger)) {
  3600      if (__isSmallInteger(anInteger)) {
  3601         if (@global(ExternalStream:FileOpenTrace) == true) {
  3601 	if (@global(ExternalStream:FileOpenTrace) == true) {
  3602             fprintf(stderr, "close [UnixOp] fd=%d\n", (int)__intVal(anInteger));
  3602 	    fprintf(stderr, "close [UnixOp] fd=%d\n", (int)__intVal(anInteger));
  3603         }
  3603 	}
  3604         close(__intVal(anInteger));
  3604 	close(__intVal(anInteger));
  3605         RETURN(self);
  3605 	RETURN(self);
  3606      }
  3606      }
  3607 %}.
  3607 %}.
  3608      ^ self primitiveFailed.
  3608      ^ self primitiveFailed.
  3609 
  3609 
  3610     "
  3610     "
  3619 #if defined(HAS_SENDFILE)
  3619 #if defined(HAS_SENDFILE)
  3620      if (__isSmallInteger(inFd)
  3620      if (__isSmallInteger(inFd)
  3621       && __isSmallInteger(outFd)
  3621       && __isSmallInteger(outFd)
  3622       && __isSmallInteger(startIdx)
  3622       && __isSmallInteger(startIdx)
  3623       && __isSmallInteger(count)) {
  3623       && __isSmallInteger(count)) {
  3624         int nWritten;
  3624 	int nWritten;
  3625 
  3625 
  3626         nWritten = sendfile(__intVal(outFd), __intVal(inFd), __intVal(startIdx), __intVal(count));
  3626 	nWritten = sendfile(__intVal(outFd), __intVal(inFd), __intVal(startIdx), __intVal(count));
  3627         if (nWritten < 0) {
  3627 	if (nWritten < 0) {
  3628             @global(LastErrorNumber) = __mkSmallInteger(errno);
  3628 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  3629         }
  3629 	}
  3630         RETURN (__mkSmallInteger(nWritten));
  3630 	RETURN (__mkSmallInteger(nWritten));
  3631      }
  3631      }
  3632 #endif
  3632 #endif
  3633 %}.
  3633 %}.
  3634     ^ 0 "/ not supported
  3634     ^ 0 "/ not supported
  3635 !
  3635 !
  3660 
  3660 
  3661     encodedPathName := self encodePath:aPathName.
  3661     encodedPathName := self encodePath:aPathName.
  3662 
  3662 
  3663 %{
  3663 %{
  3664     if (__isStringLike(encodedPathName) && __isSmallInteger(umask)) {
  3664     if (__isStringLike(encodedPathName) && __isSmallInteger(umask)) {
  3665         if (mkdir(__stringVal(encodedPathName), __smallIntegerVal(umask)) >= 0) {
  3665 	if (mkdir(__stringVal(encodedPathName), __smallIntegerVal(umask)) >= 0) {
  3666             RETURN(true);
  3666 	    RETURN(true);
  3667         }
  3667 	}
  3668         @global(LastErrorNumber) = __mkSmallInteger(errno);
  3668 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  3669     }
  3669     }
  3670 %}.
  3670 %}.
  3671     "/ could not create - if it already existed this is ok
  3671     "/ could not create - if it already existed this is ok
  3672 
  3672 
  3673     (self isDirectory:aPathName) ifTrue:[^ true].
  3673     (self isDirectory:aPathName) ifTrue:[^ true].
  3705 
  3705 
  3706 %{
  3706 %{
  3707     int ret;
  3707     int ret;
  3708 
  3708 
  3709     if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
  3709     if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
  3710         __BEGIN_INTERRUPTABLE__
  3710 	__BEGIN_INTERRUPTABLE__
  3711         do {
  3711 	do {
  3712             ret = link((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  3712 	    ret = link((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  3713         } while (ret < 0 && errno == EINTR);
  3713 	} while (ret < 0 && errno == EINTR);
  3714         __END_INTERRUPTABLE__
  3714 	__END_INTERRUPTABLE__
  3715         if (ret < 0) {
  3715 	if (ret < 0) {
  3716             @global(LastErrorNumber) = __mkSmallInteger(errno);
  3716 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  3717             RETURN ( false );
  3717 	    RETURN ( false );
  3718         }
  3718 	}
  3719         RETURN (true);
  3719 	RETURN (true);
  3720     }
  3720     }
  3721 %}.
  3721 %}.
  3722     "/
  3722     "/
  3723     "/ bad argument(s) given
  3723     "/ bad argument(s) given
  3724     "/
  3724     "/
  3741 %{
  3741 %{
  3742 #ifdef S_IFLNK
  3742 #ifdef S_IFLNK
  3743     int ret;
  3743     int ret;
  3744 
  3744 
  3745     if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
  3745     if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
  3746         __BEGIN_INTERRUPTABLE__
  3746 	__BEGIN_INTERRUPTABLE__
  3747         do {
  3747 	do {
  3748             ret = symlink((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  3748 	    ret = symlink((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  3749         } while (ret < 0 && errno == EINTR);
  3749 	} while (ret < 0 && errno == EINTR);
  3750         __END_INTERRUPTABLE__
  3750 	__END_INTERRUPTABLE__
  3751         if (ret >= 0) {
  3751 	if (ret >= 0) {
  3752             RETURN (true);
  3752 	    RETURN (true);
  3753         }
  3753 	}
  3754         @global(LastErrorNumber) = error = __mkSmallInteger(errno);
  3754 	@global(LastErrorNumber) = error = __mkSmallInteger(errno);
  3755     }
  3755     }
  3756 #endif
  3756 #endif
  3757 %}.
  3757 %}.
  3758     (encodedOldPathName isString not or:[encodedNewPathName isString not]) ifTrue:[
  3758     (encodedOldPathName isString not or:[encodedNewPathName isString not]) ifTrue:[
  3759         "/
  3759 	"/
  3760         "/ bad argument(s) given
  3760 	"/ bad argument(s) given
  3761         "/
  3761 	"/
  3762         ^ self primitiveFailed
  3762 	^ self primitiveFailed
  3763     ].
  3763     ].
  3764     error notNil ifTrue:[
  3764     error notNil ifTrue:[
  3765         (self errorHolderForNumber:error) reportError
  3765 	(self errorHolderForNumber:error) reportError
  3766     ].
  3766     ].
  3767 
  3767 
  3768     "/
  3768     "/
  3769     "/ this Unix does not seem to support symbolic links
  3769     "/ this Unix does not seem to support symbolic links
  3770     "/
  3770     "/
  3778 
  3778 
  3779 open:path attributes:attributes mode:modeInteger
  3779 open:path attributes:attributes mode:modeInteger
  3780     "open a file, return an os specific fileHandle.
  3780     "open a file, return an os specific fileHandle.
  3781      openmode is a symbol defining the way to open
  3781      openmode is a symbol defining the way to open
  3782      valid modes are:
  3782      valid modes are:
  3783         #O_RDONLY
  3783 	#O_RDONLY
  3784         #O_RDWR
  3784 	#O_RDWR
  3785         #O_WRONLY
  3785 	#O_WRONLY
  3786         #O_CREAT
  3786 	#O_CREAT
  3787         #O_APPEND
  3787 	#O_APPEND
  3788         #O_SYNC
  3788 	#O_SYNC
  3789         #O_LARGEFILE
  3789 	#O_LARGEFILE
  3790 
  3790 
  3791      This is a private entry, but maybe useful to open/create a file in a special mode,
  3791      This is a private entry, but maybe useful to open/create a file in a special mode,
  3792      which is proprietrary to the operatingSystem."
  3792      which is proprietrary to the operatingSystem."
  3793 
  3793 
  3794     |error fileDescriptor encodedPathName|
  3794     |error fileDescriptor encodedPathName|
  3801     int fd;
  3801     int fd;
  3802     int mode, openFlags = 0;
  3802     int mode, openFlags = 0;
  3803     int n;
  3803     int n;
  3804 
  3804 
  3805     if (!__isStringLike(encodedPathName)) {
  3805     if (!__isStringLike(encodedPathName)) {
  3806         error = @symbol(badArgument1);
  3806 	error = @symbol(badArgument1);
  3807         goto err;
  3807 	goto err;
  3808     }
  3808     }
  3809     if (!__isArrayLike(attributes)) {
  3809     if (!__isArrayLike(attributes)) {
  3810         error = @symbol(badArgument2);
  3810 	error = @symbol(badArgument2);
  3811         goto err;
  3811 	goto err;
  3812     }
  3812     }
  3813     if (modeInteger == nil) {
  3813     if (modeInteger == nil) {
  3814         mode = 0644;
  3814 	mode = 0644;
  3815     } else if (__isSmallInteger(modeInteger)) {
  3815     } else if (__isSmallInteger(modeInteger)) {
  3816         mode = __intVal(modeInteger);
  3816 	mode = __intVal(modeInteger);
  3817     } else {
  3817     } else {
  3818         error = @symbol(badArgument3);
  3818 	error = @symbol(badArgument3);
  3819         goto err;
  3819 	goto err;
  3820     }
  3820     }
  3821 
  3821 
  3822     nAttributes = __arraySize(attributes);
  3822     nAttributes = __arraySize(attributes);
  3823     for (n = 0, ap = __arrayVal(attributes); n < nAttributes; n++) {
  3823     for (n = 0, ap = __arrayVal(attributes); n < nAttributes; n++) {
  3824         OBJ attribute = ap[n];
  3824 	OBJ attribute = ap[n];
  3825 
  3825 
  3826         if (attribute == @symbol(O_RDONLY)) {
  3826 	if (attribute == @symbol(O_RDONLY)) {
  3827             openFlags |= O_RDONLY;
  3827 	    openFlags |= O_RDONLY;
  3828         } else if (attribute == @symbol(O_RDWR)) {
  3828 	} else if (attribute == @symbol(O_RDWR)) {
  3829             openFlags |= O_RDWR;
  3829 	    openFlags |= O_RDWR;
  3830         } else if (attribute == @symbol(O_WRONLY)) {
  3830 	} else if (attribute == @symbol(O_WRONLY)) {
  3831             openFlags |= O_WRONLY;
  3831 	    openFlags |= O_WRONLY;
  3832         } else if (attribute == @symbol(O_CREAT)) {
  3832 	} else if (attribute == @symbol(O_CREAT)) {
  3833             openFlags |= O_CREAT;
  3833 	    openFlags |= O_CREAT;
  3834         } else if (attribute == @symbol(O_APPEND)) {
  3834 	} else if (attribute == @symbol(O_APPEND)) {
  3835             openFlags |= O_APPEND;
  3835 	    openFlags |= O_APPEND;
  3836         } else if (attribute == @symbol(O_EXCL)) {
  3836 	} else if (attribute == @symbol(O_EXCL)) {
  3837             openFlags |= O_EXCL;
  3837 	    openFlags |= O_EXCL;
  3838         } else if (attribute == @symbol(O_TRUNC)) {
  3838 	} else if (attribute == @symbol(O_TRUNC)) {
  3839             openFlags |= O_TRUNC;
  3839 	    openFlags |= O_TRUNC;
  3840         } else if (attribute == @symbol(O_LARGEFILE)) {
  3840 	} else if (attribute == @symbol(O_LARGEFILE)) {
  3841 #ifdef O_LARGEFILE
  3841 #ifdef O_LARGEFILE
  3842             openFlags |= O_LARGEFILE;
  3842 	    openFlags |= O_LARGEFILE;
  3843 #else
  3843 #else
  3844             error = @symbol(badArgument2);
  3844 	    error = @symbol(badArgument2);
  3845             goto err;
  3845 	    goto err;
  3846 #endif
  3846 #endif
  3847         } else if (attribute == @symbol(O_SYNC)) {
  3847 	} else if (attribute == @symbol(O_SYNC)) {
  3848 #ifdef O_SYNC
  3848 #ifdef O_SYNC
  3849             openFlags |= O_SYNC;
  3849 	    openFlags |= O_SYNC;
  3850 #else
  3850 #else
  3851             error = @symbol(badArgument2);
  3851 	    error = @symbol(badArgument2);
  3852             goto err;
  3852 	    goto err;
  3853 #endif
  3853 #endif
  3854         }
  3854 	}
  3855     }
  3855     }
  3856 
  3856 
  3857 #if defined(O_NONBLOCK)
  3857 #if defined(O_NONBLOCK)
  3858     openFlags |= O_NONBLOCK;
  3858     openFlags |= O_NONBLOCK;
  3859 #elif defined(O_NDELAY)
  3859 #elif defined(O_NDELAY)
  3861 #endif
  3861 #endif
  3862 
  3862 
  3863 again:
  3863 again:
  3864     fd = open((char *) __stringVal(encodedPathName), openFlags, mode);
  3864     fd = open((char *) __stringVal(encodedPathName), openFlags, mode);
  3865     if (fd < 0) {
  3865     if (fd < 0) {
  3866         if (errno == EINTR) {
  3866 	if (errno == EINTR) {
  3867             __HANDLE_INTERRUPTS__;
  3867 	    __HANDLE_INTERRUPTS__;
  3868             goto again;
  3868 	    goto again;
  3869         } else {
  3869 	} else {
  3870             error = __mkSmallInteger(errno);
  3870 	    error = __mkSmallInteger(errno);
  3871             goto err;
  3871 	    goto err;
  3872         }
  3872 	}
  3873     }
  3873     }
  3874     fileDescriptor = __mkSmallInteger(fd);
  3874     fileDescriptor = __mkSmallInteger(fd);
  3875 err:;
  3875 err:;
  3876 %}.
  3876 %}.
  3877     ^ fileDescriptor notNil ifTrue:[
  3877     ^ fileDescriptor notNil ifTrue:[
  3878         FileDescriptorHandle for:fileDescriptor.
  3878 	FileDescriptorHandle for:fileDescriptor.
  3879     ] ifFalse:[
  3879     ] ifFalse:[
  3880         (self errorHolderForNumber:error) reportError
  3880 	(self errorHolderForNumber:error) reportError
  3881     ].
  3881     ].
  3882 
  3882 
  3883     "
  3883     "
  3884         self open:'/etc/hosts' attributes:#(O_RDONLY) mode:nil
  3884 	self open:'/etc/hosts' attributes:#(O_RDONLY) mode:nil
  3885         self open:'/tmp/xxzz' attributes:#(O_RDWR O_CREAT) mode:8r611
  3885 	self open:'/tmp/xxzz' attributes:#(O_RDWR O_CREAT) mode:8r611
  3886         self open:'/etc/passwd' attributes:#(O_RDWR) mode:nil
  3886 	self open:'/etc/passwd' attributes:#(O_RDWR) mode:nil
  3887         self open:'/no one knows this file' attributes:#(O_RDONLY) mode:nil
  3887 	self open:'/no one knows this file' attributes:#(O_RDONLY) mode:nil
  3888         self open:'foo/bar/baz' attributes:#(O_RDWR O_CREAT) mode:nil
  3888 	self open:'foo/bar/baz' attributes:#(O_RDWR O_CREAT) mode:nil
  3889     "
  3889     "
  3890 !
  3890 !
  3891 
  3891 
  3892 openFileForAppend:pathName
  3892 openFileForAppend:pathName
  3893 
  3893 
  3919      Return true if successful."
  3919      Return true if successful."
  3920 
  3920 
  3921     ^ self executeCommand:(Array with:'/bin/cp' with:'-af' with:sourcePathName with:destination)
  3921     ^ self executeCommand:(Array with:'/bin/cp' with:'-af' with:sourcePathName with:destination)
  3922 
  3922 
  3923     "
  3923     "
  3924         self recursiveCopyDirectory:'packages' to:'foo'.
  3924 	self recursiveCopyDirectory:'packages' to:'foo'.
  3925         self recursiveRemoveDirectory:'foo'.
  3925 	self recursiveRemoveDirectory:'foo'.
  3926     "
  3926     "
  3927 
  3927 
  3928     "Modified: / 5.6.1998 / 18:33:57 / cg"
  3928     "Modified: / 5.6.1998 / 18:33:57 / cg"
  3929 !
  3929 !
  3930 
  3930 
  3953     encodedPathName := self encodePath:fullPathName.
  3953     encodedPathName := self encodePath:fullPathName.
  3954 %{
  3954 %{
  3955     int ret;
  3955     int ret;
  3956 
  3956 
  3957     if (__isStringLike(encodedPathName)) {
  3957     if (__isStringLike(encodedPathName)) {
  3958         __BEGIN_INTERRUPTABLE__
  3958 	__BEGIN_INTERRUPTABLE__
  3959         do {
  3959 	do {
  3960             ret = rmdir((char *) __stringVal(encodedPathName));
  3960 	    ret = rmdir((char *) __stringVal(encodedPathName));
  3961         } while (ret < 0 && errno == EINTR);
  3961 	} while (ret < 0 && errno == EINTR);
  3962         __END_INTERRUPTABLE__
  3962 	__END_INTERRUPTABLE__
  3963         if (ret < 0) {
  3963 	if (ret < 0) {
  3964             @global(LastErrorNumber) = __mkSmallInteger(errno);
  3964 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  3965             RETURN ( false );
  3965 	    RETURN ( false );
  3966         }
  3966 	}
  3967         RETURN (true);
  3967 	RETURN (true);
  3968     }
  3968     }
  3969 %}.
  3969 %}.
  3970     "/
  3970     "/
  3971     "/ either not a string argument,
  3971     "/ either not a string argument,
  3972     "/ or not supported by OS
  3972     "/ or not supported by OS
  3988     encodedPathName := self encodePath:fullPathName.
  3988     encodedPathName := self encodePath:fullPathName.
  3989 %{
  3989 %{
  3990     int ret;
  3990     int ret;
  3991 
  3991 
  3992     if (__isStringLike(encodedPathName)) {
  3992     if (__isStringLike(encodedPathName)) {
  3993         __BEGIN_INTERRUPTABLE__
  3993 	__BEGIN_INTERRUPTABLE__
  3994         do {
  3994 	do {
  3995             ret = unlink((char *) __stringVal(encodedPathName));
  3995 	    ret = unlink((char *) __stringVal(encodedPathName));
  3996         } while (ret < 0 && errno == EINTR);
  3996 	} while (ret < 0 && errno == EINTR);
  3997         __END_INTERRUPTABLE__
  3997 	__END_INTERRUPTABLE__
  3998         if (ret < 0) {
  3998 	if (ret < 0) {
  3999             @global(LastErrorNumber) = __mkSmallInteger(errno);
  3999 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  4000             RETURN ( false );
  4000 	    RETURN ( false );
  4001         }
  4001 	}
  4002         RETURN (true);
  4002 	RETURN (true);
  4003     }
  4003     }
  4004 %}.
  4004 %}.
  4005     ^ self primitiveFailed
  4005     ^ self primitiveFailed
  4006 !
  4006 !
  4007 
  4007 
  4020 %{
  4020 %{
  4021     int ret, eno;
  4021     int ret, eno;
  4022 
  4022 
  4023     if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
  4023     if (__isStringLike(encodedOldPathName) && __isStringLike(encodedNewPathName)) {
  4024 #if defined(HAS_RENAME)
  4024 #if defined(HAS_RENAME)
  4025         __BEGIN_INTERRUPTABLE__
  4025 	__BEGIN_INTERRUPTABLE__
  4026         do {
  4026 	do {
  4027             ret = rename((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  4027 	    ret = rename((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  4028         } while (ret < 0 && errno == EINTR);
  4028 	} while (ret < 0 && errno == EINTR);
  4029         __END_INTERRUPTABLE__
  4029 	__END_INTERRUPTABLE__
  4030 #else
  4030 #else
  4031         ret = link((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  4031 	ret = link((char *) __stringVal(encodedOldPathName), (char *) __stringVal(encodedNewPathName));
  4032         if (ret >= 0) {
  4032 	if (ret >= 0) {
  4033             ret = unlink((char *) __stringVal(encodedOldPathName));
  4033 	    ret = unlink((char *) __stringVal(encodedOldPathName));
  4034             if (ret < 0) {
  4034 	    if (ret < 0) {
  4035                 eno = errno;
  4035 		eno = errno;
  4036                 unlink((char *) __stringVal(encodedNewPathName));
  4036 		unlink((char *) __stringVal(encodedNewPathName));
  4037                 errno = eno;
  4037 		errno = eno;
  4038             }
  4038 	    }
  4039         }
  4039 	}
  4040 #endif
  4040 #endif
  4041         if (ret < 0) {
  4041 	if (ret < 0) {
  4042             @global(LastErrorNumber) = __mkSmallInteger(errno);
  4042 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  4043             RETURN ( false );
  4043 	    RETURN ( false );
  4044         }
  4044 	}
  4045         RETURN (true);
  4045 	RETURN (true);
  4046     }
  4046     }
  4047 %}.
  4047 %}.
  4048     ^ self primitiveFailed
  4048     ^ self primitiveFailed
  4049 
  4049 
  4050     "
  4050     "
  4066 %{
  4066 %{
  4067 //cg must be nested ifdefs - macosx does not like it otherwise
  4067 //cg must be nested ifdefs - macosx does not like it otherwise
  4068 #if defined(LINUX)
  4068 #if defined(LINUX)
  4069 # if __GLIBC_PREREQ(2, 14)
  4069 # if __GLIBC_PREREQ(2, 14)
  4070     if (__isSmallInteger(handle)) {
  4070     if (__isSmallInteger(handle)) {
  4071         if (syncfs(__intVal(handle)) == 0) {
  4071 	if (syncfs(__intVal(handle)) == 0) {
  4072             RETURN(self);
  4072 	    RETURN(self);
  4073         }
  4073 	}
  4074     }
  4074     }
  4075 # endif
  4075 # endif
  4076 #endif
  4076 #endif
  4077 %}.
  4077 %}.
  4078 
  4078 
  4079     "fallback is to do a global sync"
  4079     "fallback is to do a global sync"
  4080     self sync.
  4080     self sync.
  4081 
  4081 
  4082     "
  4082     "
  4083         '/etc/passwd' asFilename readStream syncFileSystem
  4083 	'/etc/passwd' asFilename readStream syncFileSystem
  4084     "
  4084     "
  4085 !
  4085 !
  4086 
  4086 
  4087 truncateFile:aPathName to:newSize
  4087 truncateFile:aPathName to:newSize
  4088     "change a files size return true on success, false on failure.
  4088     "change a files size return true on success, false on failure.
  4098 #if defined(HAS_TRUNCATE) || defined(HAS_FTRUNCATE)
  4098 #if defined(HAS_TRUNCATE) || defined(HAS_FTRUNCATE)
  4099     int ret;
  4099     int ret;
  4100     off_t truncateSize;
  4100     off_t truncateSize;
  4101 
  4101 
  4102     if (!__isStringLike(encodedPathName))
  4102     if (!__isStringLike(encodedPathName))
  4103         goto getOutOfHere;
  4103 	goto getOutOfHere;
  4104 
  4104 
  4105     if (__isSmallInteger(newSize)) {
  4105     if (__isSmallInteger(newSize)) {
  4106         truncateSize = __intVal(newSize);
  4106 	truncateSize = __intVal(newSize);
  4107         if (truncateSize < 0) {
  4107 	if (truncateSize < 0) {
  4108             goto getOutOfHere;
  4108 	    goto getOutOfHere;
  4109         }
  4109 	}
  4110     } else {
  4110     } else {
  4111         truncateSize = __signedLongIntVal(newSize);
  4111 	truncateSize = __signedLongIntVal(newSize);
  4112         if (truncateSize < 0) {
  4112 	if (truncateSize < 0) {
  4113             goto getOutOfHere;
  4113 	    goto getOutOfHere;
  4114         }
  4114 	}
  4115         if (truncateSize == 0) {
  4115 	if (truncateSize == 0) {
  4116             if (sizeof(truncateSize) == 8) {
  4116 	    if (sizeof(truncateSize) == 8) {
  4117                 if (__signedLong64IntVal(newSize, &truncateSize) == 0 || truncateSize < 0) {
  4117 		if (__signedLong64IntVal(newSize, &truncateSize) == 0 || truncateSize < 0) {
  4118                     goto getOutOfHere;
  4118 		    goto getOutOfHere;
  4119                 }
  4119 		}
  4120             } else {
  4120 	    } else {
  4121                 goto getOutOfHere;
  4121 		goto getOutOfHere;
  4122             }
  4122 	    }
  4123         }
  4123 	}
  4124     }
  4124     }
  4125 
  4125 
  4126 #if defined(HAS_TRUNCATE)
  4126 #if defined(HAS_TRUNCATE)
  4127         __BEGIN_INTERRUPTABLE__
  4127 	__BEGIN_INTERRUPTABLE__
  4128         do {
  4128 	do {
  4129             ret = truncate((char *) __stringVal(encodedPathName), truncateSize);
  4129 	    ret = truncate((char *) __stringVal(encodedPathName), truncateSize);
  4130         } while (ret < 0 && errno == EINTR);
  4130 	} while (ret < 0 && errno == EINTR);
  4131         __END_INTERRUPTABLE__
  4131 	__END_INTERRUPTABLE__
  4132 #else
  4132 #else
  4133 # ifdef HAS_FTRUNCATE
  4133 # ifdef HAS_FTRUNCATE
  4134     {
  4134     {
  4135         int fd;
  4135 	int fd;
  4136 
  4136 
  4137         do {
  4137 	do {
  4138             fd = open((char *) __stringVal(encodedPathName), 2);
  4138 	    fd = open((char *) __stringVal(encodedPathName), 2);
  4139         } while (fd < 0 && errno == EINTR);
  4139 	} while (fd < 0 && errno == EINTR);
  4140         if (fd < 0) {
  4140 	if (fd < 0) {
  4141             @global(LastErrorNumber) = __mkSmallInteger(errno);
  4141 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  4142             RETURN ( false );
  4142 	    RETURN ( false );
  4143         }
  4143 	}
  4144 
  4144 
  4145         ret = ftruncate(fd, truncateSize);
  4145 	ret = ftruncate(fd, truncateSize);
  4146         close(fd);
  4146 	close(fd);
  4147     }
  4147     }
  4148 # endif /* HAS_FTRUNCATE */
  4148 # endif /* HAS_FTRUNCATE */
  4149 #endif
  4149 #endif
  4150     if (ret < 0) {
  4150     if (ret < 0) {
  4151         @global(LastErrorNumber) = __mkSmallInteger(errno);
  4151 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  4152         RETURN ( false );
  4152 	RETURN ( false );
  4153     }
  4153     }
  4154     RETURN (true);
  4154     RETURN (true);
  4155 getOutOfHere:;
  4155 getOutOfHere:;
  4156 #endif
  4156 #endif
  4157 %}.
  4157 %}.
  4183 #    define S_ISGID 02000
  4183 #    define S_ISGID 02000
  4184 #    define S_ISVTX 01000
  4184 #    define S_ISVTX 01000
  4185 #   endif
  4185 #   endif
  4186 
  4186 
  4187     if (aSymbol == @symbol(readUser)) {
  4187     if (aSymbol == @symbol(readUser)) {
  4188         RETURN ( __mkSmallInteger(S_IRUSR) );
  4188 	RETURN ( __mkSmallInteger(S_IRUSR) );
  4189     }
  4189     }
  4190     if (aSymbol == @symbol(writeUser)) {
  4190     if (aSymbol == @symbol(writeUser)) {
  4191         RETURN ( __mkSmallInteger(S_IWUSR) );
  4191 	RETURN ( __mkSmallInteger(S_IWUSR) );
  4192     }
  4192     }
  4193     if (aSymbol == @symbol(executeUser)) {
  4193     if (aSymbol == @symbol(executeUser)) {
  4194         RETURN ( __mkSmallInteger(S_IXUSR) );
  4194 	RETURN ( __mkSmallInteger(S_IXUSR) );
  4195     }
  4195     }
  4196     if (aSymbol == @symbol(readGroup)) {
  4196     if (aSymbol == @symbol(readGroup)) {
  4197         RETURN ( __mkSmallInteger(S_IRGRP) );
  4197 	RETURN ( __mkSmallInteger(S_IRGRP) );
  4198     }
  4198     }
  4199     if (aSymbol == @symbol(writeGroup)) {
  4199     if (aSymbol == @symbol(writeGroup)) {
  4200         RETURN ( __mkSmallInteger(S_IWGRP) );
  4200 	RETURN ( __mkSmallInteger(S_IWGRP) );
  4201     }
  4201     }
  4202     if (aSymbol == @symbol(executeGroup)) {
  4202     if (aSymbol == @symbol(executeGroup)) {
  4203         RETURN ( __mkSmallInteger(S_IXGRP) );
  4203 	RETURN ( __mkSmallInteger(S_IXGRP) );
  4204     }
  4204     }
  4205     if (aSymbol == @symbol(readOthers)) {
  4205     if (aSymbol == @symbol(readOthers)) {
  4206         RETURN ( __mkSmallInteger(S_IROTH) );
  4206 	RETURN ( __mkSmallInteger(S_IROTH) );
  4207     }
  4207     }
  4208     if (aSymbol == @symbol(writeOthers)) {
  4208     if (aSymbol == @symbol(writeOthers)) {
  4209         RETURN ( __mkSmallInteger(S_IWOTH) );
  4209 	RETURN ( __mkSmallInteger(S_IWOTH) );
  4210     }
  4210     }
  4211     if (aSymbol == @symbol(executeOthers)) {
  4211     if (aSymbol == @symbol(executeOthers)) {
  4212         RETURN ( __mkSmallInteger(S_IXOTH) );
  4212 	RETURN ( __mkSmallInteger(S_IXOTH) );
  4213     }
  4213     }
  4214     if (aSymbol == @symbol(setUid)) {
  4214     if (aSymbol == @symbol(setUid)) {
  4215         RETURN ( __mkSmallInteger(S_ISUID) );
  4215 	RETURN ( __mkSmallInteger(S_ISUID) );
  4216     }
  4216     }
  4217     if (aSymbol == @symbol(setGid)) {
  4217     if (aSymbol == @symbol(setGid)) {
  4218         RETURN ( __mkSmallInteger(S_ISGID) );
  4218 	RETURN ( __mkSmallInteger(S_ISGID) );
  4219     }
  4219     }
  4220     if (aSymbol == @symbol(removeOnlyByOwner)) {
  4220     if (aSymbol == @symbol(removeOnlyByOwner)) {
  4221         RETURN ( __mkSmallInteger(S_ISVTX) );
  4221 	RETURN ( __mkSmallInteger(S_ISVTX) );
  4222     }
  4222     }
  4223 %}.
  4223 %}.
  4224     ^ self primitiveFailed
  4224     ^ self primitiveFailed
  4225 
  4225 
  4226     "
  4226     "
  4235      Notice that the returned number is OS dependent - use the
  4235      Notice that the returned number is OS dependent - use the
  4236      modeMasks as returned by OperatingSystem>>accessMaskFor:"
  4236      modeMasks as returned by OperatingSystem>>accessMaskFor:"
  4237 
  4237 
  4238     "
  4238     "
  4239      this could have been implemented as:
  4239      this could have been implemented as:
  4240         (self infoOf:aPathName) at:#mode
  4240 	(self infoOf:aPathName) at:#mode
  4241      but for huge directory searches the code below is faster
  4241      but for huge directory searches the code below is faster
  4242     "
  4242     "
  4243 
  4243 
  4244     |encodedPathName|
  4244     |encodedPathName|
  4245 
  4245 
  4248     struct stat buf;
  4248     struct stat buf;
  4249     int ret;
  4249     int ret;
  4250 
  4250 
  4251     if (__isStringLike(encodedPathName)) {
  4251     if (__isStringLike(encodedPathName)) {
  4252 # ifdef TRACE_STAT_CALLS
  4252 # ifdef TRACE_STAT_CALLS
  4253         printf("stat on '%s' for accessMode\n", __stringVal(encodedPathName));
  4253 	printf("stat on '%s' for accessMode\n", __stringVal(encodedPathName));
  4254 # endif
  4254 # endif
  4255         __BEGIN_INTERRUPTABLE__
  4255 	__BEGIN_INTERRUPTABLE__
  4256         do {
  4256 	do {
  4257             ret = stat((char *) __stringVal(encodedPathName), &buf);
  4257 	    ret = stat((char *) __stringVal(encodedPathName), &buf);
  4258         } while ((ret < 0) && (errno == EINTR));
  4258 	} while ((ret < 0) && (errno == EINTR));
  4259         __END_INTERRUPTABLE__
  4259 	__END_INTERRUPTABLE__
  4260 
  4260 
  4261         if (ret < 0) {
  4261 	if (ret < 0) {
  4262             @global(LastErrorNumber) = __mkSmallInteger(errno);
  4262 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  4263             RETURN ( nil );
  4263 	    RETURN ( nil );
  4264         }
  4264 	}
  4265         RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
  4265 	RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
  4266     }
  4266     }
  4267 %}.
  4267 %}.
  4268    ^ self primitiveFailed
  4268    ^ self primitiveFailed
  4269 
  4269 
  4270    "
  4270    "
  4282     struct stat buf;
  4282     struct stat buf;
  4283     int ret;
  4283     int ret;
  4284 
  4284 
  4285     if (__isSmallInteger(aFileDescriptor)) {
  4285     if (__isSmallInteger(aFileDescriptor)) {
  4286 # ifdef TRACE_STAT_CALLS
  4286 # ifdef TRACE_STAT_CALLS
  4287         printf("fstat on '%d' for accessMode\n", __smallIntegerVal(aFileDescriptor));
  4287 	printf("fstat on '%d' for accessMode\n", __smallIntegerVal(aFileDescriptor));
  4288 # endif
  4288 # endif
  4289         __BEGIN_INTERRUPTABLE__
  4289 	__BEGIN_INTERRUPTABLE__
  4290         do {
  4290 	do {
  4291             ret = fstat(__smallIntegerVal(aFileDescriptor), &buf);
  4291 	    ret = fstat(__smallIntegerVal(aFileDescriptor), &buf);
  4292         } while ((ret < 0) && (errno == EINTR));
  4292 	} while ((ret < 0) && (errno == EINTR));
  4293         __END_INTERRUPTABLE__
  4293 	__END_INTERRUPTABLE__
  4294 
  4294 
  4295         if (ret < 0) {
  4295 	if (ret < 0) {
  4296             @global(LastErrorNumber) = __mkSmallInteger(errno);
  4296 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  4297             RETURN ( nil );
  4297 	    RETURN ( nil );
  4298         }
  4298 	}
  4299         RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
  4299 	RETURN ( __mkSmallInteger(buf.st_mode & 0777) );
  4300     }
  4300     }
  4301 %}.
  4301 %}.
  4302    ^ self primitiveFailed
  4302    ^ self primitiveFailed
  4303 
  4303 
  4304    "
  4304    "
  4305     '/' asFilename readingFileDo:[:s|
  4305     '/' asFilename readingFileDo:[:s|
  4306         (OperatingSystem accessModeOfFd:s fileDescriptor) printStringRadix:8
  4306 	(OperatingSystem accessModeOfFd:s fileDescriptor) printStringRadix:8
  4307     ].
  4307     ].
  4308    "
  4308    "
  4309 !
  4309 !
  4310 
  4310 
  4311 changeAccessModeOf:aPathName to:modeBits
  4311 changeAccessModeOf:aPathName to:modeBits
  4319     encodedPathName := self encodePath:aPathName.
  4319     encodedPathName := self encodePath:aPathName.
  4320 %{
  4320 %{
  4321     int ret;
  4321     int ret;
  4322 
  4322 
  4323     if (__isStringLike(encodedPathName) && __isSmallInteger(modeBits)) {
  4323     if (__isStringLike(encodedPathName) && __isSmallInteger(modeBits)) {
  4324         __BEGIN_INTERRUPTABLE__
  4324 	__BEGIN_INTERRUPTABLE__
  4325         do {
  4325 	do {
  4326             ret = chmod((char *)__stringVal(encodedPathName), __intVal(modeBits));
  4326 	    ret = chmod((char *)__stringVal(encodedPathName), __intVal(modeBits));
  4327         } while (ret < 0 && errno == EINTR);
  4327 	} while (ret < 0 && errno == EINTR);
  4328         __END_INTERRUPTABLE__
  4328 	__END_INTERRUPTABLE__
  4329         if (ret < 0) {
  4329 	if (ret < 0) {
  4330             @global(LastErrorNumber) = __mkSmallInteger(errno);
  4330 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  4331             RETURN ( false );
  4331 	    RETURN ( false );
  4332         }
  4332 	}
  4333         RETURN ( true );
  4333 	RETURN ( true );
  4334     }
  4334     }
  4335 %}.
  4335 %}.
  4336     ^ self primitiveFailed
  4336     ^ self primitiveFailed
  4337 !
  4337 !
  4338 
  4338 
  4345 
  4345 
  4346 %{
  4346 %{
  4347     int ret;
  4347     int ret;
  4348 
  4348 
  4349     if (__isSmallInteger(aFileDescriptor) && __isSmallInteger(modeBits)) {
  4349     if (__isSmallInteger(aFileDescriptor) && __isSmallInteger(modeBits)) {
  4350         __BEGIN_INTERRUPTABLE__
  4350 	__BEGIN_INTERRUPTABLE__
  4351         do {
  4351 	do {
  4352             ret = fchmod(__smallIntegerVal(aFileDescriptor), __intVal(modeBits));
  4352 	    ret = fchmod(__smallIntegerVal(aFileDescriptor), __intVal(modeBits));
  4353         } while (ret < 0 && errno == EINTR);
  4353 	} while (ret < 0 && errno == EINTR);
  4354         __END_INTERRUPTABLE__
  4354 	__END_INTERRUPTABLE__
  4355         if (ret < 0) {
  4355 	if (ret < 0) {
  4356             @global(LastErrorNumber) = __mkSmallInteger(errno);
  4356 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  4357             RETURN ( false );
  4357 	    RETURN ( false );
  4358         }
  4358 	}
  4359         RETURN ( true );
  4359 	RETURN ( true );
  4360     }
  4360     }
  4361 %}.
  4361 %}.
  4362     ^ self primitiveFailed
  4362     ^ self primitiveFailed
  4363 ! !
  4363 ! !
  4364 
  4364 
  4383     This can (again: on some systems) be avoided by passing a false blockIfLocked
  4383     This can (again: on some systems) be avoided by passing a false blockIfLocked
  4384     argument."
  4384     argument."
  4385 
  4385 
  4386 %{
  4386 %{
  4387     if (__isSmallInteger(aFileDescriptor)) {
  4387     if (__isSmallInteger(aFileDescriptor)) {
  4388         int fd = __intVal(aFileDescriptor);
  4388 	int fd = __intVal(aFileDescriptor);
  4389         int lockArg;
  4389 	int lockArg;
  4390 
  4390 
  4391         /*
  4391 	/*
  4392          * claus: sigh - each one has a different interface ...
  4392 	 * claus: sigh - each one has a different interface ...
  4393          */
  4393 	 */
  4394 #if defined(F_SETLK)
  4394 #if defined(F_SETLK)
  4395         {
  4395 	{
  4396             /*
  4396 	    /*
  4397              * new fcntl(SETLK) interface;
  4397 	     * new fcntl(SETLK) interface;
  4398              * available on SYSV4 and Linux
  4398 	     * available on SYSV4 and Linux
  4399              */
  4399 	     */
  4400             struct flock flock;
  4400 	    struct flock flock;
  4401 
  4401 
  4402             if (isSharedReadLock == true) {
  4402 	    if (isSharedReadLock == true) {
  4403                 flock.l_type = F_RDLCK;
  4403 		flock.l_type = F_RDLCK;
  4404             } else {
  4404 	    } else {
  4405                 flock.l_type = F_WRLCK;
  4405 		flock.l_type = F_WRLCK;
  4406             }
  4406 	    }
  4407             flock.l_whence = 0;
  4407 	    flock.l_whence = 0;
  4408             flock.l_start = 0;
  4408 	    flock.l_start = 0;
  4409             flock.l_len = 0;
  4409 	    flock.l_len = 0;
  4410             lockArg = F_SETLK;
  4410 	    lockArg = F_SETLK;
  4411 # if defined(F_SETLKW)
  4411 # if defined(F_SETLKW)
  4412             if (blockIfLocked == true) {
  4412 	    if (blockIfLocked == true) {
  4413                 lockArg = F_SETLKW;
  4413 		lockArg = F_SETLKW;
  4414             }
  4414 	    }
  4415 # endif
  4415 # endif
  4416             if (fcntl(fd, lockArg, &flock) != -1) {
  4416 	    if (fcntl(fd, lockArg, &flock) != -1) {
  4417                 RETURN (true);
  4417 		RETURN (true);
  4418             }
  4418 	    }
  4419         }
  4419 	}
  4420 
  4420 
  4421 #else /* no F_SETLK available */
  4421 #else /* no F_SETLK available */
  4422 
  4422 
  4423 # if defined(LOCK_EX) && defined(LOCK_UN)
  4423 # if defined(LOCK_EX) && defined(LOCK_UN)
  4424         /*
  4424 	/*
  4425          * BSD 4.3 advisory locks
  4425 	 * BSD 4.3 advisory locks
  4426          */
  4426 	 */
  4427         lockArg = LOCK_EX;
  4427 	lockArg = LOCK_EX;
  4428 #  if defined(LOCK_SH)
  4428 #  if defined(LOCK_SH)
  4429         if (isSharedReadLock == true) {
  4429 	if (isSharedReadLock == true) {
  4430             lockArg = LOCK_SH
  4430 	    lockArg = LOCK_SH
  4431         }
  4431 	}
  4432 #  endif
  4432 #  endif
  4433 #  if defined(LOCK_NB)
  4433 #  if defined(LOCK_NB)
  4434         if (blockIfLocked == false) {
  4434 	if (blockIfLocked == false) {
  4435             lockArg |= LOCK_NB;
  4435 	    lockArg |= LOCK_NB;
  4436         }
  4436 	}
  4437 #  endif
  4437 #  endif
  4438         if (flock(fd, lockArg) != -1) {
  4438 	if (flock(fd, lockArg) != -1) {
  4439             RETURN (true);
  4439 	    RETURN (true);
  4440         }
  4440 	}
  4441 
  4441 
  4442 # else /* no flock available */
  4442 # else /* no flock available */
  4443 
  4443 
  4444 #  if defined(F_LOCK) && defined(F_UNLOCK)
  4444 #  if defined(F_LOCK) && defined(F_UNLOCK)
  4445         /*
  4445 	/*
  4446          * SYSV3 advisory locks
  4446 	 * SYSV3 advisory locks
  4447          */
  4447 	 */
  4448         if (lockf(fd, F_LOCK, 0) != -1) {
  4448 	if (lockf(fd, F_LOCK, 0) != -1) {
  4449             RETURN (true);
  4449 	    RETURN (true);
  4450         }
  4450 	}
  4451 #  endif
  4451 #  endif
  4452 # endif
  4452 # endif
  4453 #endif
  4453 #endif
  4454     }
  4454     }
  4455 %}.
  4455 %}.
  4537      Notice, that not all OS's support file locks;
  4537      Notice, that not all OS's support file locks;
  4538      on some, this may simply be a no-op."
  4538      on some, this may simply be a no-op."
  4539 
  4539 
  4540 %{
  4540 %{
  4541     if (__isSmallInteger(aFileDescriptor)) {
  4541     if (__isSmallInteger(aFileDescriptor)) {
  4542         int fd = __intVal(aFileDescriptor);
  4542 	int fd = __intVal(aFileDescriptor);
  4543 
  4543 
  4544         /*
  4544 	/*
  4545          * claus: sigh - each one has a different interface ...
  4545 	 * claus: sigh - each one has a different interface ...
  4546          */
  4546 	 */
  4547 #if defined(F_SETLK)
  4547 #if defined(F_SETLK)
  4548         {
  4548 	{
  4549             /*
  4549 	    /*
  4550              * new fcntl(SETLK) interface;
  4550 	     * new fcntl(SETLK) interface;
  4551              * available on SYSV4 and Linux
  4551 	     * available on SYSV4 and Linux
  4552              */
  4552 	     */
  4553             struct flock flock;
  4553 	    struct flock flock;
  4554 
  4554 
  4555             flock.l_type = F_UNLCK;
  4555 	    flock.l_type = F_UNLCK;
  4556             flock.l_whence = 0;
  4556 	    flock.l_whence = 0;
  4557             flock.l_start = 0;
  4557 	    flock.l_start = 0;
  4558             flock.l_len = 0;
  4558 	    flock.l_len = 0;
  4559             if (fcntl(fd, F_SETLK, &flock) != -1) {
  4559 	    if (fcntl(fd, F_SETLK, &flock) != -1) {
  4560                 RETURN (true);
  4560 		RETURN (true);
  4561             }
  4561 	    }
  4562         }
  4562 	}
  4563 
  4563 
  4564 #else /* no F_SETLK available */
  4564 #else /* no F_SETLK available */
  4565 
  4565 
  4566 # if defined(LOCK_EX) && defined(LOCK_UN)
  4566 # if defined(LOCK_EX) && defined(LOCK_UN)
  4567         /*
  4567 	/*
  4568          * BSD 4.3 advisory locks
  4568 	 * BSD 4.3 advisory locks
  4569          */
  4569 	 */
  4570         if (flock(fd, LOCK_UN) != -1) {
  4570 	if (flock(fd, LOCK_UN) != -1) {
  4571             RETURN (true);
  4571 	    RETURN (true);
  4572         }
  4572 	}
  4573 
  4573 
  4574 # else /* no flock available */
  4574 # else /* no flock available */
  4575 
  4575 
  4576 #  if defined(F_LOCK) && defined(F_UNLOCK)
  4576 #  if defined(F_LOCK) && defined(F_UNLOCK)
  4577         /*
  4577 	/*
  4578          * SYSV3 advisory locks
  4578 	 * SYSV3 advisory locks
  4579          */
  4579 	 */
  4580         if (lockf(fd, F_UNLOCK, 0) != -1) {
  4580 	if (lockf(fd, F_UNLOCK, 0) != -1) {
  4581             RETURN (true);
  4581 	    RETURN (true);
  4582         }
  4582 	}
  4583 #  endif
  4583 #  endif
  4584 # endif
  4584 # endif
  4585 #endif
  4585 #endif
  4586     }
  4586     }
  4587 %}.
  4587 %}.
  4607      if realPath and popen failed."
  4607      if realPath and popen failed."
  4608 
  4608 
  4609     |names n "{ Class: SmallInteger }" |
  4609     |names n "{ Class: SmallInteger }" |
  4610 
  4610 
  4611     names := pathName
  4611     names := pathName
  4612                 asCollectionOfSubstringsSeparatedBy:self fileSeparator.
  4612 		asCollectionOfSubstringsSeparatedBy:self fileSeparator.
  4613     names := names asOrderedCollection.
  4613     names := names asOrderedCollection.
  4614     "
  4614     "
  4615      cut off initial double-slashes
  4615      cut off initial double-slashes
  4616     "
  4616     "
  4617     [names startsWith:#('' '')] whileTrue:[
  4617     [names startsWith:#('' '')] whileTrue:[
  4618         names removeFirst.
  4618 	names removeFirst.
  4619     ].
  4619     ].
  4620     "
  4620     "
  4621      cut off double-slashes at end
  4621      cut off double-slashes at end
  4622     "
  4622     "
  4623     [names endsWith:#('')] whileTrue:[
  4623     [names endsWith:#('')] whileTrue:[
  4624         names removeLast.
  4624 	names removeLast.
  4625     ].
  4625     ].
  4626     "
  4626     "
  4627      cut off current-dir at beginning
  4627      cut off current-dir at beginning
  4628     "
  4628     "
  4629     n := names size.
  4629     n := names size.
  4630     [(n >= 2) and:[names startsWith:#('.')]] whileTrue:[
  4630     [(n >= 2) and:[names startsWith:#('.')]] whileTrue:[
  4631         names removeFirst.
  4631 	names removeFirst.
  4632         n := n - 1.
  4632 	n := n - 1.
  4633     ].
  4633     ].
  4634 
  4634 
  4635     "
  4635     "
  4636      cut off parent-dirs at end
  4636      cut off parent-dirs at end
  4637     "
  4637     "
  4638     [(n > 2)
  4638     [(n > 2)
  4639      and:[(names endsWith:#('..'))
  4639      and:[(names endsWith:#('..'))
  4640      and:[((names at:(n - 1)) startsWith:'.') not ]]] whileTrue:[
  4640      and:[((names at:(n - 1)) startsWith:'.') not ]]] whileTrue:[
  4641         names removeLast; removeLast.
  4641 	names removeLast; removeLast.
  4642         n := n - 2.
  4642 	n := n - 2.
  4643     ].
  4643     ].
  4644 
  4644 
  4645     ^ names asStringWith:self fileSeparator
  4645     ^ names asStringWith:self fileSeparator
  4646                     from:1
  4646 		    from:1
  4647                     to:n
  4647 		    to:n
  4648                     compressTabs:false final:nil
  4648 		    compressTabs:false final:nil
  4649 
  4649 
  4650     "
  4650     "
  4651      OperatingSystem compressPath:'./..'
  4651      OperatingSystem compressPath:'./..'
  4652      OperatingSystem compressPath:'/foo/bar/baz/..'
  4652      OperatingSystem compressPath:'/foo/bar/baz/..'
  4653      OperatingSystem compressPath:'foo/bar/baz/..'
  4653      OperatingSystem compressPath:'foo/bar/baz/..'
  4679     CurrentDirectory := path.
  4679     CurrentDirectory := path.
  4680 
  4680 
  4681     ^ path.
  4681     ^ path.
  4682 
  4682 
  4683     "
  4683     "
  4684         self getCurrentDirectory
  4684 	self getCurrentDirectory
  4685     "
  4685     "
  4686 !
  4686 !
  4687 
  4687 
  4688 getDiskInfoOf:aDirectoryPath
  4688 getDiskInfoOf:aDirectoryPath
  4689     "return some disk info.
  4689     "return some disk info.
  4690      The amountof information returned depends upon the OS, and is
  4690      The amountof information returned depends upon the OS, and is
  4691      not guaranteed to be consistent across architectures.
  4691      not guaranteed to be consistent across architectures.
  4692      On unix, the information returned is (at least):
  4692      On unix, the information returned is (at least):
  4693         freeBytes
  4693 	freeBytes
  4694         totalBytes
  4694 	totalBytes
  4695     "
  4695     "
  4696 
  4696 
  4697     |outputText keys values n info
  4697     |outputText keys values n info
  4698      fileSystemIdx sizeIdx usedIdx availIdx capacityIdx mountIdx|
  4698      fileSystemIdx sizeIdx usedIdx availIdx capacityIdx mountIdx|
  4699 
  4699 
  4720 
  4720 
  4721     info := IdentityDictionary new.
  4721     info := IdentityDictionary new.
  4722 
  4722 
  4723     n := Integer readFrom:(values at:capacityIdx) onError:nil.
  4723     n := Integer readFrom:(values at:capacityIdx) onError:nil.
  4724     n notNil ifTrue:[
  4724     n notNil ifTrue:[
  4725         info at:#percentUsed put:n
  4725 	info at:#percentUsed put:n
  4726     ].
  4726     ].
  4727 
  4727 
  4728     n := Integer readFrom:(values at:availIdx) onError:nil.
  4728     n := Integer readFrom:(values at:availIdx) onError:nil.
  4729     n notNil ifTrue:[
  4729     n notNil ifTrue:[
  4730         info at:#freeBytes put:(n * 1024)
  4730 	info at:#freeBytes put:(n * 1024)
  4731     ].
  4731     ].
  4732 
  4732 
  4733     n := Integer readFrom:(values at:usedIdx) onError:nil.
  4733     n := Integer readFrom:(values at:usedIdx) onError:nil.
  4734     n notNil ifTrue:[
  4734     n notNil ifTrue:[
  4735         info at:#usedBytes put:(n * 1024)
  4735 	info at:#usedBytes put:(n * 1024)
  4736     ].
  4736     ].
  4737 
  4737 
  4738     n := Integer readFrom:(values at:sizeIdx) onError:nil.
  4738     n := Integer readFrom:(values at:sizeIdx) onError:nil.
  4739     n notNil ifTrue:[
  4739     n notNil ifTrue:[
  4740         info at:#totalBytes put:(n * 1024)
  4740 	info at:#totalBytes put:(n * 1024)
  4741     ].
  4741     ].
  4742 
  4742 
  4743     info at:#mountPoint put:(values at:mountIdx).
  4743     info at:#mountPoint put:(values at:mountIdx).
  4744     info at:#fileSystem put:(values at:fileSystemIdx).
  4744     info at:#fileSystem put:(values at:fileSystemIdx).
  4745 
  4745 
  4763     "/
  4763     "/
  4764     "/ default: return array filled with
  4764     "/ default: return array filled with
  4765     "/ root, home and current directories.
  4765     "/ root, home and current directories.
  4766     "/
  4766     "/
  4767     ^ Array
  4767     ^ Array
  4768         with:'/'
  4768 	with:'/'
  4769         with:(self getHomeDirectory)
  4769 	with:(self getHomeDirectory)
  4770         with:(Filename currentDirectory pathName)
  4770 	with:(Filename currentDirectory pathName)
  4771 
  4771 
  4772     "Modified: / 5.6.1998 / 18:35:35 / cg"
  4772     "Modified: / 5.6.1998 / 18:35:35 / cg"
  4773 !
  4773 !
  4774 
  4774 
  4775 getMountedVolumes
  4775 getMountedVolumes
  4776     "return info about mounted volumes.
  4776     "return info about mounted volumes.
  4777      The amount of information returned depends upon the OS, and is
  4777      The amount of information returned depends upon the OS, and is
  4778      not guaranteed to be consistent across architectures.
  4778      not guaranteed to be consistent across architectures.
  4779      On unix, the information returned is (at least):
  4779      On unix, the information returned is (at least):
  4780         mountPoint - mount point
  4780 	mountPoint - mount point
  4781         fileSystem - device or NFS-remotePath
  4781 	fileSystem - device or NFS-remotePath
  4782     "
  4782     "
  4783 
  4783 
  4784     |outputText keys values info infoEntry|
  4784     |outputText keys values info infoEntry|
  4785 
  4785 
  4786     outputText := PipeStream outputFromCommand:('df -k').
  4786     outputText := PipeStream outputFromCommand:('df -k').
  4794     "/ on some rude Unix versions ...
  4794     "/ on some rude Unix versions ...
  4795 
  4795 
  4796     info := OrderedCollection new.
  4796     info := OrderedCollection new.
  4797 
  4797 
  4798     outputText from:2 do:[:line |
  4798     outputText from:2 do:[:line |
  4799         values := line asCollectionOfWords.
  4799 	values := line asCollectionOfWords.
  4800 
  4800 
  4801         values size >= 2 ifTrue:[
  4801 	values size >= 2 ifTrue:[
  4802 
  4802 
  4803             infoEntry := IdentityDictionary new.
  4803 	    infoEntry := IdentityDictionary new.
  4804             infoEntry at:#mountPoint put:(values last).
  4804 	    infoEntry at:#mountPoint put:(values last).
  4805             infoEntry at:#fileSystem put:(values first).
  4805 	    infoEntry at:#fileSystem put:(values first).
  4806             info add:infoEntry.
  4806 	    info add:infoEntry.
  4807         ]
  4807 	]
  4808     ].
  4808     ].
  4809     ^ info
  4809     ^ info
  4810 
  4810 
  4811     "
  4811     "
  4812      OperatingSystem getMountedVolumes
  4812      OperatingSystem getMountedVolumes
  4823 
  4823 
  4824 infoOf:aPathName
  4824 infoOf:aPathName
  4825     "return some object filled with info for the file 'aPathName';
  4825     "return some object filled with info for the file 'aPathName';
  4826      the info (for which corresponding access methods are understood by
  4826      the info (for which corresponding access methods are understood by
  4827      the returned object) is:
  4827      the returned object) is:
  4828          type            - a symbol giving the files type
  4828 	 type            - a symbol giving the files type
  4829          mode            - numeric access mode
  4829 	 mode            - numeric access mode
  4830          uid             - owners user id
  4830 	 uid             - owners user id
  4831          gid             - owners group id
  4831 	 gid             - owners group id
  4832          size            - files size
  4832 	 size            - files size
  4833          id              - files number (i.e. inode number)
  4833 	 id              - files number (i.e. inode number)
  4834          accessed        - last access time (as Timestamp)
  4834 	 accessed        - last access time (as Timestamp)
  4835          modified        - last modification time (as Timestamp)
  4835 	 modified        - last modification time (as Timestamp)
  4836          statusChanged   - last status change time (as Timestamp)
  4836 	 statusChanged   - last status change time (as Timestamp)
  4837          alternativeName     - (windows only:) the MSDOS name of the file
  4837 	 alternativeName     - (windows only:) the MSDOS name of the file
  4838          recordFormatNumeric - (VMS only:) numeric value of the recordFormat
  4838 	 recordFormatNumeric - (VMS only:) numeric value of the recordFormat
  4839          recordFormat        - (VMS only:) symbolic value of the recordFormat
  4839 	 recordFormat        - (VMS only:) symbolic value of the recordFormat
  4840          recordAttributes    - (VMS only:) recordAttributes
  4840 	 recordAttributes    - (VMS only:) recordAttributes
  4841          fixedHeaderSize     - (VMS only:) fixed header size in a variable record format
  4841 	 fixedHeaderSize     - (VMS only:) fixed header size in a variable record format
  4842          recordSize          - (VMS only:) record size.
  4842 	 recordSize          - (VMS only:) record size.
  4843 
  4843 
  4844      Some of the fields may be returned as nil on systems which do not provide
  4844      Some of the fields may be returned as nil on systems which do not provide
  4845      all of the information.
  4845      all of the information.
  4846      Return nil if such a file does not exist.
  4846      Return nil if such a file does not exist.
  4847      For symbolic links (if supported by the OS),
  4847      For symbolic links (if supported by the OS),
  4855 %{
  4855 %{
  4856     struct stat buf;
  4856     struct stat buf;
  4857     int ret;
  4857     int ret;
  4858 
  4858 
  4859     if (!__isStringLike(encodedPathName)) {
  4859     if (!__isStringLike(encodedPathName)) {
  4860         error = @symbol(badArgument);
  4860 	error = @symbol(badArgument);
  4861         goto out;
  4861 	goto out;
  4862     }
  4862     }
  4863 
  4863 
  4864 # ifdef TRACE_STAT_CALLS
  4864 # ifdef TRACE_STAT_CALLS
  4865     printf("stat on '%s' for info\n", __stringVal(aPathName));
  4865     printf("stat on '%s' for info\n", __stringVal(aPathName));
  4866 # endif
  4866 # endif
  4867     __BEGIN_INTERRUPTABLE__
  4867     __BEGIN_INTERRUPTABLE__
  4868     do {
  4868     do {
  4869         ret = stat((char *) __stringVal(encodedPathName), &buf);
  4869 	ret = stat((char *) __stringVal(encodedPathName), &buf);
  4870     } while ((ret < 0) && (errno == EINTR));
  4870     } while ((ret < 0) && (errno == EINTR));
  4871     __END_INTERRUPTABLE__
  4871     __END_INTERRUPTABLE__
  4872 
  4872 
  4873     if (ret < 0) {
  4873     if (ret < 0) {
  4874         error = __mkSmallInteger(errno);
  4874 	error = __mkSmallInteger(errno);
  4875         @global(LastErrorNumber) = error;
  4875 	@global(LastErrorNumber) = error;
  4876         goto out;
  4876 	goto out;
  4877     }
  4877     }
  4878     switch (buf.st_mode & S_IFMT) {
  4878     switch (buf.st_mode & S_IFMT) {
  4879         case S_IFDIR:
  4879 	case S_IFDIR:
  4880             type = @symbol(directory);
  4880 	    type = @symbol(directory);
  4881             break;
  4881 	    break;
  4882 
  4882 
  4883         case S_IFREG:
  4883 	case S_IFREG:
  4884             type = @symbol(regular);
  4884 	    type = @symbol(regular);
  4885             break;
  4885 	    break;
  4886 # ifdef S_IFCHR
  4886 # ifdef S_IFCHR
  4887         case S_IFCHR:
  4887 	case S_IFCHR:
  4888             type = @symbol(characterSpecial);
  4888 	    type = @symbol(characterSpecial);
  4889             break;
  4889 	    break;
  4890 # endif
  4890 # endif
  4891 # ifdef S_IFBLK
  4891 # ifdef S_IFBLK
  4892         case S_IFBLK:
  4892 	case S_IFBLK:
  4893             type = @symbol(blockSpecial);
  4893 	    type = @symbol(blockSpecial);
  4894             break;
  4894 	    break;
  4895 # endif
  4895 # endif
  4896 # ifdef S_IFMPC
  4896 # ifdef S_IFMPC
  4897         case S_IFMPC:
  4897 	case S_IFMPC:
  4898             type = @symbol(multiplexedCharacterSpecial);
  4898 	    type = @symbol(multiplexedCharacterSpecial);
  4899             break;
  4899 	    break;
  4900 # endif
  4900 # endif
  4901 # ifdef S_IFMPB
  4901 # ifdef S_IFMPB
  4902         case S_IFMPB:
  4902 	case S_IFMPB:
  4903             type = @symbol(multiplexedBlockSpecial);
  4903 	    type = @symbol(multiplexedBlockSpecial);
  4904             break;
  4904 	    break;
  4905 # endif
  4905 # endif
  4906 # ifdef S_IFLNK
  4906 # ifdef S_IFLNK
  4907         case S_IFLNK:
  4907 	case S_IFLNK:
  4908             type = @symbol(symbolicLink);
  4908 	    type = @symbol(symbolicLink);
  4909             break;
  4909 	    break;
  4910 # endif
  4910 # endif
  4911 # ifdef S_IFSOCK
  4911 # ifdef S_IFSOCK
  4912         case S_IFSOCK:
  4912 	case S_IFSOCK:
  4913             type = @symbol(socket);
  4913 	    type = @symbol(socket);
  4914             break;
  4914 	    break;
  4915 # endif
  4915 # endif
  4916 # ifdef S_IFIFO
  4916 # ifdef S_IFIFO
  4917         case S_IFIFO:
  4917 	case S_IFIFO:
  4918             type = @symbol(fifo);
  4918 	    type = @symbol(fifo);
  4919             break;
  4919 	    break;
  4920 # endif
  4920 # endif
  4921         default:
  4921 	default:
  4922             type = @symbol(unknown);
  4922 	    type = @symbol(unknown);
  4923             break;
  4923 	    break;
  4924     }
  4924     }
  4925 
  4925 
  4926     if (sizeof(buf.st_ino) == 8) {
  4926     if (sizeof(buf.st_ino) == 8) {
  4927         id = __MKUINT64(&buf.st_ino);
  4927 	id = __MKUINT64(&buf.st_ino);
  4928     } else {
  4928     } else {
  4929         id = __MKUINT(buf.st_ino);
  4929 	id = __MKUINT(buf.st_ino);
  4930     }
  4930     }
  4931     mode = __mkSmallInteger(buf.st_mode & 0777);
  4931     mode = __mkSmallInteger(buf.st_mode & 0777);
  4932     uid = __mkSmallInteger(buf.st_uid);
  4932     uid = __mkSmallInteger(buf.st_uid);
  4933     gid = __mkSmallInteger(buf.st_gid);
  4933     gid = __mkSmallInteger(buf.st_gid);
  4934     nLink = __mkSmallInteger(buf.st_nlink);
  4934     nLink = __mkSmallInteger(buf.st_nlink);
  4935     if (sizeof(buf.st_size) == 8) {
  4935     if (sizeof(buf.st_size) == 8) {
  4936         size = __MKINT64(&buf.st_size);
  4936 	size = __MKINT64(&buf.st_size);
  4937     } else {
  4937     } else {
  4938         size = __MKINT(buf.st_size);
  4938 	size = __MKINT(buf.st_size);
  4939     }
  4939     }
  4940     aOStime = __MKUINT(buf.st_atime);
  4940     aOStime = __MKUINT(buf.st_atime);
  4941     mOStime = __MKUINT(buf.st_mtime);
  4941     mOStime = __MKUINT(buf.st_mtime);
  4942     cOStime = __MKUINT(buf.st_ctime);
  4942     cOStime = __MKUINT(buf.st_ctime);
  4943 
  4943 
  4944     out:;
  4944     out:;
  4945 %}.
  4945 %}.
  4946      mode notNil ifTrue:[
  4946      mode notNil ifTrue:[
  4947         "/ now done lazy in FileStatusInfo
  4947 	"/ now done lazy in FileStatusInfo
  4948         "/ atime := Timestamp fromOSTime:(aOStime * 1000).
  4948 	"/ atime := Timestamp fromOSTime:(aOStime * 1000).
  4949         "/ mtime := Timestamp fromOSTime:(mOStime * 1000).
  4949 	"/ mtime := Timestamp fromOSTime:(mOStime * 1000).
  4950         "/ ctime := Timestamp fromOSTime:(cOStime * 1000).
  4950 	"/ ctime := Timestamp fromOSTime:(cOStime * 1000).
  4951 
  4951 
  4952         ^ FileStatusInfo
  4952 	^ FileStatusInfo
  4953                     type:type
  4953 		    type:type
  4954                     mode:mode
  4954 		    mode:mode
  4955                     uid:uid
  4955 		    uid:uid
  4956                     gid:gid
  4956 		    gid:gid
  4957                     size:size
  4957 		    size:size
  4958                     id:id
  4958 		    id:id
  4959                     accessed:aOStime
  4959 		    accessed:aOStime
  4960                     modified:mOStime
  4960 		    modified:mOStime
  4961                     statusChanged:cOStime
  4961 		    statusChanged:cOStime
  4962                     sourcePath:nil targetPath:nil
  4962 		    sourcePath:nil targetPath:nil
  4963                     numLinks:nLink.
  4963 		    numLinks:nLink.
  4964     ].
  4964     ].
  4965     error notNil ifTrue:[
  4965     error notNil ifTrue:[
  4966         ^ nil.
  4966 	^ nil.
  4967     ].
  4967     ].
  4968 
  4968 
  4969     ^ self primitiveFailed
  4969     ^ self primitiveFailed
  4970 
  4970 
  4971    "
  4971    "
  4987 
  4987 
  4988 %{
  4988 %{
  4989     int ret;
  4989     int ret;
  4990 
  4990 
  4991     if (__isStringLike(encodedPathName)) {
  4991     if (__isStringLike(encodedPathName)) {
  4992         struct stat buf;
  4992 	struct stat buf;
  4993 
  4993 
  4994 # ifdef TRACE_STAT_CALLS
  4994 # ifdef TRACE_STAT_CALLS
  4995         printf("stat on '%s' for isDirectory\n", __stringVal(encodedPathName));
  4995 	printf("stat on '%s' for isDirectory\n", __stringVal(encodedPathName));
  4996 # endif
  4996 # endif
  4997         __BEGIN_INTERRUPTABLE__
  4997 	__BEGIN_INTERRUPTABLE__
  4998         do {
  4998 	do {
  4999             ret = stat((char *) __stringVal(encodedPathName), &buf);
  4999 	    ret = stat((char *) __stringVal(encodedPathName), &buf);
  5000         } while ((ret < 0) && (errno == EINTR));
  5000 	} while ((ret < 0) && (errno == EINTR));
  5001         __END_INTERRUPTABLE__
  5001 	__END_INTERRUPTABLE__
  5002         if (ret < 0) {
  5002 	if (ret < 0) {
  5003             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5003 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5004             RETURN ( false );
  5004 	    RETURN ( false );
  5005         }
  5005 	}
  5006         RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
  5006 	RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
  5007     }
  5007     }
  5008 %}.
  5008 %}.
  5009     ^ self primitiveFailed
  5009     ^ self primitiveFailed
  5010 
  5010 
  5011     "an alternative implementation would be:
  5011     "an alternative implementation would be:
  5012         ^ (self infoOf:aPathName) type == #directory
  5012 	^ (self infoOf:aPathName) type == #directory
  5013     "
  5013     "
  5014 !
  5014 !
  5015 
  5015 
  5016 isExecutable:aPathName
  5016 isExecutable:aPathName
  5017     "return true, if the given file is executable.
  5017     "return true, if the given file is executable.
  5024 %{
  5024 %{
  5025     int ret;
  5025     int ret;
  5026 
  5026 
  5027     if (__isStringLike(encodedPathName)) {
  5027     if (__isStringLike(encodedPathName)) {
  5028 # ifdef TRACE_ACCESS_CALLS
  5028 # ifdef TRACE_ACCESS_CALLS
  5029         printf("access on '%s' for executable\n", __stringVal(encodedPathName));
  5029 	printf("access on '%s' for executable\n", __stringVal(encodedPathName));
  5030 # endif
  5030 # endif
  5031         __BEGIN_INTERRUPTABLE__
  5031 	__BEGIN_INTERRUPTABLE__
  5032         do {
  5032 	do {
  5033             ret = access(__stringVal(encodedPathName), X_OK);
  5033 	    ret = access(__stringVal(encodedPathName), X_OK);
  5034         } while ((ret < 0) && (errno == EINTR));
  5034 	} while ((ret < 0) && (errno == EINTR));
  5035         __END_INTERRUPTABLE__
  5035 	__END_INTERRUPTABLE__
  5036         if (ret < 0) {
  5036 	if (ret < 0) {
  5037             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5037 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5038         }
  5038 	}
  5039         RETURN ( ((ret == 0) ? true : false) );
  5039 	RETURN ( ((ret == 0) ? true : false) );
  5040     }
  5040     }
  5041 %}.
  5041 %}.
  5042     ^ self primitiveFailed
  5042     ^ self primitiveFailed
  5043 !
  5043 !
  5044 
  5044 
  5052 %{
  5052 %{
  5053     int ret;
  5053     int ret;
  5054 
  5054 
  5055     if (__isStringLike(encodedPathName)) {
  5055     if (__isStringLike(encodedPathName)) {
  5056 # ifdef TRACE_ACCESS_CALLS
  5056 # ifdef TRACE_ACCESS_CALLS
  5057         printf("access on '%s' for readable\n", __stringVal(encodedPathName));
  5057 	printf("access on '%s' for readable\n", __stringVal(encodedPathName));
  5058 # endif
  5058 # endif
  5059         __BEGIN_INTERRUPTABLE__
  5059 	__BEGIN_INTERRUPTABLE__
  5060         do {
  5060 	do {
  5061             ret = access(__stringVal(encodedPathName), R_OK);
  5061 	    ret = access(__stringVal(encodedPathName), R_OK);
  5062         } while ((ret < 0) && (errno == EINTR));
  5062 	} while ((ret < 0) && (errno == EINTR));
  5063         __END_INTERRUPTABLE__
  5063 	__END_INTERRUPTABLE__
  5064         if (ret < 0) {
  5064 	if (ret < 0) {
  5065             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5065 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5066         }
  5066 	}
  5067         RETURN ( ((ret == 0) ? true : false) );
  5067 	RETURN ( ((ret == 0) ? true : false) );
  5068     }
  5068     }
  5069 %}.
  5069 %}.
  5070     ^ self primitiveFailed
  5070     ^ self primitiveFailed
  5071 !
  5071 !
  5072 
  5072 
  5081     struct stat buf;
  5081     struct stat buf;
  5082     int ret;
  5082     int ret;
  5083 
  5083 
  5084     if (__isStringLike(encodedPathName)) {
  5084     if (__isStringLike(encodedPathName)) {
  5085 # ifdef TRACE_STAT_CALLS
  5085 # ifdef TRACE_STAT_CALLS
  5086         printf("stat on '%s' for isValidPath\n", __stringVal(encodedPathName));
  5086 	printf("stat on '%s' for isValidPath\n", __stringVal(encodedPathName));
  5087 # endif
  5087 # endif
  5088         __BEGIN_INTERRUPTABLE__
  5088 	__BEGIN_INTERRUPTABLE__
  5089         do {
  5089 	do {
  5090             ret = stat((char *) __stringVal(encodedPathName), &buf);
  5090 	    ret = stat((char *) __stringVal(encodedPathName), &buf);
  5091         } while ((ret < 0) && (errno == EINTR));
  5091 	} while ((ret < 0) && (errno == EINTR));
  5092         __END_INTERRUPTABLE__
  5092 	__END_INTERRUPTABLE__
  5093         if (ret < 0) {
  5093 	if (ret < 0) {
  5094             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5094 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5095             RETURN (false);
  5095 	    RETURN (false);
  5096         }
  5096 	}
  5097         RETURN ( ret ? false : true );
  5097 	RETURN ( ret ? false : true );
  5098     }
  5098     }
  5099 %}.
  5099 %}.
  5100     ^ self primitiveFailed
  5100     ^ self primitiveFailed
  5101 
  5101 
  5102 "/ alternative:
  5102 "/ alternative:
  5113 %{
  5113 %{
  5114     int ret;
  5114     int ret;
  5115 
  5115 
  5116     if (__isStringLike(encodedPathName)) {
  5116     if (__isStringLike(encodedPathName)) {
  5117 # ifdef TRACE_ACCESS_CALLS
  5117 # ifdef TRACE_ACCESS_CALLS
  5118         printf("access on '%s' for writable\n", __stringVal(encodedPathName));
  5118 	printf("access on '%s' for writable\n", __stringVal(encodedPathName));
  5119 # endif
  5119 # endif
  5120         __BEGIN_INTERRUPTABLE__
  5120 	__BEGIN_INTERRUPTABLE__
  5121         do {
  5121 	do {
  5122             ret = access(__stringVal(encodedPathName), W_OK);
  5122 	    ret = access(__stringVal(encodedPathName), W_OK);
  5123         } while ((ret < 0) && (errno == EINTR));
  5123 	} while ((ret < 0) && (errno == EINTR));
  5124         __END_INTERRUPTABLE__
  5124 	__END_INTERRUPTABLE__
  5125         if (ret < 0) {
  5125 	if (ret < 0) {
  5126             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5126 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5127         }
  5127 	}
  5128         RETURN ( ((ret == 0) ? true : false) );
  5128 	RETURN ( ((ret == 0) ? true : false) );
  5129     }
  5129     }
  5130 %}.
  5130 %}.
  5131     ^ self primitiveFailed
  5131     ^ self primitiveFailed
  5132 !
  5132 !
  5133 
  5133 
  5134 linkInfoOf:aPathName
  5134 linkInfoOf:aPathName
  5135     "return some object filled with info for the file 'aPathName'.
  5135     "return some object filled with info for the file 'aPathName'.
  5136 
  5136 
  5137      The info (for which corresponding access methods are understood by
  5137      The info (for which corresponding access methods are understood by
  5138      the returned object) is:
  5138      the returned object) is:
  5139          type            - a symbol giving the files type
  5139 	 type            - a symbol giving the files type
  5140          mode            - numeric access mode
  5140 	 mode            - numeric access mode
  5141          uid             - owners user id
  5141 	 uid             - owners user id
  5142          gid             - owners group id
  5142 	 gid             - owners group id
  5143          size            - files size
  5143 	 size            - files size
  5144          id              - files number (i.e. inode number)
  5144 	 id              - files number (i.e. inode number)
  5145          accessed        - last access time (as Timestamp)
  5145 	 accessed        - last access time (as Timestamp)
  5146          modified        - last modification time (as Timestamp)
  5146 	 modified        - last modification time (as Timestamp)
  5147          statusChanged   - last status change time (as Timestamp)
  5147 	 statusChanged   - last status change time (as Timestamp)
  5148          alternativeName     - (windows only:) the MSDOS name of the file
  5148 	 alternativeName     - (windows only:) the MSDOS name of the file
  5149          recordFormatNumeric - (VMS only:) numeric value of the recordFormat
  5149 	 recordFormatNumeric - (VMS only:) numeric value of the recordFormat
  5150          recordFormat        - (VMS only:) symbolic value of the recordFormat
  5150 	 recordFormat        - (VMS only:) symbolic value of the recordFormat
  5151          recordAttributes    - (VMS only:) recordAttributes
  5151 	 recordAttributes    - (VMS only:) recordAttributes
  5152          fixedHeaderSize     - (VMS only:) fixed header size in a variable record format
  5152 	 fixedHeaderSize     - (VMS only:) fixed header size in a variable record format
  5153          recordSize          - (VMS only:) record size.
  5153 	 recordSize          - (VMS only:) record size.
  5154 
  5154 
  5155      Some of the fields may be returned as nil on systems which do not provide
  5155      Some of the fields may be returned as nil on systems which do not provide
  5156      all of the information.
  5156      all of the information.
  5157 
  5157 
  5158      If aPathName is invalid, nil is returned.
  5158      If aPathName is invalid, nil is returned.
  5172     struct stat buf;
  5172     struct stat buf;
  5173     int ret;
  5173     int ret;
  5174     char pathBuffer[1024];
  5174     char pathBuffer[1024];
  5175 
  5175 
  5176     if (__isStringLike(encodedPathName)) {
  5176     if (__isStringLike(encodedPathName)) {
  5177         __BEGIN_INTERRUPTABLE__
  5177 	__BEGIN_INTERRUPTABLE__
  5178         do {
  5178 	do {
  5179             ret = lstat((char *) __stringVal(encodedPathName), &buf);
  5179 	    ret = lstat((char *) __stringVal(encodedPathName), &buf);
  5180         } while ((ret < 0) && (errno == EINTR));
  5180 	} while ((ret < 0) && (errno == EINTR));
  5181         __END_INTERRUPTABLE__
  5181 	__END_INTERRUPTABLE__
  5182 
  5182 
  5183         if (ret < 0) {
  5183 	if (ret < 0) {
  5184             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5184 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5185             RETURN ( nil );
  5185 	    RETURN ( nil );
  5186         }
  5186 	}
  5187         switch (buf.st_mode & S_IFMT) {
  5187 	switch (buf.st_mode & S_IFMT) {
  5188     # ifdef S_IFLNK
  5188     # ifdef S_IFLNK
  5189             case S_IFLNK:
  5189 	    case S_IFLNK:
  5190                 type = @symbol(symbolicLink);
  5190 		type = @symbol(symbolicLink);
  5191                 if ((ret = readlink((char *) __stringVal(encodedPathName), pathBuffer, sizeof(pathBuffer))) < 0) {
  5191 		if ((ret = readlink((char *) __stringVal(encodedPathName), pathBuffer, sizeof(pathBuffer))) < 0) {
  5192                     @global(LastErrorNumber) = __mkSmallInteger(errno);
  5192 		    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5193                     RETURN ( nil );
  5193 		    RETURN ( nil );
  5194                 }
  5194 		}
  5195                 pathBuffer[ret] = '\0';  /* readlink does not 0-terminate */
  5195 		pathBuffer[ret] = '\0';  /* readlink does not 0-terminate */
  5196                 path = __MKSTRING(pathBuffer);
  5196 		path = __MKSTRING(pathBuffer);
  5197                 break;
  5197 		break;
  5198     # endif
  5198     # endif
  5199             case S_IFDIR:
  5199 	    case S_IFDIR:
  5200                 type = @symbol(directory);
  5200 		type = @symbol(directory);
  5201                 break;
  5201 		break;
  5202 
  5202 
  5203             case S_IFREG:
  5203 	    case S_IFREG:
  5204                 type = @symbol(regular);
  5204 		type = @symbol(regular);
  5205                 break;
  5205 		break;
  5206     # ifdef S_IFCHR
  5206     # ifdef S_IFCHR
  5207             case S_IFCHR:
  5207 	    case S_IFCHR:
  5208                 type = @symbol(characterSpecial);
  5208 		type = @symbol(characterSpecial);
  5209                 break;
  5209 		break;
  5210     # endif
  5210     # endif
  5211     # ifdef S_IFBLK
  5211     # ifdef S_IFBLK
  5212             case S_IFBLK:
  5212 	    case S_IFBLK:
  5213                 type = @symbol(blockSpecial);
  5213 		type = @symbol(blockSpecial);
  5214                 break;
  5214 		break;
  5215     # endif
  5215     # endif
  5216     # ifdef S_IFMPC
  5216     # ifdef S_IFMPC
  5217             case S_IFMPC:
  5217 	    case S_IFMPC:
  5218                 type = @symbol(multiplexedCharacterSpecial);
  5218 		type = @symbol(multiplexedCharacterSpecial);
  5219                 break;
  5219 		break;
  5220     # endif
  5220     # endif
  5221     # ifdef S_IFMPB
  5221     # ifdef S_IFMPB
  5222             case S_IFMPB:
  5222 	    case S_IFMPB:
  5223                 type = @symbol(multiplexedBlockSpecial);
  5223 		type = @symbol(multiplexedBlockSpecial);
  5224                 break;
  5224 		break;
  5225     # endif
  5225     # endif
  5226     # ifdef S_IFSOCK
  5226     # ifdef S_IFSOCK
  5227             case S_IFSOCK:
  5227 	    case S_IFSOCK:
  5228                 type = @symbol(socket);
  5228 		type = @symbol(socket);
  5229                 break;
  5229 		break;
  5230     # endif
  5230     # endif
  5231     # ifdef S_IFIFO
  5231     # ifdef S_IFIFO
  5232             case S_IFIFO:
  5232 	    case S_IFIFO:
  5233                 type = @symbol(fifo);
  5233 		type = @symbol(fifo);
  5234                 break;
  5234 		break;
  5235     # endif
  5235     # endif
  5236             default:
  5236 	    default:
  5237                 type = @symbol(unknown);
  5237 		type = @symbol(unknown);
  5238                 break;
  5238 		break;
  5239         }
  5239 	}
  5240 
  5240 
  5241         if (sizeof(buf.st_ino) == 8) {
  5241 	if (sizeof(buf.st_ino) == 8) {
  5242             id = __MKUINT64(&buf.st_ino);
  5242 	    id = __MKUINT64(&buf.st_ino);
  5243         } else {
  5243 	} else {
  5244             id = __MKUINT(buf.st_ino);
  5244 	    id = __MKUINT(buf.st_ino);
  5245         }
  5245 	}
  5246         mode = __mkSmallInteger(buf.st_mode & 0777);
  5246 	mode = __mkSmallInteger(buf.st_mode & 0777);
  5247         uid = __mkSmallInteger(buf.st_uid);
  5247 	uid = __mkSmallInteger(buf.st_uid);
  5248         gid = __mkSmallInteger(buf.st_gid);
  5248 	gid = __mkSmallInteger(buf.st_gid);
  5249         nLink = __mkSmallInteger(buf.st_nlink);
  5249 	nLink = __mkSmallInteger(buf.st_nlink);
  5250         if (sizeof(buf.st_size) == 8) {
  5250 	if (sizeof(buf.st_size) == 8) {
  5251             size = __MKINT64(&buf.st_size);
  5251 	    size = __MKINT64(&buf.st_size);
  5252         } else {
  5252 	} else {
  5253             size = __MKINT(buf.st_size);
  5253 	    size = __MKINT(buf.st_size);
  5254         }
  5254 	}
  5255         aOStime = __MKUINT(buf.st_atime);
  5255 	aOStime = __MKUINT(buf.st_atime);
  5256         mOStime = __MKUINT(buf.st_mtime);
  5256 	mOStime = __MKUINT(buf.st_mtime);
  5257         cOStime = __MKUINT(buf.st_ctime);
  5257 	cOStime = __MKUINT(buf.st_ctime);
  5258     }
  5258     }
  5259 #else
  5259 #else
  5260     RETURN ( nil );
  5260     RETURN ( nil );
  5261 #endif
  5261 #endif
  5262 %}.
  5262 %}.
  5263 
  5263 
  5264     mode notNil ifTrue:[
  5264     mode notNil ifTrue:[
  5265         ^ FileStatusInfo
  5265 	^ FileStatusInfo
  5266             type:type
  5266 	    type:type
  5267             mode:mode
  5267 	    mode:mode
  5268             uid:uid
  5268 	    uid:uid
  5269             gid:gid
  5269 	    gid:gid
  5270             size:size
  5270 	    size:size
  5271             id:id
  5271 	    id:id
  5272             accessed:aOStime
  5272 	    accessed:aOStime
  5273             modified:mOStime
  5273 	    modified:mOStime
  5274             statusChanged:cOStime
  5274 	    statusChanged:cOStime
  5275             sourcePath:aPathName targetPath:(self decodePath:path)
  5275 	    sourcePath:aPathName targetPath:(self decodePath:path)
  5276             numLinks:nLink.
  5276 	    numLinks:nLink.
  5277    ].
  5277    ].
  5278    ^ self primitiveFailed
  5278    ^ self primitiveFailed
  5279 
  5279 
  5280    "
  5280    "
  5281     OperatingSystem infoOf:'Make.proto'
  5281     OperatingSystem infoOf:'Make.proto'
  5288     "return a collection of mountPoints (aka. topDirectories of mounted file systems).
  5288     "return a collection of mountPoints (aka. topDirectories of mounted file systems).
  5289      As this might be expensive on some systems,
  5289      As this might be expensive on some systems,
  5290      the info is cached for some time (5 minutes)"
  5290      the info is cached for some time (5 minutes)"
  5291 
  5291 
  5292     CacheMountPointsTimeStamp notNil ifTrue:[
  5292     CacheMountPointsTimeStamp notNil ifTrue:[
  5293         Timestamp now < (CacheMountPointsTimeStamp addSeconds:5*60) ifTrue:[
  5293 	Timestamp now < (CacheMountPointsTimeStamp addSeconds:5*60) ifTrue:[
  5294             ^ CachedMountPoints
  5294 	    ^ CachedMountPoints
  5295         ].
  5295 	].
  5296     ].
  5296     ].
  5297 
  5297 
  5298     '/proc/mounts' asFilename exists ifTrue:[
  5298     '/proc/mounts' asFilename exists ifTrue:[
  5299         CachedMountPoints := self mountPointsFromProcFS.
  5299 	CachedMountPoints := self mountPointsFromProcFS.
  5300         CacheMountPointsTimeStamp := Timestamp now.
  5300 	CacheMountPointsTimeStamp := Timestamp now.
  5301         ^ CachedMountPoints
  5301 	^ CachedMountPoints
  5302     ].
  5302     ].
  5303 
  5303 
  5304     "/ TODO: add fallback code for other OS's (i.e. reading /etc/mtab)
  5304     "/ TODO: add fallback code for other OS's (i.e. reading /etc/mtab)
  5305     ^ #()
  5305     ^ #()
  5306 
  5306 
  5337      from what you expect."
  5337      from what you expect."
  5338 
  5338 
  5339     |p path command|
  5339     |p path command|
  5340 
  5340 
  5341     path = '.' ifTrue:[
  5341     path = '.' ifTrue:[
  5342         ^ self getCurrentDirectory.
  5342 	^ self getCurrentDirectory.
  5343     ].
  5343     ].
  5344 
  5344 
  5345     "some systems have a convenient function for this ..."
  5345     "some systems have a convenient function for this ..."
  5346     path := self primPathNameOf:(self encodePath:pathName).
  5346     path := self primPathNameOf:(self encodePath:pathName).
  5347     path notNil ifTrue:[
  5347     path notNil ifTrue:[
  5348         path := self decodePath:path.
  5348 	path := self decodePath:path.
  5349     ] ifFalse:[
  5349     ] ifFalse:[
  5350         (self isValidPath:pathName) ifFalse:[
  5350 	(self isValidPath:pathName) ifFalse:[
  5351             p := pathName.
  5351 	    p := pathName.
  5352             [(p size > 1)
  5352 	    [(p size > 1)
  5353              and:[p endsWith:(self fileSeparator)]
  5353 	     and:[p endsWith:(self fileSeparator)]
  5354             ] whileTrue:[
  5354 	    ] whileTrue:[
  5355                 p := p copyButLast.
  5355 		p := p copyButLast.
  5356             ].
  5356 	    ].
  5357             ^ p
  5357 	    ^ p
  5358         ].
  5358 	].
  5359 
  5359 
  5360         (SlowFork==true or:[PipeFailed==true]) ifFalse:[
  5360 	(SlowFork==true or:[PipeFailed==true]) ifFalse:[
  5361             |directoryName fileBaseName|
  5361 	    |directoryName fileBaseName|
  5362 
  5362 
  5363             (self isDirectory:pathName) ifTrue:[
  5363 	    (self isDirectory:pathName) ifTrue:[
  5364                 directoryName := pathName.
  5364 		directoryName := pathName.
  5365                 fileBaseName := nil.
  5365 		fileBaseName := nil.
  5366             ] ifFalse:[
  5366 	    ] ifFalse:[
  5367                 |pathFilename|
  5367 		|pathFilename|
  5368                 pathFilename := pathName asFilename.
  5368 		pathFilename := pathName asFilename.
  5369                 directoryName := pathFilename directoryName.
  5369 		directoryName := pathFilename directoryName.
  5370                 fileBaseName := pathFilename baseName.
  5370 		fileBaseName := pathFilename baseName.
  5371             ].
  5371 	    ].
  5372 
  5372 
  5373             PipeStream openErrorSignal handle:[:ex |
  5373 	    PipeStream openErrorSignal handle:[:ex |
  5374                 PipeFailed := true.
  5374 		PipeFailed := true.
  5375                 'UnixOperatingSystem [warning]: cannot fork/popen' errorPrintCR.
  5375 		'UnixOperatingSystem [warning]: cannot fork/popen' errorPrintCR.
  5376                 ex return.
  5376 		ex return.
  5377             ] do:[
  5377 	    ] do:[
  5378                 "have to fall back ..."
  5378 		"have to fall back ..."
  5379                 command := 'cd "' , directoryName , '"; pwd'.
  5379 		command := 'cd "' , directoryName , '"; pwd'.
  5380                 p := PipeStream readingFrom:command.
  5380 		p := PipeStream readingFrom:command.
  5381             ].
  5381 	    ].
  5382 
  5382 
  5383             (p isNil or:[p atEnd]) ifTrue:[
  5383 	    (p isNil or:[p atEnd]) ifTrue:[
  5384                 ('UnixOperatingSystem [warning]: PipeStream for <' , command , '> failed') errorPrintCR.
  5384 		('UnixOperatingSystem [warning]: PipeStream for <' , command , '> failed') errorPrintCR.
  5385             ] ifFalse:[
  5385 	    ] ifFalse:[
  5386                 path := p nextLine.
  5386 		path := p nextLine.
  5387                 p close.
  5387 		p close.
  5388             ].
  5388 	    ].
  5389             fileBaseName notNil ifTrue:[
  5389 	    fileBaseName notNil ifTrue:[
  5390                 path := path, '/', fileBaseName.
  5390 		path := path, '/', fileBaseName.
  5391             ].
  5391 	    ].
  5392         ].
  5392 	].
  5393         path isNil ifTrue:[
  5393 	path isNil ifTrue:[
  5394             "/
  5394 	    "/
  5395             "/ return the original - there is nothing else can we do
  5395 	    "/ return the original - there is nothing else can we do
  5396             "/
  5396 	    "/
  5397             path := pathName
  5397 	    path := pathName
  5398         ].
  5398 	].
  5399         (SlowFork==true or:[ForkFailed==true]) ifTrue:[
  5399 	(SlowFork==true or:[ForkFailed==true]) ifTrue:[
  5400             path := self compressPath:path
  5400 	    path := self compressPath:path
  5401         ]
  5401 	]
  5402     ].
  5402     ].
  5403     ^ path.
  5403     ^ path.
  5404 
  5404 
  5405     "
  5405     "
  5406      OperatingSystem pathNameOf:'.'
  5406      OperatingSystem pathNameOf:'.'
  5421     "return the name of the current directory"
  5421     "return the name of the current directory"
  5422 
  5422 
  5423     |path|
  5423     |path|
  5424 
  5424 
  5425 %{  /* UNLIMITEDSTACK */
  5425 %{  /* UNLIMITEDSTACK */
  5426         char nameBuffer[MAXPATHLEN + 1];
  5426 	char nameBuffer[MAXPATHLEN + 1];
  5427 
  5427 
  5428         if (getcwd(nameBuffer, MAXPATHLEN)) {
  5428 	if (getcwd(nameBuffer, MAXPATHLEN)) {
  5429             path = __MKSTRING(nameBuffer);
  5429 	    path = __MKSTRING(nameBuffer);
  5430             RETURN(path);
  5430 	    RETURN(path);
  5431         }
  5431 	}
  5432 %}.
  5432 %}.
  5433     ^ self primitiveFailed.
  5433     ^ self primitiveFailed.
  5434 
  5434 
  5435     "
  5435     "
  5436         self primGetCurrentDirectory
  5436 	self primGetCurrentDirectory
  5437     "
  5437     "
  5438 !
  5438 !
  5439 
  5439 
  5440 primIdOf:aPathName
  5440 primIdOf:aPathName
  5441     "the actual code to return the fileNumber (i.e. inode number) of a file."
  5441     "the actual code to return the fileNumber (i.e. inode number) of a file."
  5449     unsigned INT ino;
  5449     unsigned INT ino;
  5450     OBJ retVal;
  5450     OBJ retVal;
  5451 
  5451 
  5452     if (__isStringLike(encodedPathName)) {
  5452     if (__isStringLike(encodedPathName)) {
  5453 # ifdef TRACE_STAT_CALLS
  5453 # ifdef TRACE_STAT_CALLS
  5454         printf("stat on '%s' for id\n", __stringVal(encodedPathName));
  5454 	printf("stat on '%s' for id\n", __stringVal(encodedPathName));
  5455 # endif
  5455 # endif
  5456         __BEGIN_INTERRUPTABLE__
  5456 	__BEGIN_INTERRUPTABLE__
  5457         do {
  5457 	do {
  5458             ret = stat((char *) __stringVal(encodedPathName), &buf);
  5458 	    ret = stat((char *) __stringVal(encodedPathName), &buf);
  5459         } while (ret < 0 && errno == EINTR);
  5459 	} while (ret < 0 && errno == EINTR);
  5460         __END_INTERRUPTABLE__
  5460 	__END_INTERRUPTABLE__
  5461         if (ret >= 0) {
  5461 	if (ret >= 0) {
  5462             ino = buf.st_ino;
  5462 	    ino = buf.st_ino;
  5463             retVal = __MKUINT(ino);
  5463 	    retVal = __MKUINT(ino);
  5464             RETURN (retVal);
  5464 	    RETURN (retVal);
  5465         }
  5465 	}
  5466         @global(LastErrorNumber) = __mkSmallInteger(errno);
  5466 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  5467         RETURN (nil);
  5467 	RETURN (nil);
  5468     }
  5468     }
  5469     RETURN (nil);
  5469     RETURN (nil);
  5470 %}.
  5470 %}.
  5471 !
  5471 !
  5472 
  5472 
  5490 
  5490 
  5491 %{  /* UNLIMITEDSTACK */
  5491 %{  /* UNLIMITEDSTACK */
  5492 
  5492 
  5493     if (__isStringLike(pathName)) {
  5493     if (__isStringLike(pathName)) {
  5494 #ifdef HAS_REALPATH
  5494 #ifdef HAS_REALPATH
  5495         extern char *realpath();
  5495 	extern char *realpath();
  5496 
  5496 
  5497         // POSIX-2008 says, that a NULL namebuffer causes realPath to malloc()
  5497 	// POSIX-2008 says, that a NULL namebuffer causes realPath to malloc()
  5498         // the required memory. But this does not work as of 2013-04
  5498 	// the required memory. But this does not work as of 2013-04
  5499         char nameBuffer[MAXPATHLEN+1];
  5499 	char nameBuffer[MAXPATHLEN+1];
  5500         char *nameP = realpath(__stringVal(pathName), nameBuffer);
  5500 	char *nameP = realpath(__stringVal(pathName), nameBuffer);
  5501         if (nameP) {
  5501 	if (nameP) {
  5502             OBJ ret = __MKSTRING(nameP);
  5502 	    OBJ ret = __MKSTRING(nameP);
  5503             // free(nameP);
  5503 	    // free(nameP);
  5504             RETURN ( ret );
  5504 	    RETURN ( ret );
  5505         }
  5505 	}
  5506         // fprintf(stderr, "stx[warning]: realpath(\"%s\") failed: %s\n", __stringVal(pathName), strerror(errno));
  5506 	// fprintf(stderr, "stx[warning]: realpath(\"%s\") failed: %s\n", __stringVal(pathName), strerror(errno));
  5507 #endif /* ! HAS_REALPATH */
  5507 #endif /* ! HAS_REALPATH */
  5508     } else {
  5508     } else {
  5509         error = @symbol(argument);     // argument is not a string
  5509 	error = @symbol(argument);     // argument is not a string
  5510     }
  5510     }
  5511 %}.
  5511 %}.
  5512 "/ Does not work as of 2013-04 (UNLIMITEDSTACK problem?)
  5512 "/ Does not work as of 2013-04 (UNLIMITEDSTACK problem?)
  5513 "/    error notNil ifTrue:[
  5513 "/    error notNil ifTrue:[
  5514 "/        ^ self primitiveFailed:error.
  5514 "/        ^ self primitiveFailed:error.
  5515 "/    ].
  5515 "/    ].
  5516     ^ nil
  5516     ^ nil
  5517 
  5517 
  5518     "
  5518     "
  5519         self primPathNameOf:'.'
  5519 	self primPathNameOf:'.'
  5520         self primPathNameOf:'/murks/quatsch/bla/.'
  5520 	self primPathNameOf:'/murks/quatsch/bla/.'
  5521         self primPathNameOf:5555
  5521 	self primPathNameOf:5555
  5522     "
  5522     "
  5523 !
  5523 !
  5524 
  5524 
  5525 timeOfLastAccess:aPathName
  5525 timeOfLastAccess:aPathName
  5526     "return the time, when the file was last accessed.
  5526     "return the time, when the file was last accessed.
  5527      For nonexistent files, nil is returned."
  5527      For nonexistent files, nil is returned."
  5528 
  5528 
  5529     "could be implemented as:
  5529     "could be implemented as:
  5530         (self infoOf:aPathName) accessed
  5530 	(self infoOf:aPathName) accessed
  5531     "
  5531     "
  5532     |osSeconds i encodedPathName|
  5532     |osSeconds i encodedPathName|
  5533 
  5533 
  5534     encodedPathName := self encodePath:aPathName.
  5534     encodedPathName := self encodePath:aPathName.
  5535 
  5535 
  5538     time_t mtime;
  5538     time_t mtime;
  5539     int ret;
  5539     int ret;
  5540 
  5540 
  5541     if (__isStringLike(encodedPathName)) {
  5541     if (__isStringLike(encodedPathName)) {
  5542 # ifdef TRACE_STAT_CALLS
  5542 # ifdef TRACE_STAT_CALLS
  5543         printf("stat on '%s' for timeOfLastAccess\n", __stringVal(encodedPathName));
  5543 	printf("stat on '%s' for timeOfLastAccess\n", __stringVal(encodedPathName));
  5544 # endif
  5544 # endif
  5545         __BEGIN_INTERRUPTABLE__
  5545 	__BEGIN_INTERRUPTABLE__
  5546         do {
  5546 	do {
  5547             ret = stat((char *) __stringVal(encodedPathName), &buf);
  5547 	    ret = stat((char *) __stringVal(encodedPathName), &buf);
  5548         } while (ret < 0 && errno == EINTR);
  5548 	} while (ret < 0 && errno == EINTR);
  5549         __END_INTERRUPTABLE__
  5549 	__END_INTERRUPTABLE__
  5550         if (ret < 0) {
  5550 	if (ret < 0) {
  5551             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5551 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5552             RETURN (nil);
  5552 	    RETURN (nil);
  5553         }
  5553 	}
  5554         osSeconds = __MKUINT(buf.st_atime);
  5554 	osSeconds = __MKUINT(buf.st_atime);
  5555     }
  5555     }
  5556 %}.
  5556 %}.
  5557     osSeconds notNil ifTrue:[^ Timestamp fromOSTime:(osSeconds * 1000)].
  5557     osSeconds notNil ifTrue:[^ Timestamp fromOSTime:(osSeconds * 1000)].
  5558 
  5558 
  5559     i := self infoOf:aPathName.
  5559     i := self infoOf:aPathName.
  5568 timeOfLastChange:aPathName
  5568 timeOfLastChange:aPathName
  5569     "return the time, when the file was last changed.
  5569     "return the time, when the file was last changed.
  5570      For nonexistent files, nil is returned."
  5570      For nonexistent files, nil is returned."
  5571 
  5571 
  5572     "could be implemented as:
  5572     "could be implemented as:
  5573         (self infoOf:aPathName) modified
  5573 	(self infoOf:aPathName) modified
  5574     "
  5574     "
  5575 
  5575 
  5576     |osSeconds i encodedPathName|
  5576     |osSeconds i encodedPathName|
  5577 
  5577 
  5578     encodedPathName := self encodePath:aPathName.
  5578     encodedPathName := self encodePath:aPathName.
  5581     int ret;
  5581     int ret;
  5582     time_t mtime;
  5582     time_t mtime;
  5583 
  5583 
  5584     if (__isStringLike(encodedPathName)) {
  5584     if (__isStringLike(encodedPathName)) {
  5585 # ifdef TRACE_STAT_CALLS
  5585 # ifdef TRACE_STAT_CALLS
  5586         printf("stat on '%s' for timeOfLastChange\n", __stringVal(encodedPathName));
  5586 	printf("stat on '%s' for timeOfLastChange\n", __stringVal(encodedPathName));
  5587 # endif
  5587 # endif
  5588         __BEGIN_INTERRUPTABLE__
  5588 	__BEGIN_INTERRUPTABLE__
  5589         do {
  5589 	do {
  5590             ret = stat((char *) __stringVal(encodedPathName), &buf);
  5590 	    ret = stat((char *) __stringVal(encodedPathName), &buf);
  5591         } while (ret < 0 && errno == EINTR);
  5591 	} while (ret < 0 && errno == EINTR);
  5592         __END_INTERRUPTABLE__
  5592 	__END_INTERRUPTABLE__
  5593         if (ret < 0) {
  5593 	if (ret < 0) {
  5594             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5594 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5595             RETURN ( nil );
  5595 	    RETURN ( nil );
  5596         }
  5596 	}
  5597         osSeconds = __MKUINT(buf.st_mtime);
  5597 	osSeconds = __MKUINT(buf.st_mtime);
  5598     }
  5598     }
  5599 %}.
  5599 %}.
  5600     osSeconds notNil ifTrue:[^ Timestamp fromOSTime:(osSeconds * 1000)].
  5600     osSeconds notNil ifTrue:[^ Timestamp fromOSTime:(osSeconds * 1000)].
  5601 
  5601 
  5602     i := self infoOf:aPathName.
  5602     i := self infoOf:aPathName.
  5617 
  5617 
  5618     encodedPathName := self encodePath:aPathName.
  5618     encodedPathName := self encodePath:aPathName.
  5619 
  5619 
  5620     "
  5620     "
  5621      this could have been implemented as:
  5621      this could have been implemented as:
  5622         (self infoOf:aPathName) type
  5622 	(self infoOf:aPathName) type
  5623      but for huge directory searches the code below is faster
  5623      but for huge directory searches the code below is faster
  5624     "
  5624     "
  5625 
  5625 
  5626 %{
  5626 %{
  5627     struct stat buf;
  5627     struct stat buf;
  5628     int ret;
  5628     int ret;
  5629 
  5629 
  5630     if (__isStringLike(encodedPathName)) {
  5630     if (__isStringLike(encodedPathName)) {
  5631 # ifdef TRACE_STAT_CALLS
  5631 # ifdef TRACE_STAT_CALLS
  5632         printf("stat on '%s' for type\n", __stringVal(encodedPathName));
  5632 	printf("stat on '%s' for type\n", __stringVal(encodedPathName));
  5633 # endif
  5633 # endif
  5634         __BEGIN_INTERRUPTABLE__
  5634 	__BEGIN_INTERRUPTABLE__
  5635         do {
  5635 	do {
  5636             ret = stat((char *) __stringVal(encodedPathName), &buf);
  5636 	    ret = stat((char *) __stringVal(encodedPathName), &buf);
  5637         } while (ret < 0 && errno == EINTR);
  5637 	} while (ret < 0 && errno == EINTR);
  5638         __END_INTERRUPTABLE__
  5638 	__END_INTERRUPTABLE__
  5639         if (ret < 0) {
  5639 	if (ret < 0) {
  5640             @global(LastErrorNumber) = __mkSmallInteger(errno);
  5640 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  5641             RETURN ( nil );
  5641 	    RETURN ( nil );
  5642         }
  5642 	}
  5643         switch (buf.st_mode & S_IFMT) {
  5643 	switch (buf.st_mode & S_IFMT) {
  5644             case S_IFDIR:
  5644 	    case S_IFDIR:
  5645                 RETURN ( @symbol(directory) );
  5645 		RETURN ( @symbol(directory) );
  5646             case S_IFREG:
  5646 	    case S_IFREG:
  5647                 RETURN ( @symbol(regular) );
  5647 		RETURN ( @symbol(regular) );
  5648 # ifdef S_IFCHR
  5648 # ifdef S_IFCHR
  5649             case S_IFCHR:
  5649 	    case S_IFCHR:
  5650                 RETURN ( @symbol(characterSpecial) );
  5650 		RETURN ( @symbol(characterSpecial) );
  5651 # endif
  5651 # endif
  5652 # ifdef S_IFBLK
  5652 # ifdef S_IFBLK
  5653             case S_IFBLK:
  5653 	    case S_IFBLK:
  5654                 RETURN ( @symbol(blockSpecial) );
  5654 		RETURN ( @symbol(blockSpecial) );
  5655 # endif
  5655 # endif
  5656 # ifdef S_IFLNK
  5656 # ifdef S_IFLNK
  5657             case S_IFLNK:
  5657 	    case S_IFLNK:
  5658                 RETURN ( @symbol(symbolicLink) );
  5658 		RETURN ( @symbol(symbolicLink) );
  5659 # endif
  5659 # endif
  5660 # ifdef S_IFSOCK
  5660 # ifdef S_IFSOCK
  5661             case S_IFSOCK:
  5661 	    case S_IFSOCK:
  5662                 RETURN ( @symbol(socket) );
  5662 		RETURN ( @symbol(socket) );
  5663 # endif
  5663 # endif
  5664 # ifdef S_IFIFO
  5664 # ifdef S_IFIFO
  5665             case S_IFIFO:
  5665 	    case S_IFIFO:
  5666                 RETURN ( @symbol(fifo) );
  5666 		RETURN ( @symbol(fifo) );
  5667 # endif
  5667 # endif
  5668             default:
  5668 	    default:
  5669                 RETURN ( @symbol(unknown) );
  5669 		RETURN ( @symbol(unknown) );
  5670         }
  5670 	}
  5671     }
  5671     }
  5672 %}.
  5672 %}.
  5673     i := self infoOf:aPathName.
  5673     i := self infoOf:aPathName.
  5674     i notNil ifTrue:[^ i type].
  5674     i notNil ifTrue:[^ i type].
  5675     ^ nil.
  5675     ^ nil.
  5707 
  5707 
  5708 %{  /* NOCONTEXT */
  5708 %{  /* NOCONTEXT */
  5709 
  5709 
  5710     if (__isSmallInteger(signalNumber)) {
  5710     if (__isSmallInteger(signalNumber)) {
  5711 #ifdef SIG_DFL
  5711 #ifdef SIG_DFL
  5712         signal(__intVal(signalNumber), SIG_DFL);
  5712 	signal(__intVal(signalNumber), SIG_DFL);
  5713         RETURN (self);
  5713 	RETURN (self);
  5714 #endif
  5714 #endif
  5715     }
  5715     }
  5716 %}.
  5716 %}.
  5717     "
  5717     "
  5718      this error is triggered on non-integer argument
  5718      this error is triggered on non-integer argument
  5736 
  5736 
  5737     int ret, flags, f;
  5737     int ret, flags, f;
  5738 
  5738 
  5739 #if (defined(F_GETFL) && defined(F_SETFL) && defined(FASYNC)) || defined(SYSV4)
  5739 #if (defined(F_GETFL) && defined(F_SETFL) && defined(FASYNC)) || defined(SYSV4)
  5740     if (__isSmallInteger(fd)) {
  5740     if (__isSmallInteger(fd)) {
  5741         f = __intVal(fd);
  5741 	f = __intVal(fd);
  5742 # if defined(SYSV4)
  5742 # if defined(SYSV4)
  5743         ret = ioctl(f, I_SETSIG, 0);
  5743 	ret = ioctl(f, I_SETSIG, 0);
  5744 # else /*! SYSV4*/
  5744 # else /*! SYSV4*/
  5745         flags = fcntl(f, F_GETFL, 0);
  5745 	flags = fcntl(f, F_GETFL, 0);
  5746         /*
  5746 	/*
  5747          * if already clear, there is no need for this syscall ...
  5747 	 * if already clear, there is no need for this syscall ...
  5748          */
  5748 	 */
  5749         if (flags & FASYNC) {
  5749 	if (flags & FASYNC) {
  5750             ret = fcntl(f, F_SETFL, flags & ~FASYNC);
  5750 	    ret = fcntl(f, F_SETFL, flags & ~FASYNC);
  5751             if (ret >= 0) ret = flags;
  5751 	    if (ret >= 0) ret = flags;
  5752         } else {
  5752 	} else {
  5753             ret = flags;
  5753 	    ret = flags;
  5754         }
  5754 	}
  5755 # endif /* !SYSV4 */
  5755 # endif /* !SYSV4 */
  5756         RETURN ( __mkSmallInteger(ret) );
  5756 	RETURN ( __mkSmallInteger(ret) );
  5757     }
  5757     }
  5758 #endif
  5758 #endif
  5759 %}.
  5759 %}.
  5760     "
  5760     "
  5761      this error is triggered on non-integer argument
  5761      this error is triggered on non-integer argument
  5776      Use only for fully debugged stand alone applications."
  5776      Use only for fully debugged stand alone applications."
  5777 
  5777 
  5778 %{  /* NOCONTEXT */
  5778 %{  /* NOCONTEXT */
  5779 
  5779 
  5780     if (__isSmallInteger(signalNumber)) {
  5780     if (__isSmallInteger(signalNumber)) {
  5781         int sigNo = __intVal(signalNumber);
  5781 	int sigNo = __intVal(signalNumber);
  5782 
  5782 
  5783         if (sigNo == 0) {
  5783 	if (sigNo == 0) {
  5784             RETURN (self);
  5784 	    RETURN (self);
  5785         }
  5785 	}
  5786 #ifdef SIG_IGN
  5786 #ifdef SIG_IGN
  5787         signal(sigNo, SIG_IGN);
  5787 	signal(sigNo, SIG_IGN);
  5788         RETURN (self);
  5788 	RETURN (self);
  5789 #endif
  5789 #endif
  5790     }
  5790     }
  5791 %}.
  5791 %}.
  5792     "
  5792     "
  5793      this error is triggered on non-integer argument
  5793      this error is triggered on non-integer argument
  5804 !
  5804 !
  5805 
  5805 
  5806 disableTimer
  5806 disableTimer
  5807     "disable timer interrupts.
  5807     "disable timer interrupts.
  5808      WARNING:
  5808      WARNING:
  5809         the system will not operate correctly with timer interrupts
  5809 	the system will not operate correctly with timer interrupts
  5810         disabled, because no scheduling or timeouts are possible."
  5810 	disabled, because no scheduling or timeouts are possible."
  5811 
  5811 
  5812 %{  /* NOCONTEXT */
  5812 %{  /* NOCONTEXT */
  5813 
  5813 
  5814 #if defined(ITIMER_REAL) && !defined(NO_SETITIMER)
  5814 #if defined(ITIMER_REAL) && !defined(NO_SETITIMER)
  5815     struct itimerval dt;
  5815     struct itimerval dt;
  5870 #   endif
  5870 #   endif
  5871 #  endif
  5871 #  endif
  5872 # endif
  5872 # endif
  5873 
  5873 
  5874     if (__isSmallInteger(fd)) {
  5874     if (__isSmallInteger(fd)) {
  5875         if (firstCall) {
  5875 	if (firstCall) {
  5876 # ifdef HAS_SIGACTION
  5876 # ifdef HAS_SIGACTION
  5877             struct sigaction act;
  5877 	    struct sigaction act;
  5878 
  5878 
  5879             /*
  5879 	    /*
  5880              * Do not add SA_RESTART here. A signal can cause a
  5880 	     * Do not add SA_RESTART here. A signal can cause a
  5881              * thread switch, another thread can do a garbage collect
  5881 	     * thread switch, another thread can do a garbage collect
  5882              * and restarted system calls may write into old
  5882 	     * and restarted system calls may write into old
  5883              * (collected) addresses.
  5883 	     * (collected) addresses.
  5884              */
  5884 	     */
  5885 
  5885 
  5886             act.sa_flags = SA_SIGINFO; /* <- if you add more, remember dummys at the top */
  5886 	    act.sa_flags = SA_SIGINFO; /* <- if you add more, remember dummys at the top */
  5887             sigemptyset(&act.sa_mask);
  5887 	    sigemptyset(&act.sa_mask);
  5888             act.sa_handler = __signalIoInterrupt;
  5888 	    act.sa_handler = __signalIoInterrupt;
  5889             sigaction(THESIGNAL, &act, 0);
  5889 	    sigaction(THESIGNAL, &act, 0);
  5890 # else
  5890 # else
  5891 #  ifdef HAS_SIGVEC
  5891 #  ifdef HAS_SIGVEC
  5892             struct sigvec vec;
  5892 	    struct sigvec vec;
  5893 
  5893 
  5894             vec.sv_flags = SV_INTERRUPT;
  5894 	    vec.sv_flags = SV_INTERRUPT;
  5895             sigemptyset(&vec.sv_mask);
  5895 	    sigemptyset(&vec.sv_mask);
  5896             vec.sv_handler = __signalIoInterrupt;
  5896 	    vec.sv_handler = __signalIoInterrupt;
  5897             sigvec(THESIGNAL, &vec, NULL);
  5897 	    sigvec(THESIGNAL, &vec, NULL);
  5898 #  else
  5898 #  else
  5899             signal(THESIGNAL, __signalIoInterrupt);
  5899 	    signal(THESIGNAL, __signalIoInterrupt);
  5900 #  endif /* SIGVEC */
  5900 #  endif /* SIGVEC */
  5901 # endif /* SIGACTION */
  5901 # endif /* SIGACTION */
  5902             firstCall = 0;
  5902 	    firstCall = 0;
  5903         }
  5903 	}
  5904 #undef THESIGNAL
  5904 #undef THESIGNAL
  5905 
  5905 
  5906         f = __intVal(fd);
  5906 	f = __intVal(fd);
  5907 # if defined(SYSV4)
  5907 # if defined(SYSV4)
  5908         ret = ioctl(f, I_SETSIG, S_INPUT | S_HIPRI | S_ERROR | S_RDNORM | S_RDBAND | S_MSG | S_HANGUP);
  5908 	ret = ioctl(f, I_SETSIG, S_INPUT | S_HIPRI | S_ERROR | S_RDNORM | S_RDBAND | S_MSG | S_HANGUP);
  5909 # else /*! SYSV4*/
  5909 # else /*! SYSV4*/
  5910         flags = fcntl(f, F_GETFL, 0);
  5910 	flags = fcntl(f, F_GETFL, 0);
  5911         /*
  5911 	/*
  5912          * if already set, there is no need for this syscall ...
  5912 	 * if already set, there is no need for this syscall ...
  5913          */
  5913 	 */
  5914         if (flags & FASYNC) {
  5914 	if (flags & FASYNC) {
  5915             ret = flags;
  5915 	    ret = flags;
  5916         } else {
  5916 	} else {
  5917             ret = fcntl(f, F_SETFL, flags | FASYNC);
  5917 	    ret = fcntl(f, F_SETFL, flags | FASYNC);
  5918             if (ret >= 0) ret = flags;
  5918 	    if (ret >= 0) ret = flags;
  5919         }
  5919 	}
  5920 # endif /*!SYSV4*/
  5920 # endif /*!SYSV4*/
  5921 
  5921 
  5922 # if defined(F_SETOWN) || defined(FIOSETOWN)
  5922 # if defined(F_SETOWN) || defined(FIOSETOWN)
  5923         {
  5923 	{
  5924             int pid;
  5924 	    int pid;
  5925             int ok;
  5925 	    int ok;
  5926 
  5926 
  5927             pid = getpid();
  5927 	    pid = getpid();
  5928 
  5928 
  5929 #  if defined(F_SETOWN)
  5929 #  if defined(F_SETOWN)
  5930             ok = fcntl(f, F_SETOWN, pid);
  5930 	    ok = fcntl(f, F_SETOWN, pid);
  5931             /* printf("F_SETOWN returns %d (%d)\n", ret, errno); */
  5931 	    /* printf("F_SETOWN returns %d (%d)\n", ret, errno); */
  5932 #  else
  5932 #  else
  5933             ok = ioctl(f, FIOSETOWN, &pid);
  5933 	    ok = ioctl(f, FIOSETOWN, &pid);
  5934             /* printf("FIOSETOWN returns %d (%d)\n", ret, errno); */
  5934 	    /* printf("FIOSETOWN returns %d (%d)\n", ret, errno); */
  5935 #  endif
  5935 #  endif
  5936             if (ok < 0) {
  5936 	    if (ok < 0) {
  5937                 ret = ok;
  5937 		ret = ok;
  5938             }
  5938 	    }
  5939         }
  5939 	}
  5940 # endif
  5940 # endif
  5941         RETURN ( __MKUINT(ret) );
  5941 	RETURN ( __MKUINT(ret) );
  5942     }
  5942     }
  5943 #endif
  5943 #endif
  5944 %}.
  5944 %}.
  5945     "
  5945     "
  5946      this error is triggered on non-integer argument
  5946      this error is triggered on non-integer argument
  6046      && ((sigNr = __intVal(signalNumber)) >= 0)
  6046      && ((sigNr = __intVal(signalNumber)) >= 0)
  6047 #ifdef SIG_LIMIT
  6047 #ifdef SIG_LIMIT
  6048      &&  (sigNr <= SIG_LIMIT)
  6048      &&  (sigNr <= SIG_LIMIT)
  6049 #endif
  6049 #endif
  6050     ) {
  6050     ) {
  6051         /*
  6051 	/*
  6052          * standard signals are forced into standard handlers
  6052 	 * standard signals are forced into standard handlers
  6053          * - all others go into general signalInterrupt
  6053 	 * - all others go into general signalInterrupt
  6054          */
  6054 	 */
  6055 #if defined(SIGPOLL) && defined(SIGIO)
  6055 #if defined(SIGPOLL) && defined(SIGIO)
  6056         if (sigNr == SIGPOLL)
  6056 	if (sigNr == SIGPOLL)
  6057             sigNr = SIGIO;
  6057 	    sigNr = SIGIO;
  6058 #endif
  6058 #endif
  6059         switch (sigNr) {
  6059 	switch (sigNr) {
  6060             case 0:
  6060 	    case 0:
  6061                 /* enabling a non-supported signal */
  6061 		/* enabling a non-supported signal */
  6062                 RETURN (self);
  6062 		RETURN (self);
  6063 
  6063 
  6064 #ifdef SIGBREAK
  6064 #ifdef SIGBREAK
  6065             case SIGBREAK:
  6065 	    case SIGBREAK:
  6066 #endif
  6066 #endif
  6067 #ifdef SIGINT
  6067 #ifdef SIGINT
  6068             case SIGINT:
  6068 	    case SIGINT:
  6069 #endif
  6069 #endif
  6070 #ifdef SIGQUIT
  6070 #ifdef SIGQUIT
  6071             case SIGQUIT:
  6071 	    case SIGQUIT:
  6072 #endif
  6072 #endif
  6073 #if defined(SIGINT) || defined(SIGQUIT) || defined(SIGBREAK)
  6073 #if defined(SIGINT) || defined(SIGQUIT) || defined(SIGBREAK)
  6074                 handler = __signalUserInterrupt;
  6074 		handler = __signalUserInterrupt;
  6075                 break;
  6075 		break;
  6076 #endif
  6076 #endif
  6077 #ifdef SIGFPE
  6077 #ifdef SIGFPE
  6078             case SIGFPE:
  6078 	    case SIGFPE:
  6079                 handler = __signalFpExceptionInterrupt;
  6079 		handler = __signalFpExceptionInterrupt;
  6080                 break;
  6080 		break;
  6081 #endif
  6081 #endif
  6082 
  6082 
  6083 #ifdef SIGPIPE
  6083 #ifdef SIGPIPE
  6084             case SIGPIPE:
  6084 	    case SIGPIPE:
  6085                 handler = __signalPIPEInterrupt;
  6085 		handler = __signalPIPEInterrupt;
  6086                 break;
  6086 		break;
  6087 #endif
  6087 #endif
  6088 #ifdef SIGBUS
  6088 #ifdef SIGBUS
  6089             case SIGBUS:
  6089 	    case SIGBUS:
  6090                 handler = __signalBUSInterrupt;
  6090 		handler = __signalBUSInterrupt;
  6091                 break;
  6091 		break;
  6092 #endif
  6092 #endif
  6093 #ifdef SIGSEGV
  6093 #ifdef SIGSEGV
  6094             case SIGSEGV:
  6094 	    case SIGSEGV:
  6095                 handler = __signalSEGVInterrupt;
  6095 		handler = __signalSEGVInterrupt;
  6096                 break;
  6096 		break;
  6097 #endif
  6097 #endif
  6098 #ifdef SIGABRT
  6098 #ifdef SIGABRT
  6099             case SIGABRT:
  6099 	    case SIGABRT:
  6100                 handler = __signalAbortInterrupt;
  6100 		handler = __signalAbortInterrupt;
  6101                 break;
  6101 		break;
  6102 #endif
  6102 #endif
  6103 #ifdef SIGILL
  6103 #ifdef SIGILL
  6104             case SIGILL:
  6104 	    case SIGILL:
  6105                 handler = __signalTrapInterrupt;
  6105 		handler = __signalTrapInterrupt;
  6106                 break;
  6106 		break;
  6107 #endif
  6107 #endif
  6108 #ifdef SIGEMT
  6108 #ifdef SIGEMT
  6109             case SIGEMT:
  6109 	    case SIGEMT:
  6110                 handler = __signalTrapInterrupt;
  6110 		handler = __signalTrapInterrupt;
  6111                 break;
  6111 		break;
  6112 #endif
  6112 #endif
  6113 #ifdef SIGIO
  6113 #ifdef SIGIO
  6114             case SIGIO:
  6114 	    case SIGIO:
  6115                 handler = __signalIoInterrupt;
  6115 		handler = __signalIoInterrupt;
  6116                 break;
  6116 		break;
  6117 #endif
  6117 #endif
  6118 
  6118 
  6119 #ifdef CHILD_SIGNAL
  6119 #ifdef CHILD_SIGNAL
  6120             case CHILD_SIGNAL:
  6120 	    case CHILD_SIGNAL:
  6121                 handler = __signalChildInterrupt;
  6121 		handler = __signalChildInterrupt;
  6122                 break;
  6122 		break;
  6123 #endif
  6123 #endif
  6124 #ifdef SIGALRM
  6124 #ifdef SIGALRM
  6125             case SIGALRM:
  6125 	    case SIGALRM:
  6126                 handler = __signalTimerInterrupt;
  6126 		handler = __signalTimerInterrupt;
  6127                 break;
  6127 		break;
  6128 #endif
  6128 #endif
  6129 
  6129 
  6130             default:
  6130 	    default:
  6131                 handler = __signalInterrupt;
  6131 		handler = __signalInterrupt;
  6132                 break;
  6132 		break;
  6133         }
  6133 	}
  6134 
  6134 
  6135         {
  6135 	{
  6136 #ifdef HAS_SIGACTION
  6136 #ifdef HAS_SIGACTION
  6137             struct sigaction act;
  6137 	    struct sigaction act;
  6138 
  6138 
  6139             /*
  6139 	    /*
  6140              * Do not add SA_RESTART here. A signal can cause a
  6140 	     * Do not add SA_RESTART here. A signal can cause a
  6141              * thread switch, another thread can do a garbage collect
  6141 	     * thread switch, another thread can do a garbage collect
  6142              * and restarted system calls may write into old
  6142 	     * and restarted system calls may write into old
  6143              * (collected) addresses.
  6143 	     * (collected) addresses.
  6144              */
  6144 	     */
  6145 
  6145 
  6146             act.sa_flags = SA_SIGINFO; /* <- if you add more, remember dummys at the top */
  6146 	    act.sa_flags = SA_SIGINFO; /* <- if you add more, remember dummys at the top */
  6147             sigemptyset(&act.sa_mask);
  6147 	    sigemptyset(&act.sa_mask);
  6148             act.sa_handler = handler;
  6148 	    act.sa_handler = handler;
  6149             sigaction(sigNr, &act, 0);
  6149 	    sigaction(sigNr, &act, 0);
  6150 #else
  6150 #else
  6151 # ifdef HAS_SIGVEC
  6151 # ifdef HAS_SIGVEC
  6152             struct sigvec vec;
  6152 	    struct sigvec vec;
  6153 
  6153 
  6154             vec.sv_flags = SV_INTERRUPT;
  6154 	    vec.sv_flags = SV_INTERRUPT;
  6155             sigemptyset(&vec.sv_mask);
  6155 	    sigemptyset(&vec.sv_mask);
  6156             vec.sv_handler = handler;
  6156 	    vec.sv_handler = handler;
  6157             sigvec(sigNr, &vec, NULL);
  6157 	    sigvec(sigNr, &vec, NULL);
  6158 # else
  6158 # else
  6159             (void) signal(sigNr, handler);
  6159 	    (void) signal(sigNr, handler);
  6160 # endif
  6160 # endif
  6161 #endif
  6161 #endif
  6162         }
  6162 	}
  6163 
  6163 
  6164         /*
  6164 	/*
  6165          * maybe, we should ret the old enable-status
  6165 	 * maybe, we should ret the old enable-status
  6166          * as boolean here ...
  6166 	 * as boolean here ...
  6167          */
  6167 	 */
  6168         RETURN (self);
  6168 	RETURN (self);
  6169     }
  6169     }
  6170 %}.
  6170 %}.
  6171 
  6171 
  6172     "
  6172     "
  6173      this error is triggered on non-integer argument, or
  6173      this error is triggered on non-integer argument, or
  6184 
  6184 
  6185     millis = __intVal(milliSeconds);
  6185     millis = __intVal(milliSeconds);
  6186 
  6186 
  6187 #ifdef SIGALRM
  6187 #ifdef SIGALRM
  6188     {
  6188     {
  6189         static int firstCall = 1;
  6189 	static int firstCall = 1;
  6190 # ifndef __signalTimerInterrupt
  6190 # ifndef __signalTimerInterrupt
  6191         extern void __signalTimerInterrupt(SIGHANDLER_ARG);
  6191 	extern void __signalTimerInterrupt(SIGHANDLER_ARG);
  6192 # endif
  6192 # endif
  6193 
  6193 
  6194         if (firstCall) {
  6194 	if (firstCall) {
  6195 # ifdef HAS_SIGACTION
  6195 # ifdef HAS_SIGACTION
  6196             struct sigaction act;
  6196 	    struct sigaction act;
  6197 
  6197 
  6198             act.sa_flags = SA_SIGINFO; /* <- if you add more, remember dummys at the top */
  6198 	    act.sa_flags = SA_SIGINFO; /* <- if you add more, remember dummys at the top */
  6199             sigemptyset(&act.sa_mask);
  6199 	    sigemptyset(&act.sa_mask);
  6200             act.sa_handler = __signalTimerInterrupt;
  6200 	    act.sa_handler = __signalTimerInterrupt;
  6201             sigaction(SIGALRM, &act, 0);
  6201 	    sigaction(SIGALRM, &act, 0);
  6202 # else
  6202 # else
  6203 #  ifdef HAS_SIGVEC
  6203 #  ifdef HAS_SIGVEC
  6204             struct sigvec vec;
  6204 	    struct sigvec vec;
  6205 
  6205 
  6206             vec.sv_flags = SV_INTERRUPT;
  6206 	    vec.sv_flags = SV_INTERRUPT;
  6207             sigemptyset(&vec.sv_mask);
  6207 	    sigemptyset(&vec.sv_mask);
  6208             vec.sv_handler = __signalTimerInterrupt;
  6208 	    vec.sv_handler = __signalTimerInterrupt;
  6209             sigvec(SIGALRM, &vec, NULL);
  6209 	    sigvec(SIGALRM, &vec, NULL);
  6210 #  else /* neither SIGACTION nor SIGVEC */
  6210 #  else /* neither SIGACTION nor SIGVEC */
  6211             signal(SIGALRM, __signalTimerInterrupt);
  6211 	    signal(SIGALRM, __signalTimerInterrupt);
  6212 #  endif /* stupid system  */
  6212 #  endif /* stupid system  */
  6213 # endif
  6213 # endif
  6214             firstCall = 0;
  6214 	    firstCall = 0;
  6215         }
  6215 	}
  6216     }
  6216     }
  6217 #endif /* SIGALRM */
  6217 #endif /* SIGALRM */
  6218 
  6218 
  6219 
  6219 
  6220 #if defined(ITIMER_REAL) && !defined(NO_SETITIMER)
  6220 #if defined(ITIMER_REAL) && !defined(NO_SETITIMER)
  6221     {
  6221     {
  6222         struct itimerval dt;
  6222 	struct itimerval dt;
  6223 
  6223 
  6224         dt.it_interval.tv_sec = 0;
  6224 	dt.it_interval.tv_sec = 0;
  6225         dt.it_interval.tv_usec = 0;
  6225 	dt.it_interval.tv_usec = 0;
  6226         dt.it_value.tv_sec = millis / 1000;
  6226 	dt.it_value.tv_sec = millis / 1000;
  6227         dt.it_value.tv_usec = (millis % 1000) * 1000;
  6227 	dt.it_value.tv_usec = (millis % 1000) * 1000;
  6228         setitimer(ITIMER_REAL, &dt, 0);
  6228 	setitimer(ITIMER_REAL, &dt, 0);
  6229         RETURN (true);
  6229 	RETURN (true);
  6230     }
  6230     }
  6231 #else /* no ITIMER_REAL */
  6231 #else /* no ITIMER_REAL */
  6232 
  6232 
  6233 # ifdef USE_SLOW_ALARM
  6233 # ifdef USE_SLOW_ALARM
  6234     {
  6234     {
  6235         /*
  6235 	/*
  6236          * last fallback - use alarm (which only gives 1 second resolution).
  6236 	 * last fallback - use alarm (which only gives 1 second resolution).
  6237          * If the system does not support any of the above, you have to life
  6237 	 * If the system does not support any of the above, you have to life
  6238          * with this. The consequence is that pressing CTRL-C processing and
  6238 	 * with this. The consequence is that pressing CTRL-C processing and
  6239          * thread switching will take place much delayed.
  6239 	 * thread switching will take place much delayed.
  6240          */
  6240 	 */
  6241         alarm(1);
  6241 	alarm(1);
  6242         RETURN(true);
  6242 	RETURN(true);
  6243     }
  6243     }
  6244 # endif
  6244 # endif
  6245 #endif /* ITIMER_REAL */
  6245 #endif /* ITIMER_REAL */
  6246 %}.
  6246 %}.
  6247     ^ false
  6247     ^ false
  6259 killProcess:processId
  6259 killProcess:processId
  6260     "kill a unix process.
  6260     "kill a unix process.
  6261      The process has a no chance to do some cleanup.
  6261      The process has a no chance to do some cleanup.
  6262 
  6262 
  6263      WARNING: in order to avoid zombie processes (on unix),
  6263      WARNING: in order to avoid zombie processes (on unix),
  6264               you may have to fetch the processes exitstatus with
  6264 	      you may have to fetch the processes exitstatus with
  6265               OperatingSystem>>getStatusOfProcess:aProcessId."
  6265 	      OperatingSystem>>getStatusOfProcess:aProcessId."
  6266 
  6266 
  6267     self sendSignal:(self sigKILL) to:processId.
  6267     self sendSignal:(self sigKILL) to:processId.
  6268 
  6268 
  6269     "Modified: / 10.6.1998 / 11:59:12 / cg"
  6269     "Modified: / 10.6.1998 / 11:59:12 / cg"
  6270 !
  6270 !
  6272 killProcessGroup:processGroupId
  6272 killProcessGroup:processGroupId
  6273     "kill a unix process group.
  6273     "kill a unix process group.
  6274      The process has a no chance to do some cleanup.
  6274      The process has a no chance to do some cleanup.
  6275 
  6275 
  6276      WARNING: in order to avoid zombie processes (on unix),
  6276      WARNING: in order to avoid zombie processes (on unix),
  6277               you may have to fetch the processes exitstatus with
  6277 	      you may have to fetch the processes exitstatus with
  6278               OperatingSystem>>getStatusOfProcess:aProcessId."
  6278 	      OperatingSystem>>getStatusOfProcess:aProcessId."
  6279 
  6279 
  6280     self sendSignal:(self sigKILL) to:(processGroupId negated).
  6280     self sendSignal:(self sigKILL) to:(processGroupId negated).
  6281 
  6281 
  6282     "Created: / 10.6.1998 / 11:59:29 / cg"
  6282     "Created: / 10.6.1998 / 11:59:29 / cg"
  6283 !
  6283 !
  6287      Returns false if any error occurred, true otherwise.
  6287      Returns false if any error occurred, true otherwise.
  6288 
  6288 
  6289      Do not confuse UNIX signals with Smalltalk-Signals.
  6289      Do not confuse UNIX signals with Smalltalk-Signals.
  6290 
  6290 
  6291      WARNING: in order to avoid zombie processes (on unix),
  6291      WARNING: in order to avoid zombie processes (on unix),
  6292               you may have to fetch the processes exitstatus with
  6292 	      you may have to fetch the processes exitstatus with
  6293               OperatingSystem>>getStatusOfProcess:aProcessId
  6293 	      OperatingSystem>>getStatusOfProcess:aProcessId
  6294               if the signal terminates that process."
  6294 	      if the signal terminates that process."
  6295 
  6295 
  6296 %{
  6296 %{
  6297     if (__bothSmallInteger(signalNumber, processId)) {
  6297     if (__bothSmallInteger(signalNumber, processId)) {
  6298         if (kill(__intVal(processId), __intVal(signalNumber)) < 0) {
  6298 	if (kill(__intVal(processId), __intVal(signalNumber)) < 0) {
  6299             @global(LastErrorNumber) = __mkSmallInteger(errno);
  6299 	    @global(LastErrorNumber) = __mkSmallInteger(errno);
  6300             RETURN ( false );
  6300 	    RETURN ( false );
  6301         }
  6301 	}
  6302         RETURN ( true );
  6302 	RETURN ( true );
  6303     }
  6303     }
  6304 %}.
  6304 %}.
  6305     "/
  6305     "/
  6306     "/ either invalid argument (non-integers)
  6306     "/ either invalid argument (non-integers)
  6307     "/ or not supported by OS
  6307     "/ or not supported by OS
  6314      This is used by the old MessageTally for profiling.
  6314      This is used by the old MessageTally for profiling.
  6315      Should be changed to use real profiling timer if available.
  6315      Should be changed to use real profiling timer if available.
  6316      On systems, where no virtual timer is available, use the real timer
  6316      On systems, where no virtual timer is available, use the real timer
  6317      (which is of course less correct).
  6317      (which is of course less correct).
  6318      OBSOLETE: the new messageTally runs as a high prio process, not using
  6318      OBSOLETE: the new messageTally runs as a high prio process, not using
  6319                spy interrupts."
  6319 	       spy interrupts."
  6320 
  6320 
  6321 %{  /* NOCONTEXT */
  6321 %{  /* NOCONTEXT */
  6322 
  6322 
  6323 #ifndef __spyInterrupt
  6323 #ifndef __spyInterrupt
  6324     extern void __spyInterrupt();
  6324     extern void __spyInterrupt();
  6353 !
  6353 !
  6354 
  6354 
  6355 stopSpyTimer
  6355 stopSpyTimer
  6356     "stop spy timing - disable spy timer.
  6356     "stop spy timing - disable spy timer.
  6357      OBSOLETE: the new messageTally runs as a high prio process, not using
  6357      OBSOLETE: the new messageTally runs as a high prio process, not using
  6358                spy interrupts."
  6358 	       spy interrupts."
  6359 
  6359 
  6360 %{  /* NOCONTEXT */
  6360 %{  /* NOCONTEXT */
  6361 
  6361 
  6362 #if defined(ITIMER_VIRTUAL) && !defined(NO_SETITIMER)
  6362 #if defined(ITIMER_VIRTUAL) && !defined(NO_SETITIMER)
  6363     struct itimerval dt;
  6363     struct itimerval dt;
  6376 terminateProcess:processId
  6376 terminateProcess:processId
  6377     "terminate a unix process.
  6377     "terminate a unix process.
  6378      The process has a chance to do some cleanup.
  6378      The process has a chance to do some cleanup.
  6379 
  6379 
  6380      WARNING: in order to avoid zombie processes (on unix),
  6380      WARNING: in order to avoid zombie processes (on unix),
  6381               you may have to fetch the processes exitstatus with
  6381 	      you may have to fetch the processes exitstatus with
  6382               OperatingSystem>>getStatusOfProcess:aProcessId."
  6382 	      OperatingSystem>>getStatusOfProcess:aProcessId."
  6383 
  6383 
  6384     self sendSignal:(self sigTERM) to:processId.
  6384     self sendSignal:(self sigTERM) to:processId.
  6385 
  6385 
  6386     "Modified: / 28.12.1995 / 15:05:37 / stefan"
  6386     "Modified: / 28.12.1995 / 15:05:37 / stefan"
  6387     "Modified: / 27.1.1998 / 20:05:47 / cg"
  6387     "Modified: / 27.1.1998 / 20:05:47 / cg"
  6390 terminateProcessGroup:processGroupId
  6390 terminateProcessGroup:processGroupId
  6391     "terminate a unix process group.
  6391     "terminate a unix process group.
  6392      The process has a chance to do some cleanup.
  6392      The process has a chance to do some cleanup.
  6393 
  6393 
  6394      WARNING: in order to avoid zombie processes (on unix),
  6394      WARNING: in order to avoid zombie processes (on unix),
  6395               you may have to fetch the processes exitstatus with
  6395 	      you may have to fetch the processes exitstatus with
  6396               OperatingSystem>>getStatusOfProcess:aProcessId."
  6396 	      OperatingSystem>>getStatusOfProcess:aProcessId."
  6397 
  6397 
  6398     self sendSignal:(self sigTERM) to:(processGroupId negated).
  6398     self sendSignal:(self sigTERM) to:(processGroupId negated).
  6399 
  6399 
  6400     "Modified: / 28.12.1995 / 15:05:37 / stefan"
  6400     "Modified: / 28.12.1995 / 15:05:37 / stefan"
  6401     "Created: / 23.4.1996 / 16:40:34 / stefan"
  6401     "Created: / 23.4.1996 / 16:40:34 / stefan"
  6414 %{
  6414 %{
  6415 #ifndef NO_SOCKET
  6415 #ifndef NO_SOCKET
  6416      int fds[2];
  6416      int fds[2];
  6417 
  6417 
  6418      if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
  6418      if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
  6419         @global(LastErrorNumber) = __mkSmallInteger(errno);
  6419 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  6420         RETURN ( nil );
  6420 	RETURN ( nil );
  6421      }
  6421      }
  6422 
  6422 
  6423      fd1 = __mkSmallInteger(fds[0]);
  6423      fd1 = __mkSmallInteger(fds[0]);
  6424      fd2 = __mkSmallInteger(fds[1]);
  6424      fd2 = __mkSmallInteger(fds[1]);
  6425 #endif
  6425 #endif
  6426 %}.
  6426 %}.
  6427     fd1 notNil ifTrue:[
  6427     fd1 notNil ifTrue:[
  6428         ^ Array with:fd1 with:fd2.
  6428 	^ Array with:fd1 with:fd2.
  6429     ].
  6429     ].
  6430     ^ nil
  6430     ^ nil
  6431 !
  6431 !
  6432 
  6432 
  6433 makePTY
  6433 makePTY
  6450     int _fdM, _fdS;
  6450     int _fdM, _fdS;
  6451     char *slaveName;
  6451     char *slaveName;
  6452 
  6452 
  6453     slaveName = _getpty(&_fdM, O_RDWR|O_NDELAY, 0600, 0);
  6453     slaveName = _getpty(&_fdM, O_RDWR|O_NDELAY, 0600, 0);
  6454     if ((slaveName != 0) && (_fdM >= 0)) {
  6454     if ((slaveName != 0) && (_fdM >= 0)) {
  6455         _fdS = open(slaveName, O_RDWR);
  6455 	_fdS = open(slaveName, O_RDWR);
  6456         if (_fdS < 0) {
  6456 	if (_fdS < 0) {
  6457             (void)close(_fdM);
  6457 	    (void)close(_fdM);
  6458             _fdS = _fdM = -1;
  6458 	    _fdS = _fdM = -1;
  6459         }
  6459 	}
  6460     } else {
  6460     } else {
  6461         _fdM -1;
  6461 	_fdM -1;
  6462     }
  6462     }
  6463     if ((_fdM >= 0) && (_fdS >= 0)) {
  6463     if ((_fdM >= 0) && (_fdS >= 0)) {
  6464         fdM = __mkSmallInteger(_fdM);
  6464 	fdM = __mkSmallInteger(_fdM);
  6465         fdS = __mkSmallInteger(_fdS);
  6465 	fdS = __mkSmallInteger(_fdS);
  6466         ptyName = __MKSTRING(slaveName);
  6466 	ptyName = __MKSTRING(slaveName);
  6467     }
  6467     }
  6468 #   define PTY_IS_IMPLEMENTED 1
  6468 #   define PTY_IS_IMPLEMENTED 1
  6469 #endif /* IRIX5 */
  6469 #endif /* IRIX5 */
  6470 
  6470 
  6471 
  6471 
  6475     extern char *ptsname();     /* also in #include <stdlib.h> */
  6475     extern char *ptsname();     /* also in #include <stdlib.h> */
  6476 
  6476 
  6477     _fdM = open("/dev/ptmx", O_RDWR | O_NOCTTY);
  6477     _fdM = open("/dev/ptmx", O_RDWR | O_NOCTTY);
  6478 
  6478 
  6479     if (_fdM >= 0) {
  6479     if (_fdM >= 0) {
  6480         /*
  6480 	/*
  6481         ** grantpt() changes owner, group and mode of the pseudo-tty
  6481 	** grantpt() changes owner, group and mode of the pseudo-tty
  6482         */
  6482 	*/
  6483         grantpt(_fdM);
  6483 	grantpt(_fdM);
  6484         unlockpt(_fdM);
  6484 	unlockpt(_fdM);
  6485         slaveName = ptsname(_fdM);
  6485 	slaveName = ptsname(_fdM);
  6486 
  6486 
  6487         if (slaveName != NULL) {
  6487 	if (slaveName != NULL) {
  6488             /* printf("slave is: %s\n", slaveName); */
  6488 	    /* printf("slave is: %s\n", slaveName); */
  6489             _fdS = open(slaveName, O_RDWR);
  6489 	    _fdS = open(slaveName, O_RDWR);
  6490             if (_fdS < 0) {
  6490 	    if (_fdS < 0) {
  6491                 (void)close(_fdM);
  6491 		(void)close(_fdM);
  6492                 _fdS = _fdM = -1;
  6492 		_fdS = _fdM = -1;
  6493             }
  6493 	    }
  6494 #if defined(UNIXWARE) || defined(solaris)
  6494 #if defined(UNIXWARE) || defined(solaris)
  6495             else {
  6495 	    else {
  6496                 /* push terminal modules on stream */
  6496 		/* push terminal modules on stream */
  6497                 ioctl(_fdS, I_PUSH, "ptem");
  6497 		ioctl(_fdS, I_PUSH, "ptem");
  6498                 ioctl(_fdS, I_PUSH, "ldterm");
  6498 		ioctl(_fdS, I_PUSH, "ldterm");
  6499             }
  6499 	    }
  6500 #endif
  6500 #endif
  6501         } else {
  6501 	} else {
  6502             (void)close(_fdM);
  6502 	    (void)close(_fdM);
  6503             _fdS = _fdM = -1;
  6503 	    _fdS = _fdM = -1;
  6504         }
  6504 	}
  6505     }
  6505     }
  6506 
  6506 
  6507     if ((_fdM >= 0) && (_fdS >= 0)) {
  6507     if ((_fdM >= 0) && (_fdS >= 0)) {
  6508         fdM = __mkSmallInteger(_fdM);
  6508 	fdM = __mkSmallInteger(_fdM);
  6509         fdS = __mkSmallInteger(_fdS);
  6509 	fdS = __mkSmallInteger(_fdS);
  6510         ptyName = __MKSTRING(slaveName);
  6510 	ptyName = __MKSTRING(slaveName);
  6511     }
  6511     }
  6512 #   define PTY_IS_IMPLEMENTED 1
  6512 #   define PTY_IS_IMPLEMENTED 1
  6513 #endif /* HAS_UNIX98_PTY */
  6513 #endif /* HAS_UNIX98_PTY */
  6514 
  6514 
  6515 #if !defined(PTY_IS_IMPLEMENTED)
  6515 #if !defined(PTY_IS_IMPLEMENTED)
  6573 
  6573 
  6574     len = sizeof(PTY_TEMPL) - 1;
  6574     len = sizeof(PTY_TEMPL) - 1;
  6575     strncpy(line, PTY_TEMPL, sizeof(PTY_TEMPL));
  6575     strncpy(line, PTY_TEMPL, sizeof(PTY_TEMPL));
  6576 
  6576 
  6577     if (ttygid == -2) {
  6577     if (ttygid == -2) {
  6578         struct group *gr;
  6578 	struct group *gr;
  6579 
  6579 
  6580         if ((gr = getgrnam("tty")) != NULL)
  6580 	if ((gr = getgrnam("tty")) != NULL)
  6581             ttygid = gr->gr_gid;
  6581 	    ttygid = gr->gr_gid;
  6582         else
  6582 	else
  6583             ttygid = -1;
  6583 	    ttygid = -1;
  6584     }
  6584     }
  6585 
  6585 
  6586     for (cp1 = PTY_1_CHARS; *cp1; cp1++) {
  6586     for (cp1 = PTY_1_CHARS; *cp1; cp1++) {
  6587         line[len-2] = * cp1;
  6587 	line[len-2] = * cp1;
  6588 
  6588 
  6589         for( cp2 = PTY_2_CHARS; *cp2; cp2++ ) {
  6589 	for( cp2 = PTY_2_CHARS; *cp2; cp2++ ) {
  6590             line[PT_INDEX] = 'p';
  6590 	    line[PT_INDEX] = 'p';
  6591             line[len-1] = *cp2;
  6591 	    line[len-1] = *cp2;
  6592 
  6592 
  6593             if ((_fdM = open(line, O_RDWR, 0)) < 0) {
  6593 	    if ((_fdM = open(line, O_RDWR, 0)) < 0) {
  6594                 if (errno == ENOENT) {
  6594 		if (errno == ENOENT) {
  6595                     _fdM = _fdS = -1;
  6595 		    _fdM = _fdS = -1;
  6596                     goto getOutOfHere; /* out of ptys */
  6596 		    goto getOutOfHere; /* out of ptys */
  6597                 }
  6597 		}
  6598             } else {
  6598 	    } else {
  6599                 line[PT_INDEX] = 't';
  6599 		line[PT_INDEX] = 't';
  6600 
  6600 
  6601                 /*
  6601 		/*
  6602                  * try to set owner and mode.
  6602 		 * try to set owner and mode.
  6603                  * this works only if running under root
  6603 		 * this works only if running under root
  6604                  */
  6604 		 */
  6605                 (void) chown( line, getuid(), ttygid );
  6605 		(void) chown( line, getuid(), ttygid );
  6606                 (void) chmod( line, S_IRUSR | S_IWUSR | S_IWGRP );
  6606 		(void) chmod( line, S_IRUSR | S_IWUSR | S_IWGRP );
  6607 
  6607 
  6608                 if( (_fdS = open(line, O_RDWR, 0)) >= 0 ) {
  6608 		if( (_fdS = open(line, O_RDWR, 0)) >= 0 ) {
  6609                     slaveName = line;
  6609 		    slaveName = line;
  6610                     goto getOutOfHere; /* success */
  6610 		    goto getOutOfHere; /* success */
  6611                 }
  6611 		}
  6612                 (void) close(_fdM );
  6612 		(void) close(_fdM );
  6613             }
  6613 	    }
  6614         }
  6614 	}
  6615     }
  6615     }
  6616   getOutOfHere: ;
  6616   getOutOfHere: ;
  6617 
  6617 
  6618     if ((_fdM >= 0) && (_fdS >= 0)) {
  6618     if ((_fdM >= 0) && (_fdS >= 0)) {
  6619         fdM = __mkSmallInteger(_fdM);
  6619 	fdM = __mkSmallInteger(_fdM);
  6620         fdS = __mkSmallInteger(_fdS);
  6620 	fdS = __mkSmallInteger(_fdS);
  6621         ptyName = __MKSTRING(slaveName);
  6621 	ptyName = __MKSTRING(slaveName);
  6622     }
  6622     }
  6623 
  6623 
  6624 #endif /* ! defined(PTY_IS_IMPLEMENTED) */
  6624 #endif /* ! defined(PTY_IS_IMPLEMENTED) */
  6625 %}.
  6625 %}.
  6626 
  6626 
  6627     fdM notNil ifTrue:[
  6627     fdM notNil ifTrue:[
  6628         ^ Array with:fdM with:fdS with:ptyName.
  6628 	^ Array with:fdM with:fdS with:ptyName.
  6629     ].
  6629     ].
  6630 
  6630 
  6631     ^ nil
  6631     ^ nil
  6632 !
  6632 !
  6633 
  6633 
  6655 
  6655 
  6656 %{
  6656 %{
  6657      int fds[2];
  6657      int fds[2];
  6658 
  6658 
  6659      if (pipe(fds) < 0) {
  6659      if (pipe(fds) < 0) {
  6660         @global(LastErrorNumber) = __mkSmallInteger(errno);
  6660 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  6661         RETURN ( nil );
  6661 	RETURN ( nil );
  6662      }
  6662      }
  6663 
  6663 
  6664      fd1 = __mkSmallInteger(fds[0]);
  6664      fd1 = __mkSmallInteger(fds[0]);
  6665      fd2 = __mkSmallInteger(fds[1]);
  6665      fd2 = __mkSmallInteger(fds[1]);
  6666 %}.
  6666 %}.
  6667     fd1 notNil ifTrue:[
  6667     fd1 notNil ifTrue:[
  6668         ^ Array with:fd1 with:fd2.
  6668 	^ Array with:fd1 with:fd2.
  6669     ].
  6669     ].
  6670     ^ nil
  6670     ^ nil
  6671 !
  6671 !
  6672 
  6672 
  6673 resetTerminalInputOutputModes:fd
  6673 resetTerminalInputOutputModes:fd
  6675 %{
  6675 %{
  6676     struct termios switcher;
  6676     struct termios switcher;
  6677 
  6677 
  6678     printf("setMappingMaster fd:%d\n", (int)__intVal(fd));
  6678     printf("setMappingMaster fd:%d\n", (int)__intVal(fd));
  6679     if (__isSmallInteger(fd)) {
  6679     if (__isSmallInteger(fd)) {
  6680         if (tcgetattr( __intVal(fd), &switcher) < 0) RETURN (false);
  6680 	if (tcgetattr( __intVal(fd), &switcher) < 0) RETURN (false);
  6681         switcher.c_iflag = 0;
  6681 	switcher.c_iflag = 0;
  6682         switcher.c_oflag = 0;
  6682 	switcher.c_oflag = 0;
  6683         if (tcsetattr( __intVal(fd), TCSANOW, &switcher) >= 0) {
  6683 	if (tcsetattr( __intVal(fd), TCSANOW, &switcher) >= 0) {
  6684             RETURN (true);
  6684 	    RETURN (true);
  6685         }
  6685 	}
  6686     }
  6686     }
  6687 %}.
  6687 %}.
  6688     ^ false
  6688     ^ false
  6689 !
  6689 !
  6690 
  6690 
  6695     struct winsize wsize;
  6695     struct winsize wsize;
  6696 
  6696 
  6697     if (__isSmallInteger(fd)
  6697     if (__isSmallInteger(fd)
  6698      && __isSmallInteger(w)
  6698      && __isSmallInteger(w)
  6699      && __isSmallInteger(h)) {
  6699      && __isSmallInteger(h)) {
  6700         wsize.ws_row = (unsigned short)__intVal(h);
  6700 	wsize.ws_row = (unsigned short)__intVal(h);
  6701         wsize.ws_col = (unsigned short)__intVal(w);
  6701 	wsize.ws_col = (unsigned short)__intVal(w);
  6702         if (ioctl(__intVal(fd), TIOCSWINSZ, (char *)&wsize) >= 0) {
  6702 	if (ioctl(__intVal(fd), TIOCSWINSZ, (char *)&wsize) >= 0) {
  6703             RETURN (true);
  6703 	    RETURN (true);
  6704         }
  6704 	}
  6705     }
  6705     }
  6706 #endif
  6706 #endif
  6707 %}.
  6707 %}.
  6708     ^ false
  6708     ^ false
  6709 !
  6709 !
  6713      we will send no more data to the pipe, i.e. EOF is reached"
  6713      we will send no more data to the pipe, i.e. EOF is reached"
  6714 
  6714 
  6715 %{
  6715 %{
  6716 #ifndef NO_SOCKET
  6716 #ifndef NO_SOCKET
  6717     if (__isSmallInteger(fileDescriptor)) {
  6717     if (__isSmallInteger(fileDescriptor)) {
  6718         shutdown(__smallIntegerVal(fileDescriptor), 1);
  6718 	shutdown(__smallIntegerVal(fileDescriptor), 1);
  6719         RETURN(self);
  6719 	RETURN(self);
  6720     }
  6720     }
  6721 #endif
  6721 #endif
  6722 %}.
  6722 %}.
  6723     self primitiveFailed
  6723     self primitiveFailed
  6724 ! !
  6724 ! !
  6726 !UnixOperatingSystem class methodsFor:'misc'!
  6726 !UnixOperatingSystem class methodsFor:'misc'!
  6727 
  6727 
  6728 closeLeftOverFiles
  6728 closeLeftOverFiles
  6729     "a bad bad kludge and workaround for a big bug in the linux
  6729     "a bad bad kludge and workaround for a big bug in the linux
  6730      getAddrInfo implementation:
  6730      getAddrInfo implementation:
  6731         if it gets interrupted (via a timer, for example), its domain-name
  6731 	if it gets interrupted (via a timer, for example), its domain-name
  6732         socket remains open and is NEVER closed.
  6732 	socket remains open and is NEVER closed.
  6733         These open files collect up and lead to no-more-files eventually.
  6733 	These open files collect up and lead to no-more-files eventually.
  6734      Invoking this method helps in this situation."
  6734      Invoking this method helps in this situation."
  6735 
  6735 
  6736     |p|
  6736     |p|
  6737 
  6737 
  6738     p := PipeStream
  6738     p := PipeStream
  6739             readingFrom:('lsof -p ' , (OperatingSystem getProcessId printString)).
  6739 	    readingFrom:('lsof -p ' , (OperatingSystem getProcessId printString)).
  6740 
  6740 
  6741     p linesDo:[:line |
  6741     p linesDo:[:line |
  6742         |words fd|
  6742 	|words fd|
  6743 
  6743 
  6744         words := line asCollectionOfWords.
  6744 	words := line asCollectionOfWords.
  6745         "/ COMMAND PID USER   FD   TYPE     DEVICE    SIZE    NODE NAME
  6745 	"/ COMMAND PID USER   FD   TYPE     DEVICE    SIZE    NODE NAME
  6746         words first = 'stx' ifTrue:[
  6746 	words first = 'stx' ifTrue:[
  6747             words second = (OperatingSystem getProcessId printString) ifTrue:[
  6747 	    words second = (OperatingSystem getProcessId printString) ifTrue:[
  6748                 (words fourth endsWith:'u') ifTrue:[
  6748 		(words fourth endsWith:'u') ifTrue:[
  6749                     (words fifth = 'IPv4') ifTrue:[
  6749 		    (words fifth = 'IPv4') ifTrue:[
  6750                         (words seventh = 'UDP') ifTrue:[
  6750 			(words seventh = 'UDP') ifTrue:[
  6751                             (words last endsWith:'domain') ifTrue:[
  6751 			    (words last endsWith:'domain') ifTrue:[
  6752                                 fd := Number readFrom:(words fourth copyButLast).
  6752 				fd := Number readFrom:(words fourth copyButLast).
  6753 Transcript showCR:line.
  6753 Transcript showCR:line.
  6754                                 OperatingSystem closeFd:fd.
  6754 				OperatingSystem closeFd:fd.
  6755                             ]
  6755 			    ]
  6756                         ]
  6756 			]
  6757                     ]
  6757 		    ]
  6758                 ]
  6758 		]
  6759             ]
  6759 	    ]
  6760         ]
  6760 	]
  6761     ].
  6761     ].
  6762     p close.
  6762     p close.
  6763 
  6763 
  6764     "
  6764     "
  6765      self closeLeftOverFiles
  6765      self closeLeftOverFiles
  6772 
  6772 
  6773 %{
  6773 %{
  6774     int dupFd;
  6774     int dupFd;
  6775 
  6775 
  6776     if (__isSmallInteger(aFileDescriptor)) {
  6776     if (__isSmallInteger(aFileDescriptor)) {
  6777         dupFd = dup(__smallIntegerVal(aFileDescriptor));
  6777 	dupFd = dup(__smallIntegerVal(aFileDescriptor));
  6778         if (dupFd >= 0) {
  6778 	if (dupFd >= 0) {
  6779             RETURN(__mkSmallInteger(dupFd));
  6779 	    RETURN(__mkSmallInteger(dupFd));
  6780         }
  6780 	}
  6781     }
  6781     }
  6782 %}.
  6782 %}.
  6783     ^ self primitiveFailed.
  6783     ^ self primitiveFailed.
  6784 !
  6784 !
  6785 
  6785 
  6830 !
  6830 !
  6831 
  6831 
  6832 getDomainName
  6832 getDomainName
  6833     "return the domain this host is in.
  6833     "return the domain this host is in.
  6834      Notice:
  6834      Notice:
  6835         not all systems support this; on some, #unknown is returned."
  6835 	not all systems support this; on some, #unknown is returned."
  6836 
  6836 
  6837     |domainName idx hostName primDomainName|
  6837     |domainName idx hostName primDomainName|
  6838 
  6838 
  6839     "/ use cached value, if present
  6839     "/ use cached value, if present
  6840     (DomainName notNil and:[DomainName ~~ #unknown]) ifTrue:[
  6840     (DomainName notNil and:[DomainName ~~ #unknown]) ifTrue:[
  6841         ^ DomainName
  6841 	^ DomainName
  6842     ].
  6842     ].
  6843 
  6843 
  6844     primDomainName := domainName := self primGetDomainName.
  6844     primDomainName := domainName := self primGetDomainName.
  6845     domainName = '(none)' ifTrue:[
  6845     domainName = '(none)' ifTrue:[
  6846         domainName := nil.
  6846 	domainName := nil.
  6847     ].
  6847     ].
  6848     domainName isEmptyOrNil ifTrue:[
  6848     domainName isEmptyOrNil ifTrue:[
  6849         "sometimes, we can extract the domainName from the hostName ..."
  6849 	"sometimes, we can extract the domainName from the hostName ..."
  6850         hostName := self primGetHostName.
  6850 	hostName := self primGetHostName.
  6851         hostName notNil ifTrue:[
  6851 	hostName notNil ifTrue:[
  6852             idx := hostName indexOf:$..
  6852 	    idx := hostName indexOf:$..
  6853             idx ~~ 0 ifTrue:[
  6853 	    idx ~~ 0 ifTrue:[
  6854                 domainName := hostName copyFrom:idx+1.
  6854 		domainName := hostName copyFrom:idx+1.
  6855             ]
  6855 	    ]
  6856         ].
  6856 	].
  6857         domainName isEmptyOrNil ifTrue:[
  6857 	domainName isEmptyOrNil ifTrue:[
  6858             "/ fallBack
  6858 	    "/ fallBack
  6859             domainName := self getEnvironment:'DOMAIN'.
  6859 	    domainName := self getEnvironment:'DOMAIN'.
  6860 
  6860 
  6861             "if #primGetDomainName did work, /bin/domainname would return the same result"
  6861 	    "if #primGetDomainName did work, /bin/domainname would return the same result"
  6862             (domainName isNil and:[primDomainName isNil]) ifTrue:[
  6862 	    (domainName isNil and:[primDomainName isNil]) ifTrue:[
  6863                 domainName := self getCommandOutputFrom:'/bin/domainname'.
  6863 		domainName := self getCommandOutputFrom:'/bin/domainname'.
  6864                 (domainName isEmptyOrNil or:[ domainName = '(none)' ]) ifTrue:[
  6864 		(domainName isEmptyOrNil or:[ domainName = '(none)' ]) ifTrue:[
  6865                     domainName := nil.
  6865 		    domainName := nil.
  6866                 ].
  6866 		].
  6867             ].
  6867 	    ].
  6868             domainName isNil ifTrue:[
  6868 	    domainName isNil ifTrue:[
  6869                 DomainName ~~ #unknown ifTrue:[
  6869 		DomainName ~~ #unknown ifTrue:[
  6870                     "/ only warn once - the warning can be ignored, if you do not use the domain name
  6870 		    "/ only warn once - the warning can be ignored, if you do not use the domain name
  6871                     ObjectMemory debugPrinting ifTrue:[
  6871 		    ObjectMemory debugPrinting ifTrue:[
  6872                         'UnixOperatingSystem [info]: cannot find out domainname' infoPrintCR.
  6872 			'UnixOperatingSystem [info]: cannot find out domainname' infoPrintCR.
  6873                     ].
  6873 		    ].
  6874                 ].
  6874 		].
  6875                 domainName := #unknown.
  6875 		domainName := #unknown.
  6876             ].
  6876 	    ].
  6877         ].
  6877 	].
  6878     ].
  6878     ].
  6879 
  6879 
  6880     "cache, because domainName fetching may be expensive;
  6880     "cache, because domainName fetching may be expensive;
  6881      but if unknown, it will be tried again"
  6881      but if unknown, it will be tried again"
  6882     DomainName := domainName.
  6882     DomainName := domainName.
  6908 
  6908 
  6909     /*
  6909     /*
  6910      * get the size of the environment
  6910      * get the size of the environment
  6911      */
  6911      */
  6912     if (environ) {
  6912     if (environ) {
  6913         for (env = environ; *env; env++) {
  6913 	for (env = environ; *env; env++) {
  6914             nEnv++;
  6914 	    nEnv++;
  6915         }
  6915 	}
  6916     }
  6916     }
  6917 
  6917 
  6918     /*
  6918     /*
  6919      * allcate an array for keys and values
  6919      * allcate an array for keys and values
  6920      */
  6920      */
  6921     resultArray = __ARRAY_NEW_INT(nEnv * 2);
  6921     resultArray = __ARRAY_NEW_INT(nEnv * 2);
  6922     if (resultArray == nil) {
  6922     if (resultArray == nil) {
  6923         error = @symbol(allocationFailure);
  6923 	error = @symbol(allocationFailure);
  6924         goto bad;
  6924 	goto bad;
  6925     }
  6925     }
  6926 
  6926 
  6927     if (environ) {
  6927     if (environ) {
  6928         int envIndex;
  6928 	int envIndex;
  6929 
  6929 
  6930         for (env = environ, envIndex = 0; *env; env++) {
  6930 	for (env = environ, envIndex = 0; *env; env++) {
  6931             OBJ t;
  6931 	    OBJ t;
  6932             char *separatorPtr;
  6932 	    char *separatorPtr;
  6933 
  6933 
  6934             separatorPtr = strchr(*env, '=');
  6934 	    separatorPtr = strchr(*env, '=');
  6935             t = __MKSTRING_L(*env, separatorPtr-*env);
  6935 	    t = __MKSTRING_L(*env, separatorPtr-*env);
  6936             __arrayVal(resultArray)[envIndex++] = t;
  6936 	    __arrayVal(resultArray)[envIndex++] = t;
  6937             __STORE(resultArray, t);
  6937 	    __STORE(resultArray, t);
  6938             if (separatorPtr == 0) {
  6938 	    if (separatorPtr == 0) {
  6939                 t = nil;
  6939 		t = nil;
  6940             } else {
  6940 	    } else {
  6941                 t = __MKSTRING(separatorPtr+1);
  6941 		t = __MKSTRING(separatorPtr+1);
  6942             }
  6942 	    }
  6943             __arrayVal(resultArray)[envIndex++] = t;
  6943 	    __arrayVal(resultArray)[envIndex++] = t;
  6944             __STORE(resultArray, t);
  6944 	    __STORE(resultArray, t);
  6945         }
  6945 	}
  6946     }
  6946     }
  6947 
  6947 
  6948 bad:;
  6948 bad:;
  6949 %}.
  6949 %}.
  6950     error notNil ifTrue:[
  6950     error notNil ifTrue:[
  6951         ^ self primitiveFailed:error.
  6951 	^ self primitiveFailed:error.
  6952     ].
  6952     ].
  6953 
  6953 
  6954     sz := resultArray size.
  6954     sz := resultArray size.
  6955     dict := Dictionary new:(sz // 2).
  6955     dict := Dictionary new:(sz // 2).
  6956     1 to:sz by:2 do:[:i |
  6956     1 to:sz by:2 do:[:i |
  6957         |key|
  6957 	|key|
  6958 
  6958 
  6959         key := resultArray at:i.
  6959 	key := resultArray at:i.
  6960         key notNil ifTrue:[
  6960 	key notNil ifTrue:[
  6961             "same behavior as getenv() - the first entry takes precedence"
  6961 	    "same behavior as getenv() - the first entry takes precedence"
  6962             (dict includesKey:key) ifFalse:[
  6962 	    (dict includesKey:key) ifFalse:[
  6963                 dict at:key put:(resultArray at:i+1)
  6963 		dict at:key put:(resultArray at:i+1)
  6964             ].
  6964 	    ].
  6965         ].
  6965 	].
  6966     ].
  6966     ].
  6967     ^ dict
  6967     ^ dict
  6968 
  6968 
  6969     "
  6969     "
  6970      OperatingSystem getEnvironment
  6970      OperatingSystem getEnvironment
  6977 %{  /* NOCONTEXT */
  6977 %{  /* NOCONTEXT */
  6978 
  6978 
  6979     extern char *getenv();
  6979     extern char *getenv();
  6980 
  6980 
  6981     if (__isStringLike(aStringOrSymbol)) {
  6981     if (__isStringLike(aStringOrSymbol)) {
  6982         char *env =  getenv(__stringVal(aStringOrSymbol));
  6982 	char *env =  getenv(__stringVal(aStringOrSymbol));
  6983         if (env) {
  6983 	if (env) {
  6984             RETURN ( __MKSTRING(env) );
  6984 	    RETURN ( __MKSTRING(env) );
  6985         }
  6985 	}
  6986         RETURN ( nil );
  6986 	RETURN ( nil );
  6987     }
  6987     }
  6988 %}.
  6988 %}.
  6989     ^ self primitiveFailed
  6989     ^ self primitiveFailed
  6990 
  6990 
  6991     "
  6991     "
  7003      The host name returned is fully qualified - if returned so by the system."
  7003      The host name returned is fully qualified - if returned so by the system."
  7004 
  7004 
  7005     |hostName|
  7005     |hostName|
  7006 
  7006 
  7007     (HostName notNil and:[HostName ~~ #unknown]) ifTrue:[
  7007     (HostName notNil and:[HostName ~~ #unknown]) ifTrue:[
  7008         ^ HostName
  7008 	^ HostName
  7009     ].
  7009     ].
  7010 
  7010 
  7011     hostName := self primGetHostName.
  7011     hostName := self primGetHostName.
  7012     hostName isNil ifTrue:[
  7012     hostName isNil ifTrue:[
  7013         "fallBack - in non-antique systes we never come here"
  7013 	"fallBack - in non-antique systes we never come here"
  7014         hostName := self getEnvironment:'HOST'.
  7014 	hostName := self getEnvironment:'HOST'.
  7015         hostName isNil ifTrue:[
  7015 	hostName isNil ifTrue:[
  7016             hostName := self getCommandOutputFrom:'/bin/hostname'
  7016 	    hostName := self getCommandOutputFrom:'/bin/hostname'
  7017         ].
  7017 	].
  7018         hostName isNil ifTrue:[
  7018 	hostName isNil ifTrue:[
  7019             HostName ~~ #unknown ifTrue:[
  7019 	    HostName ~~ #unknown ifTrue:[
  7020                 'UnixOperatingSystem [info]: cannot find out hostname' infoPrintCR.
  7020 		'UnixOperatingSystem [info]: cannot find out hostname' infoPrintCR.
  7021                 hostName := #unknown.
  7021 		hostName := #unknown.
  7022             ].
  7022 	    ].
  7023         ].
  7023 	].
  7024     ].
  7024     ].
  7025 
  7025 
  7026     "cache, because hostname fetching may be expensive;
  7026     "cache, because hostname fetching may be expensive;
  7027      but if unknown, it will be tried again"
  7027      but if unknown, it will be tried again"
  7028     HostName := hostName.
  7028     HostName := hostName.
  7036 
  7036 
  7037 getLocaleInfo
  7037 getLocaleInfo
  7038     "return a dictionary filled with values from the locale information;
  7038     "return a dictionary filled with values from the locale information;
  7039      Not all fields may be present, depending on the OS's setup and capabilities.
  7039      Not all fields may be present, depending on the OS's setup and capabilities.
  7040      Possible fields are:
  7040      Possible fields are:
  7041         decimalPoint                    <String>
  7041 	decimalPoint                    <String>
  7042 
  7042 
  7043         thousandsSep                    <String>
  7043 	thousandsSep                    <String>
  7044 
  7044 
  7045         internationalCurrencySymbol     <String>
  7045 	internationalCurrencySymbol     <String>
  7046 
  7046 
  7047         currencySymbol                  <String>
  7047 	currencySymbol                  <String>
  7048 
  7048 
  7049         monetaryDecimalPoint            <String>
  7049 	monetaryDecimalPoint            <String>
  7050 
  7050 
  7051         monetaryThousandsSeparator      <String>
  7051 	monetaryThousandsSeparator      <String>
  7052 
  7052 
  7053         positiveSign                    <String>
  7053 	positiveSign                    <String>
  7054 
  7054 
  7055         negativeSign                    <String>
  7055 	negativeSign                    <String>
  7056 
  7056 
  7057         internationalFractionalDigits   <Integer>
  7057 	internationalFractionalDigits   <Integer>
  7058 
  7058 
  7059         fractionalDigits                <Integer>
  7059 	fractionalDigits                <Integer>
  7060 
  7060 
  7061         positiveSignPrecedesCurrencySymbol      <Boolean>
  7061 	positiveSignPrecedesCurrencySymbol      <Boolean>
  7062 
  7062 
  7063         negativeSignPrecedesCurrencySymbol      <Boolean>
  7063 	negativeSignPrecedesCurrencySymbol      <Boolean>
  7064 
  7064 
  7065         positiveSignSeparatedBySpaceFromCurrencySymbol  <Boolean>
  7065 	positiveSignSeparatedBySpaceFromCurrencySymbol  <Boolean>
  7066 
  7066 
  7067         negativeSignSeparatedBySpaceFromCurrencySymbol  <Boolean>
  7067 	negativeSignSeparatedBySpaceFromCurrencySymbol  <Boolean>
  7068 
  7068 
  7069         positiveSignPosition                            <Symbol>
  7069 	positiveSignPosition                            <Symbol>
  7070                                                         one of: #parenthesesAround,
  7070 							one of: #parenthesesAround,
  7071                                                                 #signPrecedes,
  7071 								#signPrecedes,
  7072                                                                 #signSuceeds,
  7072 								#signSuceeds,
  7073                                                                 #signPrecedesCurrencySymbol,
  7073 								#signPrecedesCurrencySymbol,
  7074                                                                 #signSuceedsCurrencySymbol
  7074 								#signSuceedsCurrencySymbol
  7075 
  7075 
  7076         negativeSignPosition                            <like above>
  7076 	negativeSignPosition                            <like above>
  7077 
  7077 
  7078      it is up to the application to deal with undefined values.
  7078      it is up to the application to deal with undefined values.
  7079 
  7079 
  7080      Notice, that (for now), the system does not use this information;
  7080      Notice, that (for now), the system does not use this information;
  7081      it should be used by applications as required.
  7081      it should be used by applications as required.
  7082     "
  7082     "
  7083 
  7083 
  7084     |info val|
  7084     |info val|
  7085 
  7085 
  7086     LocaleInfo notNil ifTrue:[
  7086     LocaleInfo notNil ifTrue:[
  7087         "/ return the internal info; useful on systems which do not
  7087 	"/ return the internal info; useful on systems which do not
  7088         "/ support this.
  7088 	"/ support this.
  7089         ^ LocaleInfo
  7089 	^ LocaleInfo
  7090     ].
  7090     ].
  7091 
  7091 
  7092     info := IdentityDictionary new.
  7092     info := IdentityDictionary new.
  7093 %{
  7093 %{
  7094     char *decimalPoint;         /* something like "." (US) or "," (german) */
  7094     char *decimalPoint;         /* something like "." (US) or "," (german) */
  7105     int   csNegPrecedes;        /* money: 1 if currency symbol precedes a negative value; 0 if it sceeds */
  7105     int   csNegPrecedes;        /* money: 1 if currency symbol precedes a negative value; 0 if it sceeds */
  7106     int   csPosSepBySpace;      /* money: 1 if currency symbol should be separated by a space from a positive value; 0 if no space */
  7106     int   csPosSepBySpace;      /* money: 1 if currency symbol should be separated by a space from a positive value; 0 if no space */
  7107     int   csNegSepBySpace;      /* money: 1 if currency symbol should be separated by a space from a negative value; 0 if no space */
  7107     int   csNegSepBySpace;      /* money: 1 if currency symbol should be separated by a space from a negative value; 0 if no space */
  7108     int   csPosSignPosition;    /* money: 0: ()'s around the value & currency symbol */
  7108     int   csPosSignPosition;    /* money: 0: ()'s around the value & currency symbol */
  7109     int   csNegSignPosition;    /*        1: sign precedes the value & currency symbol */
  7109     int   csNegSignPosition;    /*        1: sign precedes the value & currency symbol */
  7110                                 /*        2: sign succeeds the value & currency symbol */
  7110 				/*        2: sign succeeds the value & currency symbol */
  7111                                 /*        3: sign immediately precedes the currency symbol */
  7111 				/*        3: sign immediately precedes the currency symbol */
  7112                                 /*        4: sign immediately suceeds the currency symbol */
  7112 				/*        4: sign immediately suceeds the currency symbol */
  7113 
  7113 
  7114 #if defined(HAS_LOCALECONV)
  7114 #if defined(HAS_LOCALECONV)
  7115     struct lconv *conf;
  7115     struct lconv *conf;
  7116 
  7116 
  7117     conf = localeconv();
  7117     conf = localeconv();
  7118     if (conf) {
  7118     if (conf) {
  7119         decimalPoint = conf->decimal_point;
  7119 	decimalPoint = conf->decimal_point;
  7120         thousandsSep = conf->thousands_sep;
  7120 	thousandsSep = conf->thousands_sep;
  7121         intCurrencySymbol = conf->int_curr_symbol;
  7121 	intCurrencySymbol = conf->int_curr_symbol;
  7122         currencySymbol = conf->currency_symbol;
  7122 	currencySymbol = conf->currency_symbol;
  7123         monDecimalPoint = conf->mon_decimal_point;
  7123 	monDecimalPoint = conf->mon_decimal_point;
  7124         monThousandsSep = conf->mon_thousands_sep;
  7124 	monThousandsSep = conf->mon_thousands_sep;
  7125         positiveSign = conf->positive_sign;
  7125 	positiveSign = conf->positive_sign;
  7126         negativeSign = conf->negative_sign;
  7126 	negativeSign = conf->negative_sign;
  7127         intFractDigits = conf->int_frac_digits;
  7127 	intFractDigits = conf->int_frac_digits;
  7128         fractDigits = conf->frac_digits;
  7128 	fractDigits = conf->frac_digits;
  7129         csPosPrecedes = conf->p_cs_precedes;
  7129 	csPosPrecedes = conf->p_cs_precedes;
  7130         csNegPrecedes = conf->n_cs_precedes;
  7130 	csNegPrecedes = conf->n_cs_precedes;
  7131         csPosSepBySpace = conf->p_sep_by_space;
  7131 	csPosSepBySpace = conf->p_sep_by_space;
  7132         csNegSepBySpace = conf->n_sep_by_space;
  7132 	csNegSepBySpace = conf->n_sep_by_space;
  7133         csPosSignPosition = conf->p_sign_posn;
  7133 	csPosSignPosition = conf->p_sign_posn;
  7134         csNegSignPosition = conf->n_sign_posn;
  7134 	csNegSignPosition = conf->n_sign_posn;
  7135     }
  7135     }
  7136 #else
  7136 #else
  7137     decimalPoint = (char *)0;
  7137     decimalPoint = (char *)0;
  7138     thousandsSep = (char *)0;
  7138     thousandsSep = (char *)0;
  7139     intCurrencySymbol = (char *)0;
  7139     intCurrencySymbol = (char *)0;
  7150     csNegSepBySpace = -1;
  7150     csNegSepBySpace = -1;
  7151     csPosSignPosition = -1;
  7151     csPosSignPosition = -1;
  7152     csNegSignPosition = -1;
  7152     csNegSignPosition = -1;
  7153 #endif
  7153 #endif
  7154     if (decimalPoint) {
  7154     if (decimalPoint) {
  7155         val = __MKSTRING(decimalPoint);
  7155 	val = __MKSTRING(decimalPoint);
  7156         __AT_PUT_(info, @symbol(decimalPoint), val);
  7156 	__AT_PUT_(info, @symbol(decimalPoint), val);
  7157     }
  7157     }
  7158     if (thousandsSep) {
  7158     if (thousandsSep) {
  7159         val = __MKSTRING(thousandsSep);
  7159 	val = __MKSTRING(thousandsSep);
  7160         __AT_PUT_(info, @symbol(thousandsSeparator), val);
  7160 	__AT_PUT_(info, @symbol(thousandsSeparator), val);
  7161     }
  7161     }
  7162     if (intCurrencySymbol) {
  7162     if (intCurrencySymbol) {
  7163         val = __MKSTRING(intCurrencySymbol);
  7163 	val = __MKSTRING(intCurrencySymbol);
  7164         __AT_PUT_(info, @symbol(internationCurrencySymbol), val);
  7164 	__AT_PUT_(info, @symbol(internationCurrencySymbol), val);
  7165     }
  7165     }
  7166     if (currencySymbol) {
  7166     if (currencySymbol) {
  7167         val = __MKSTRING(currencySymbol);
  7167 	val = __MKSTRING(currencySymbol);
  7168         __AT_PUT_(info, @symbol(currencySymbol), val);
  7168 	__AT_PUT_(info, @symbol(currencySymbol), val);
  7169     }
  7169     }
  7170     if (monDecimalPoint) {
  7170     if (monDecimalPoint) {
  7171         val = __MKSTRING(monDecimalPoint);
  7171 	val = __MKSTRING(monDecimalPoint);
  7172         __AT_PUT_(info, @symbol(monetaryDecimalPoint), val);
  7172 	__AT_PUT_(info, @symbol(monetaryDecimalPoint), val);
  7173     }
  7173     }
  7174     if (monThousandsSep) {
  7174     if (monThousandsSep) {
  7175         val = __MKSTRING(monThousandsSep);
  7175 	val = __MKSTRING(monThousandsSep);
  7176         __AT_PUT_(info, @symbol(monetaryThousandsSeparator), val);
  7176 	__AT_PUT_(info, @symbol(monetaryThousandsSeparator), val);
  7177     }
  7177     }
  7178     if (positiveSign) {
  7178     if (positiveSign) {
  7179         val = __MKSTRING(positiveSign);
  7179 	val = __MKSTRING(positiveSign);
  7180         __AT_PUT_(info, @symbol(positiveSign), val);
  7180 	__AT_PUT_(info, @symbol(positiveSign), val);
  7181     }
  7181     }
  7182     if (negativeSign) {
  7182     if (negativeSign) {
  7183         val = __MKSTRING(negativeSign);
  7183 	val = __MKSTRING(negativeSign);
  7184         __AT_PUT_(info, @symbol(negativeSign), val);
  7184 	__AT_PUT_(info, @symbol(negativeSign), val);
  7185     }
  7185     }
  7186     if (intFractDigits >= 0) {
  7186     if (intFractDigits >= 0) {
  7187         __AT_PUT_(info, @symbol(internationalFractionalDigits),  __mkSmallInteger(intFractDigits));
  7187 	__AT_PUT_(info, @symbol(internationalFractionalDigits),  __mkSmallInteger(intFractDigits));
  7188     }
  7188     }
  7189     if (fractDigits >= 0) {
  7189     if (fractDigits >= 0) {
  7190         __AT_PUT_(info, @symbol(fractionalDigits),  __mkSmallInteger(fractDigits));
  7190 	__AT_PUT_(info, @symbol(fractionalDigits),  __mkSmallInteger(fractDigits));
  7191     }
  7191     }
  7192     if (csPosPrecedes >= 0) {
  7192     if (csPosPrecedes >= 0) {
  7193         if (csPosPrecedes == 0) {
  7193 	if (csPosPrecedes == 0) {
  7194             val = false;
  7194 	    val = false;
  7195         } else {
  7195 	} else {
  7196             val = true;
  7196 	    val = true;
  7197         }
  7197 	}
  7198         __AT_PUT_(info, @symbol(positiveSignPrecedesCurrencySymbol), val );
  7198 	__AT_PUT_(info, @symbol(positiveSignPrecedesCurrencySymbol), val );
  7199     }
  7199     }
  7200     if (csNegPrecedes >= 0) {
  7200     if (csNegPrecedes >= 0) {
  7201         if (csNegPrecedes == 0) {
  7201 	if (csNegPrecedes == 0) {
  7202             val = false;
  7202 	    val = false;
  7203         } else {
  7203 	} else {
  7204             val = true;
  7204 	    val = true;
  7205         }
  7205 	}
  7206         __AT_PUT_(info, @symbol(negativeSignPrecedesCurrencySymbol), val );
  7206 	__AT_PUT_(info, @symbol(negativeSignPrecedesCurrencySymbol), val );
  7207     }
  7207     }
  7208     if (csPosSepBySpace >= 0) {
  7208     if (csPosSepBySpace >= 0) {
  7209         if (csPosSepBySpace == 0) {
  7209 	if (csPosSepBySpace == 0) {
  7210             val = false;
  7210 	    val = false;
  7211         } else {
  7211 	} else {
  7212             val = true;
  7212 	    val = true;
  7213         }
  7213 	}
  7214         __AT_PUT_(info, @symbol(positiveSignSeparatedBySpaceFromCurrencySymbol), val);
  7214 	__AT_PUT_(info, @symbol(positiveSignSeparatedBySpaceFromCurrencySymbol), val);
  7215     }
  7215     }
  7216     if (csNegSepBySpace >= 0) {
  7216     if (csNegSepBySpace >= 0) {
  7217         if (csNegSepBySpace == 0) {
  7217 	if (csNegSepBySpace == 0) {
  7218             val = false;
  7218 	    val = false;
  7219         } else {
  7219 	} else {
  7220             val = true;
  7220 	    val = true;
  7221         }
  7221 	}
  7222         __AT_PUT_(info, @symbol(negativeSignSeparatedBySpaceFromCurrencySymbol), val);
  7222 	__AT_PUT_(info, @symbol(negativeSignSeparatedBySpaceFromCurrencySymbol), val);
  7223     }
  7223     }
  7224     switch (csPosSignPosition) {
  7224     switch (csPosSignPosition) {
  7225         case 0:
  7225 	case 0:
  7226             val = @symbol(parenthesesAround);
  7226 	    val = @symbol(parenthesesAround);
  7227             break;
  7227 	    break;
  7228 
  7228 
  7229         case 1:
  7229 	case 1:
  7230             val = @symbol(signPrecedes);
  7230 	    val = @symbol(signPrecedes);
  7231             break;
  7231 	    break;
  7232 
  7232 
  7233         case 2:
  7233 	case 2:
  7234             val = @symbol(signSuceeds);
  7234 	    val = @symbol(signSuceeds);
  7235             break;
  7235 	    break;
  7236 
  7236 
  7237         case 3:
  7237 	case 3:
  7238             val = @symbol(signPrecedesCurrencySymbol);
  7238 	    val = @symbol(signPrecedesCurrencySymbol);
  7239             break;
  7239 	    break;
  7240 
  7240 
  7241         case 4:
  7241 	case 4:
  7242             val = @symbol(signSuceedsCurrencySymbol);
  7242 	    val = @symbol(signSuceedsCurrencySymbol);
  7243             break;
  7243 	    break;
  7244 
  7244 
  7245         default:
  7245 	default:
  7246             val = nil;
  7246 	    val = nil;
  7247     }
  7247     }
  7248     if (val != nil) {
  7248     if (val != nil) {
  7249         __AT_PUT_(info, @symbol(positiveSignPosition), val);
  7249 	__AT_PUT_(info, @symbol(positiveSignPosition), val);
  7250     }
  7250     }
  7251 
  7251 
  7252     switch (csNegSignPosition) {
  7252     switch (csNegSignPosition) {
  7253         case 0:
  7253 	case 0:
  7254             val = @symbol(parenthesesAround);
  7254 	    val = @symbol(parenthesesAround);
  7255             break;
  7255 	    break;
  7256 
  7256 
  7257         case 1:
  7257 	case 1:
  7258             val = @symbol(signPrecedes);
  7258 	    val = @symbol(signPrecedes);
  7259             break;
  7259 	    break;
  7260 
  7260 
  7261         case 2:
  7261 	case 2:
  7262             val = @symbol(signSuceeds);
  7262 	    val = @symbol(signSuceeds);
  7263             break;
  7263 	    break;
  7264 
  7264 
  7265         case 3:
  7265 	case 3:
  7266             val = @symbol(signPrecedesCurrencySymbol);
  7266 	    val = @symbol(signPrecedesCurrencySymbol);
  7267             break;
  7267 	    break;
  7268 
  7268 
  7269         case 4:
  7269 	case 4:
  7270             val = @symbol(signSuceedsCurrencySymbol);
  7270 	    val = @symbol(signSuceedsCurrencySymbol);
  7271             break;
  7271 	    break;
  7272 
  7272 
  7273         default:
  7273 	default:
  7274             val = nil;
  7274 	    val = nil;
  7275     }
  7275     }
  7276     if (val != nil) {
  7276     if (val != nil) {
  7277         __AT_PUT_(info, @symbol(negativeSignPosition), val);
  7277 	__AT_PUT_(info, @symbol(negativeSignPosition), val);
  7278     }
  7278     }
  7279 %}.
  7279 %}.
  7280     ^ info
  7280     ^ info
  7281 
  7281 
  7282     "
  7282     "
  7286     "Created: 23.12.1995 / 14:19:20 / cg"
  7286     "Created: 23.12.1995 / 14:19:20 / cg"
  7287 !
  7287 !
  7288 
  7288 
  7289 getNetworkAddressInfo
  7289 getNetworkAddressInfo
  7290     "return a Dictionary of network interface information.
  7290     "return a Dictionary of network interface information.
  7291         key -> name of interface
  7291 	key -> name of interface
  7292         value -> a Set of network address
  7292 	value -> a Set of network address
  7293                 information for the interface - a dictionaries containing the
  7293 		information for the interface - a dictionaries containing the
  7294                 information about the configuration of each interface in the system.
  7294 		information about the configuration of each interface in the system.
  7295                 The dictionary keys are:
  7295 		The dictionary keys are:
  7296                     #address
  7296 		    #address
  7297                     #netmask
  7297 		    #netmask
  7298                     #flags
  7298 		    #flags
  7299                     #destAddress"
  7299 		    #destAddress"
  7300 
  7300 
  7301     |returnArray addressArray nameArray noOfIf retDictionary error retIndex|
  7301     |returnArray addressArray nameArray noOfIf retDictionary error retIndex|
  7302 
  7302 
  7303     noOfIf := 0.
  7303     noOfIf := 0.
  7304 
  7304 
  7314     int n_ifa = 0;
  7314     int n_ifa = 0;
  7315     int retI = 0;
  7315     int retI = 0;
  7316     OBJ t;
  7316     OBJ t;
  7317 
  7317 
  7318     if (getifaddrs(&ifap) < 0) {
  7318     if (getifaddrs(&ifap) < 0) {
  7319         error = __MKSTRING("getifaddrs() failed");
  7319 	error = __MKSTRING("getifaddrs() failed");
  7320         goto out;
  7320 	goto out;
  7321     }
  7321     }
  7322 
  7322 
  7323     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) n_ifa++;
  7323     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) n_ifa++;
  7324 
  7324 
  7325     returnArray = __ARRAY_NEW_INT(n_ifa*5);
  7325     returnArray = __ARRAY_NEW_INT(n_ifa*5);
  7326 
  7326 
  7327     if (returnArray == nil) {
  7327     if (returnArray == nil) {
  7328         /* Creating a string wouldn't work here */
  7328 	/* Creating a string wouldn't work here */
  7329         error = @symbol(allocationFailure);
  7329 	error = @symbol(allocationFailure);
  7330         goto bad;
  7330 	goto bad;
  7331     }
  7331     }
  7332 
  7332 
  7333     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) {
  7333     for (ifaLoop = ifap; ifaLoop != 0; ifaLoop = ifaLoop->ifa_next) {
  7334         int family, len;
  7334 	int family, len;
  7335 
  7335 
  7336         if (ifaLoop->ifa_addr == 0)
  7336 	if (ifaLoop->ifa_addr == 0)
  7337                continue;
  7337 	       continue;
  7338         family = ifaLoop->ifa_addr->sa_family;
  7338 	family = ifaLoop->ifa_addr->sa_family;
  7339         switch (family) {
  7339 	switch (family) {
  7340         case AF_INET:
  7340 	case AF_INET:
  7341             len = sizeof(struct sockaddr_in);
  7341 	    len = sizeof(struct sockaddr_in);
  7342             break;
  7342 	    break;
  7343         case AF_INET6:
  7343 	case AF_INET6:
  7344             len = sizeof(struct sockaddr_in6);
  7344 	    len = sizeof(struct sockaddr_in6);
  7345             break;
  7345 	    break;
  7346 #if 0
  7346 #if 0
  7347         case AF_PACKET:
  7347 	case AF_PACKET:
  7348             len = sizeof(sockaddr_ll);
  7348 	    len = sizeof(sockaddr_ll);
  7349             break;
  7349 	    break;
  7350 #endif
  7350 #endif
  7351         default:
  7351 	default:
  7352             /* skip */
  7352 	    /* skip */
  7353             continue;
  7353 	    continue;
  7354         };
  7354 	};
  7355         t = __MKSTRING(ifaLoop->ifa_name);
  7355 	t = __MKSTRING(ifaLoop->ifa_name);
  7356         __arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7356 	__arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7357         t = __MKUINT(ifaLoop->ifa_flags);
  7357 	t = __MKUINT(ifaLoop->ifa_flags);
  7358         __arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7358 	__arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7359         t = __MKBYTEARRAY((char *)ifaLoop->ifa_addr, len);
  7359 	t = __MKBYTEARRAY((char *)ifaLoop->ifa_addr, len);
  7360         __arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7360 	__arrayVal(returnArray)[retI++] = t; __STORE(returnArray, t);
  7361         if (ifaLoop->ifa_netmask != 0) {
  7361 	if (ifaLoop->ifa_netmask != 0) {
  7362             t = __MKBYTEARRAY((char *)ifaLoop->ifa_netmask, len);
  7362 	    t = __MKBYTEARRAY((char *)ifaLoop->ifa_netmask, len);
  7363             __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7363 	    __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7364         }
  7364 	}
  7365         retI++;
  7365 	retI++;
  7366         if (ifaLoop->ifa_dstaddr != 0) {
  7366 	if (ifaLoop->ifa_dstaddr != 0) {
  7367             t = __MKBYTEARRAY((char *)ifaLoop->ifa_dstaddr, len);
  7367 	    t = __MKBYTEARRAY((char *)ifaLoop->ifa_dstaddr, len);
  7368             __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7368 	    __arrayVal(returnArray)[retI] = t; __STORE(returnArray, t);
  7369         }
  7369 	}
  7370         retI++;
  7370 	retI++;
  7371     }
  7371     }
  7372 
  7372 
  7373     noOfIf = __mkSmallInteger(n_ifa);
  7373     noOfIf = __mkSmallInteger(n_ifa);
  7374 
  7374 
  7375 bad:
  7375 bad:
  7390     ** Open an INET socket
  7390     ** Open an INET socket
  7391     */
  7391     */
  7392 
  7392 
  7393     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7393     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7394     if (afinet_socket < 0) {
  7394     if (afinet_socket < 0) {
  7395         goto bad;
  7395 	goto bad;
  7396     }
  7396     }
  7397 
  7397 
  7398     /*
  7398     /*
  7399     ** Get the list of network interfaces
  7399     ** Get the list of network interfaces
  7400     */
  7400     */
  7401 
  7401 
  7402     ifc.ifc_len = sizeof (buf);
  7402     ifc.ifc_len = sizeof (buf);
  7403     ifc.ifc_buf = (caddr_t) buf;
  7403     ifc.ifc_buf = (caddr_t) buf;
  7404 
  7404 
  7405     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7405     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7406         close(afinet_socket);
  7406 	close(afinet_socket);
  7407         error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7407 	error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7408         goto bad;
  7408 	goto bad;
  7409     }
  7409     }
  7410 
  7410 
  7411     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7411     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7412 
  7412 
  7413     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7413     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7414     addressArray = __ARRAY_NEW_INT(n_ifs);
  7414     addressArray = __ARRAY_NEW_INT(n_ifs);
  7415 
  7415 
  7416     if (nameArray == nil || addressArray == nil) {
  7416     if (nameArray == nil || addressArray == nil) {
  7417         /* Creating a string wouldn/t work here */
  7417 	/* Creating a string wouldn/t work here */
  7418         error = @symbol(allocationFailure);
  7418 	error = @symbol(allocationFailure);
  7419         goto bad;
  7419 	goto bad;
  7420     }
  7420     }
  7421 
  7421 
  7422     /*
  7422     /*
  7423     ** Iterate of the list of the system's netif. Find all
  7423     ** Iterate of the list of the system's netif. Find all
  7424     ** active interfaces and their ethernet addresses
  7424     ** active interfaces and their ethernet addresses
  7425     */
  7425     */
  7426     countOfIf = 0;
  7426     countOfIf = 0;
  7427 
  7427 
  7428     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++, ifr++) {
  7428     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++, ifr++) {
  7429         /*
  7429 	/*
  7430         ** Get address for this interface
  7430 	** Get address for this interface
  7431         */
  7431 	*/
  7432         memset (&ifreq, 0, sizeof(ifreq));
  7432 	memset (&ifreq, 0, sizeof(ifreq));
  7433         memcpy (ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
  7433 	memcpy (ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name));
  7434         if (ioctl (afinet_socket, SIOCGIFADDR, &ifreq) >= 0) {
  7434 	if (ioctl (afinet_socket, SIOCGIFADDR, &ifreq) >= 0) {
  7435             t = __MKBYTEARRAY((char *)&ifreq.ifr_addr, sizeof(ifreq.ifr_addr));
  7435 	    t = __MKBYTEARRAY((char *)&ifreq.ifr_addr, sizeof(ifreq.ifr_addr));
  7436             __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7436 	    __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7437             t = __MKSTRING(&ifreq.ifr_name);
  7437 	    t = __MKSTRING(&ifreq.ifr_name);
  7438             __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7438 	    __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7439             countOfIf++;
  7439 	    countOfIf++;
  7440         } else {
  7440 	} else {
  7441             if (@global(InfoPrinting) == true) {
  7441 	    if (@global(InfoPrinting) == true) {
  7442                 fprintf(stderr, "OS [warning]: SIOCGIFADDR failed: %d\n", errno);
  7442 		fprintf(stderr, "OS [warning]: SIOCGIFADDR failed: %d\n", errno);
  7443             }
  7443 	    }
  7444         }
  7444 	}
  7445         error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7445 	error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7446     }
  7446     }
  7447 
  7447 
  7448     noOfIf = __mkSmallInteger(countOfIf);
  7448     noOfIf = __mkSmallInteger(countOfIf);
  7449 bad:
  7449 bad:
  7450     if (afinet_socket >= 0)
  7450     if (afinet_socket >= 0)
  7451         close(afinet_socket);
  7451 	close(afinet_socket);
  7452 #else
  7452 #else
  7453     error = @symbol(notSupported);
  7453     error = @symbol(notSupported);
  7454 #endif /* defined(SIOCGIFADDR) */
  7454 #endif /* defined(SIOCGIFADDR) */
  7455 out:;
  7455 out:;
  7456 %}.
  7456 %}.
  7457 
  7457 
  7458     retDictionary := Dictionary new:noOfIf.
  7458     retDictionary := Dictionary new:noOfIf.
  7459     error notNil ifTrue:[
  7459     error notNil ifTrue:[
  7460         self primitiveFailed:error.
  7460 	self primitiveFailed:error.
  7461         "return empty dictionary if proceeding from error"
  7461 	"return empty dictionary if proceeding from error"
  7462         ^  retDictionary.
  7462 	^  retDictionary.
  7463     ].
  7463     ].
  7464 
  7464 
  7465     retIndex := 1.
  7465     retIndex := 1.
  7466 
  7466 
  7467     1 to:noOfIf do:[:cnt|
  7467     1 to:noOfIf do:[:cnt|
  7468         |name addressBytes set dict|
  7468 	|name addressBytes set dict|
  7469 
  7469 
  7470         name := returnArray at:retIndex.
  7470 	name := returnArray at:retIndex.
  7471         addressBytes := returnArray at:retIndex+2.
  7471 	addressBytes := returnArray at:retIndex+2.
  7472 
  7472 
  7473         addressBytes notNil ifTrue:[
  7473 	addressBytes notNil ifTrue:[
  7474             set := retDictionary at:name ifAbsentPut:[Set new].
  7474 	    set := retDictionary at:name ifAbsentPut:[Set new].
  7475             dict := Dictionary new:5.
  7475 	    dict := Dictionary new:5.
  7476             dict at:#flags put:(returnArray at:retIndex+1).
  7476 	    dict at:#flags put:(returnArray at:retIndex+1).
  7477             dict at:#address put:(SocketAddress fromBytes:addressBytes).
  7477 	    dict at:#address put:(SocketAddress fromBytes:addressBytes).
  7478             addressBytes := returnArray at:retIndex+3.
  7478 	    addressBytes := returnArray at:retIndex+3.
  7479             addressBytes notNil ifTrue:[
  7479 	    addressBytes notNil ifTrue:[
  7480                 dict at:#netMask put:(SocketAddress fromBytes:addressBytes).
  7480 		dict at:#netMask put:(SocketAddress fromBytes:addressBytes).
  7481             ].
  7481 	    ].
  7482             addressBytes := returnArray at:retIndex+4.
  7482 	    addressBytes := returnArray at:retIndex+4.
  7483             addressBytes notNil ifTrue:[
  7483 	    addressBytes notNil ifTrue:[
  7484                 dict at:#destAddress put:(SocketAddress fromBytes:addressBytes).
  7484 		dict at:#destAddress put:(SocketAddress fromBytes:addressBytes).
  7485             ].
  7485 	    ].
  7486             set add:dict.
  7486 	    set add:dict.
  7487         ].
  7487 	].
  7488         retIndex := retIndex + 5.
  7488 	retIndex := retIndex + 5.
  7489     ].
  7489     ].
  7490 
  7490 
  7491     ^ retDictionary
  7491     ^ retDictionary
  7492 
  7492 
  7493     "
  7493     "
  7495     "
  7495     "
  7496 !
  7496 !
  7497 
  7497 
  7498 getNetworkAddresses
  7498 getNetworkAddresses
  7499     "return a dictionary filled with
  7499     "return a dictionary filled with
  7500         key -> name of interface
  7500 	key -> name of interface
  7501         value -> the socket adress of the interface
  7501 	value -> the socket adress of the interface
  7502      for each interface"
  7502      for each interface"
  7503 
  7503 
  7504     |addressArray nameArray noOfIf retDictionary error|
  7504     |addressArray nameArray noOfIf retDictionary error|
  7505 
  7505 
  7506     noOfIf := 0.
  7506     noOfIf := 0.
  7520     ** Open an INET socket
  7520     ** Open an INET socket
  7521     */
  7521     */
  7522 
  7522 
  7523     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7523     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7524     if (afinet_socket < 0) {
  7524     if (afinet_socket < 0) {
  7525         error = __MKSTRING("Cannot open socket");
  7525 	error = __MKSTRING("Cannot open socket");
  7526         goto bad;
  7526 	goto bad;
  7527     }
  7527     }
  7528 
  7528 
  7529     /*
  7529     /*
  7530     ** Get the list of network interfaces
  7530     ** Get the list of network interfaces
  7531     */
  7531     */
  7532 
  7532 
  7533     ifc.ifc_len = sizeof (buf);
  7533     ifc.ifc_len = sizeof (buf);
  7534     ifc.ifc_buf = (caddr_t) buf;
  7534     ifc.ifc_buf = (caddr_t) buf;
  7535 
  7535 
  7536     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7536     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7537         close(afinet_socket);
  7537 	close(afinet_socket);
  7538         error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7538 	error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7539         goto bad;
  7539 	goto bad;
  7540     }
  7540     }
  7541 
  7541 
  7542     // get the number of interfaces in the returned structure
  7542     // get the number of interfaces in the returned structure
  7543 
  7543 
  7544     // cg: sigh
  7544     // cg: sigh
  7550     // see also 2nd loop below
  7550     // see also 2nd loop below
  7551 #ifndef __osx__
  7551 #ifndef __osx__
  7552     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7552     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7553 #else
  7553 #else
  7554     {
  7554     {
  7555         unsigned char *cp = buf;
  7555 	unsigned char *cp = buf;
  7556         char *limit = buf + ifc.ifc_len;
  7556 	char *limit = buf + ifc.ifc_len;
  7557 
  7557 
  7558         n_ifs = 0;
  7558 	n_ifs = 0;
  7559         while (cp < limit) {
  7559 	while (cp < limit) {
  7560             int sz;
  7560 	    int sz;
  7561 
  7561 
  7562             ifr = (struct ifreq *)cp;
  7562 	    ifr = (struct ifreq *)cp;
  7563             sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7563 	    sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7564 
  7564 
  7565             cp += sz;
  7565 	    cp += sz;
  7566             n_ifs++;
  7566 	    n_ifs++;
  7567         }
  7567 	}
  7568     }
  7568     }
  7569 #endif
  7569 #endif
  7570 
  7570 
  7571     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7571     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7572     addressArray = __ARRAY_NEW_INT(n_ifs);
  7572     addressArray = __ARRAY_NEW_INT(n_ifs);
  7573 
  7573 
  7574     if (nameArray == nil || addressArray == nil) {
  7574     if (nameArray == nil || addressArray == nil) {
  7575         /* Creating a string wouldn/t work here */
  7575 	/* Creating a string wouldn/t work here */
  7576         error = @symbol(allocationFailure);
  7576 	error = @symbol(allocationFailure);
  7577         goto bad;
  7577 	goto bad;
  7578     }
  7578     }
  7579 
  7579 
  7580     /*
  7580     /*
  7581     ** Iterate of the list of the system's netif. Find all
  7581     ** Iterate of the list of the system's netif. Find all
  7582     ** active interfaces and their ethernet addresses
  7582     ** active interfaces and their ethernet addresses
  7583     */
  7583     */
  7584     countOfIf = 0;
  7584     countOfIf = 0;
  7585 
  7585 
  7586     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++) {
  7586     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++) {
  7587         /*
  7587 	/*
  7588         ** Get Flags for this interface
  7588 	** Get Flags for this interface
  7589         */
  7589 	*/
  7590 
  7590 
  7591         memcpy(&ifreq, ifr, sizeof(ifreq));
  7591 	memcpy(&ifreq, ifr, sizeof(ifreq));
  7592         /*
  7592 	/*
  7593         ** Get address for this interface
  7593 	** Get address for this interface
  7594         */
  7594 	*/
  7595         memcpy(&ifreq, ifr, sizeof(ifreq));
  7595 	memcpy(&ifreq, ifr, sizeof(ifreq));
  7596         if (ioctl (afinet_socket, SIOCGIFADDR, &ifreq) >= 0) {
  7596 	if (ioctl (afinet_socket, SIOCGIFADDR, &ifreq) >= 0) {
  7597             t = __MKBYTEARRAY((char *)&ifreq.ifr_addr, sizeof(ifreq.ifr_addr));
  7597 	    t = __MKBYTEARRAY((char *)&ifreq.ifr_addr, sizeof(ifreq.ifr_addr));
  7598             __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7598 	    __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7599             t = __MKSTRING(&ifreq.ifr_name);
  7599 	    t = __MKSTRING(&ifreq.ifr_name);
  7600             __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7600 	    __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7601             countOfIf += 1;
  7601 	    countOfIf += 1;
  7602         }
  7602 	}
  7603         // see (sigh) comment above
  7603 	// see (sigh) comment above
  7604 #ifndef __osx__
  7604 #ifndef __osx__
  7605         ifr++;
  7605 	ifr++;
  7606 #else
  7606 #else
  7607         {
  7607 	{
  7608             int sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7608 	    int sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7609 
  7609 
  7610             ifr = (struct ifreq *)( ((char *)ifr)+sz );
  7610 	    ifr = (struct ifreq *)( ((char *)ifr)+sz );
  7611         }
  7611 	}
  7612 #endif
  7612 #endif
  7613     }
  7613     }
  7614 
  7614 
  7615     noOfIf = __mkSmallInteger(countOfIf);
  7615     noOfIf = __mkSmallInteger(countOfIf);
  7616 bad:
  7616 bad:
  7617     if (afinet_socket >= 0)
  7617     if (afinet_socket >= 0)
  7618         close(afinet_socket);
  7618 	close(afinet_socket);
  7619 #else
  7619 #else
  7620     error = @symbol(notSupported);
  7620     error = @symbol(notSupported);
  7621 #endif /* defined(SIOCGIFADDR) */
  7621 #endif /* defined(SIOCGIFADDR) */
  7622 %}.
  7622 %}.
  7623 
  7623 
  7624     retDictionary := Dictionary new:noOfIf.
  7624     retDictionary := Dictionary new:noOfIf.
  7625     error notNil ifTrue:[
  7625     error notNil ifTrue:[
  7626         self primitiveFailed:error.
  7626 	self primitiveFailed:error.
  7627         "return empty dictionary if proceed from error"
  7627 	"return empty dictionary if proceed from error"
  7628         ^  retDictionary.
  7628 	^  retDictionary.
  7629     ].
  7629     ].
  7630 
  7630 
  7631     1 to:noOfIf do:[:cnt|
  7631     1 to:noOfIf do:[:cnt|
  7632         "take the first address, if there is more than one!!"
  7632 	"take the first address, if there is more than one!!"
  7633         retDictionary at:(nameArray at:cnt) ifAbsentPut:(SocketAddress fromBytes:(addressArray at:cnt)).
  7633 	retDictionary at:(nameArray at:cnt) ifAbsentPut:(SocketAddress fromBytes:(addressArray at:cnt)).
  7634     ].
  7634     ].
  7635 
  7635 
  7636     ^ retDictionary
  7636     ^ retDictionary
  7637 
  7637 
  7638     "
  7638     "
  7640     "
  7640     "
  7641 !
  7641 !
  7642 
  7642 
  7643 getNetworkMACAddresses
  7643 getNetworkMACAddresses
  7644     "return a dictionary filled with
  7644     "return a dictionary filled with
  7645         key -> name of interface
  7645 	key -> name of interface
  7646         value -> the MAC adress (as ByteArray)
  7646 	value -> the MAC adress (as ByteArray)
  7647      for each interface"
  7647      for each interface"
  7648 
  7648 
  7649     |addressArray nameArray noOfIf retDictionary error|
  7649     |addressArray nameArray noOfIf retDictionary error|
  7650 
  7650 
  7651     noOfIf := 0.
  7651     noOfIf := 0.
  7664     ** Open an INET socket
  7664     ** Open an INET socket
  7665     */
  7665     */
  7666 
  7666 
  7667     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7667     afinet_socket = socket(AF_INET, SOCK_DGRAM, 0);
  7668     if (afinet_socket < 0) {
  7668     if (afinet_socket < 0) {
  7669         error = __MKSTRING("Cannot open socket");
  7669 	error = __MKSTRING("Cannot open socket");
  7670         goto bad;
  7670 	goto bad;
  7671     }
  7671     }
  7672 
  7672 
  7673     /*
  7673     /*
  7674     ** Get the list of network interfaces
  7674     ** Get the list of network interfaces
  7675     */
  7675     */
  7676 
  7676 
  7677     ifc.ifc_len = sizeof (buf);
  7677     ifc.ifc_len = sizeof (buf);
  7678     ifc.ifc_buf = (caddr_t) buf;
  7678     ifc.ifc_buf = (caddr_t) buf;
  7679 
  7679 
  7680     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7680     if (ioctl (afinet_socket, SIOCGIFCONF, (caddr_t) &ifc) < 0) {
  7681         error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7681 	error = __MKSTRING("ioctl(SIOCGIFCONF) failed");
  7682         goto bad;
  7682 	goto bad;
  7683     }
  7683     }
  7684 
  7684 
  7685     // get the number of interfaces in the returned structure
  7685     // get the number of interfaces in the returned structure
  7686 
  7686 
  7687     // cg: sigh
  7687     // cg: sigh
  7693     // see also 2nd loop below
  7693     // see also 2nd loop below
  7694 #ifndef __osx__
  7694 #ifndef __osx__
  7695     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7695     n_ifs = ifc.ifc_len / sizeof (struct ifreq);
  7696 #else
  7696 #else
  7697     {
  7697     {
  7698         unsigned char *cp = buf;
  7698 	unsigned char *cp = buf;
  7699         char *limit = buf + ifc.ifc_len;
  7699 	char *limit = buf + ifc.ifc_len;
  7700 
  7700 
  7701         n_ifs = 0;
  7701 	n_ifs = 0;
  7702         while (cp < limit) {
  7702 	while (cp < limit) {
  7703             int sz;
  7703 	    int sz;
  7704 
  7704 
  7705             ifr = (struct ifreq *)cp;
  7705 	    ifr = (struct ifreq *)cp;
  7706             sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7706 	    sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7707 
  7707 
  7708             cp += sz;
  7708 	    cp += sz;
  7709             n_ifs++;
  7709 	    n_ifs++;
  7710         }
  7710 	}
  7711     }
  7711     }
  7712 #endif
  7712 #endif
  7713 
  7713 
  7714     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7714     nameArray    = __ARRAY_NEW_INT(n_ifs);
  7715     addressArray = __ARRAY_NEW_INT(n_ifs);
  7715     addressArray = __ARRAY_NEW_INT(n_ifs);
  7716 
  7716 
  7717     if (nameArray == nil || addressArray == nil) {
  7717     if (nameArray == nil || addressArray == nil) {
  7718         /* Creating a string wouldn/t work here */
  7718 	/* Creating a string wouldn/t work here */
  7719         error = @symbol(allocationFailure);
  7719 	error = @symbol(allocationFailure);
  7720         goto bad;
  7720 	goto bad;
  7721     }
  7721     }
  7722 
  7722 
  7723     /*
  7723     /*
  7724     ** Iterate of the list of the system's netif. Find all
  7724     ** Iterate of the list of the system's netif. Find all
  7725     ** active interfaces and their ethernet addresses
  7725     ** active interfaces and their ethernet addresses
  7726     */
  7726     */
  7727 
  7727 
  7728     countOfIf = 0;
  7728     countOfIf = 0;
  7729 
  7729 
  7730     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++) {
  7730     for (i=0, ifr = ifc.ifc_req; i < n_ifs; i++) {
  7731         /*
  7731 	/*
  7732         ** Get Flags for this interface
  7732 	** Get Flags for this interface
  7733         */
  7733 	*/
  7734 
  7734 
  7735 # ifndef __osx__ // SIOCGIFFLAGS fails on osx (Q@sv: what is this needed for anyway?)
  7735 # ifndef __osx__ // SIOCGIFFLAGS fails on osx (Q@sv: what is this needed for anyway?)
  7736         {
  7736 	{
  7737             struct ifreq ifreq;
  7737 	    struct ifreq ifreq;
  7738             memcpy(&ifreq, ifr, sizeof(ifreq));
  7738 	    memcpy(&ifreq, ifr, sizeof(ifreq));
  7739             if (ioctl (afinet_socket, SIOCGIFFLAGS, &ifreq) < 0) {
  7739 	    if (ioctl (afinet_socket, SIOCGIFFLAGS, &ifreq) < 0) {
  7740                 if (@global(InfoPrinting) == true) {
  7740 		if (@global(InfoPrinting) == true) {
  7741                     fprintf(stderr, "OS [warning]: ioctl(SIOCGIFFLAGS) failed");
  7741 		    fprintf(stderr, "OS [warning]: ioctl(SIOCGIFFLAGS) failed");
  7742                 }
  7742 		}
  7743             }
  7743 	    }
  7744         }
  7744 	}
  7745 # endif
  7745 # endif
  7746         {
  7746 	{
  7747 # ifdef SIOCGIFHWADDR
  7747 # ifdef SIOCGIFHWADDR
  7748             /*
  7748 	    /*
  7749             ** Get Hardware address for this interface
  7749 	    ** Get Hardware address for this interface
  7750             */
  7750 	    */
  7751             {
  7751 	    {
  7752                 struct ifreq ifreq;
  7752 		struct ifreq ifreq;
  7753                 memcpy(&ifreq, ifr, sizeof(ifreq));
  7753 		memcpy(&ifreq, ifr, sizeof(ifreq));
  7754                 if (ioctl (afinet_socket, SIOCGIFHWADDR, &ifreq) >= 0) {
  7754 		if (ioctl (afinet_socket, SIOCGIFHWADDR, &ifreq) >= 0) {
  7755                     t = __MKBYTEARRAY(&ifreq.ifr_hwaddr.sa_data, IFHWADDRLEN);
  7755 		    t = __MKBYTEARRAY(&ifreq.ifr_hwaddr.sa_data, IFHWADDRLEN);
  7756                     __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7756 		    __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7757                     t = __MKSTRING(&ifreq.ifr_name);
  7757 		    t = __MKSTRING(&ifreq.ifr_name);
  7758                     __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7758 		    __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7759                     countOfIf += 1;
  7759 		    countOfIf += 1;
  7760                 }
  7760 		}
  7761             }
  7761 	    }
  7762 
  7762 
  7763 #else
  7763 #else
  7764             // macosx has no SIOCGIFHWADDR
  7764 	    // macosx has no SIOCGIFHWADDR
  7765             // printf("family: %d\n", ifr->ifr_addr.sa_family);
  7765 	    // printf("family: %d\n", ifr->ifr_addr.sa_family);
  7766             // printf("name: %s\n", ifr->ifr_name);
  7766 	    // printf("name: %s\n", ifr->ifr_name);
  7767 
  7767 
  7768             if (ifr->ifr_addr.sa_family == AF_LINK) {
  7768 	    if (ifr->ifr_addr.sa_family == AF_LINK) {
  7769                 struct sockaddr_dl *sdl;
  7769 		struct sockaddr_dl *sdl;
  7770                 char *adr;
  7770 		char *adr;
  7771                 extern char *ether_ntoa();
  7771 		extern char *ether_ntoa();
  7772                 unsigned char mac[6];
  7772 		unsigned char mac[6];
  7773                 int a,b,c,d,e,f;
  7773 		int a,b,c,d,e,f;
  7774 
  7774 
  7775                 sdl = (struct sockaddr_dl *)&(ifr->ifr_addr);
  7775 		sdl = (struct sockaddr_dl *)&(ifr->ifr_addr);
  7776                 adr = ether_ntoa(LLADDR(sdl));
  7776 		adr = ether_ntoa(LLADDR(sdl));
  7777                 // printf("name: %s adr: %s\n", ifr->ifr_name, adr);
  7777 		// printf("name: %s adr: %s\n", ifr->ifr_name, adr);
  7778                 sscanf(adr, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
  7778 		sscanf(adr, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f);
  7779                 mac[0] = a;
  7779 		mac[0] = a;
  7780                 mac[1] = b;
  7780 		mac[1] = b;
  7781                 mac[2] = c;
  7781 		mac[2] = c;
  7782                 mac[3] = d;
  7782 		mac[3] = d;
  7783                 mac[4] = e;
  7783 		mac[4] = e;
  7784                 mac[5] = f;
  7784 		mac[5] = f;
  7785 
  7785 
  7786                 t = __MKBYTEARRAY(mac, 6);
  7786 		t = __MKBYTEARRAY(mac, 6);
  7787                 __arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7787 		__arrayVal(addressArray)[countOfIf] = t; __STORE(addressArray, t);
  7788                 t = __MKSTRING(ifr->ifr_name);
  7788 		t = __MKSTRING(ifr->ifr_name);
  7789                 __arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7789 		__arrayVal(nameArray)[countOfIf] = t; __STORE(nameArray, t);
  7790                 countOfIf += 1;
  7790 		countOfIf += 1;
  7791             }
  7791 	    }
  7792 #endif
  7792 #endif
  7793         }
  7793 	}
  7794 
  7794 
  7795         // see (sigh) comment above
  7795 	// see (sigh) comment above
  7796 #ifndef __osx__
  7796 #ifndef __osx__
  7797         ifr++;
  7797 	ifr++;
  7798 #else
  7798 #else
  7799         {
  7799 	{
  7800             int sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7800 	    int sz = IFNAMSIZ + ifr->ifr_addr.sa_len;
  7801 
  7801 
  7802             ifr = (struct ifreq *)( ((char *)ifr)+sz );
  7802 	    ifr = (struct ifreq *)( ((char *)ifr)+sz );
  7803         }
  7803 	}
  7804 #endif
  7804 #endif
  7805     }
  7805     }
  7806 
  7806 
  7807     noOfIf = __mkSmallInteger(countOfIf);
  7807     noOfIf = __mkSmallInteger(countOfIf);
  7808 bad:
  7808 bad:
  7809     if (afinet_socket >= 0)
  7809     if (afinet_socket >= 0)
  7810         close(afinet_socket);
  7810 	close(afinet_socket);
  7811 #else
  7811 #else
  7812     error = @symbol(notSupported);
  7812     error = @symbol(notSupported);
  7813 #endif /* SIOCGIFHWADDR */
  7813 #endif /* SIOCGIFHWADDR */
  7814 %}.
  7814 %}.
  7815 
  7815 
  7816     error notNil ifTrue:[
  7816     error notNil ifTrue:[
  7817         self primitiveFailed:error.
  7817 	self primitiveFailed:error.
  7818         "return an empty dictionary if proceed from error"
  7818 	"return an empty dictionary if proceed from error"
  7819         ^  Dictionary new.
  7819 	^  Dictionary new.
  7820     ].
  7820     ].
  7821 
  7821 
  7822     "we prefer OrderedDictionary here, because we want to keep the
  7822     "we prefer OrderedDictionary here, because we want to keep the
  7823      order as defined in the OS."
  7823      order as defined in the OS."
  7824     retDictionary := OrderedDictionary new:noOfIf.
  7824     retDictionary := OrderedDictionary new:noOfIf.
  7825     1 to:noOfIf do:[:cnt|
  7825     1 to:noOfIf do:[:cnt|
  7826         |macAddress|
  7826 	|macAddress|
  7827 
  7827 
  7828         macAddress := addressArray at:cnt.
  7828 	macAddress := addressArray at:cnt.
  7829         macAddress ~= #[0 0 0 0 0 0] ifTrue:[
  7829 	macAddress ~= #[0 0 0 0 0 0] ifTrue:[
  7830             retDictionary at:(nameArray at:cnt) put:macAddress.
  7830 	    retDictionary at:(nameArray at:cnt) put:macAddress.
  7831         ].
  7831 	].
  7832     ].
  7832     ].
  7833 
  7833 
  7834     ^ retDictionary
  7834     ^ retDictionary
  7835 
  7835 
  7836     "
  7836     "
  7868 
  7868 
  7869 getSystemID
  7869 getSystemID
  7870     "if supported by the OS, return the systemID;
  7870     "if supported by the OS, return the systemID;
  7871      a unique per machine identification.
  7871      a unique per machine identification.
  7872      WARNING:
  7872      WARNING:
  7873         not all systems support this; on some, #unknown is returned."
  7873 	not all systems support this; on some, #unknown is returned."
  7874 
  7874 
  7875 %{  /* NOCONTEXT */
  7875 %{  /* NOCONTEXT */
  7876 #if defined(HAS_SYSINFO) && defined(SI_HW_SERIAL)
  7876 #if defined(HAS_SYSINFO) && defined(SI_HW_SERIAL)
  7877     {
  7877     {
  7878         char buffer[128];
  7878 	char buffer[128];
  7879 
  7879 
  7880         buffer[0] = 0;
  7880 	buffer[0] = 0;
  7881         if (sysinfo(SI_HW_SERIAL, buffer, sizeof(buffer))) {
  7881 	if (sysinfo(SI_HW_SERIAL, buffer, sizeof(buffer))) {
  7882             buffer[127] = 0;
  7882 	    buffer[127] = 0;
  7883             if (strlen(buffer) > 0) {
  7883 	    if (strlen(buffer) > 0) {
  7884                 RETURN(__MKSTRING(buffer));
  7884 		RETURN(__MKSTRING(buffer));
  7885             }
  7885 	    }
  7886         }
  7886 	}
  7887     }
  7887     }
  7888 #elif defined(HAS_GETHOSTID)
  7888 #elif defined(HAS_GETHOSTID)
  7889     int runningId;
  7889     int runningId;
  7890     OBJ arr;
  7890     OBJ arr;
  7891 
  7891 
  7898     char idBuffer[MAXSYSIDSIZE];
  7898     char idBuffer[MAXSYSIDSIZE];
  7899     int retVal;
  7899     int retVal;
  7900     OBJ arr;
  7900     OBJ arr;
  7901 
  7901 
  7902     if ((retVal = syssgi(SGI_SYSID, idBuffer)) == 0) {
  7902     if ((retVal = syssgi(SGI_SYSID, idBuffer)) == 0) {
  7903         arr = __BYTEARRAY_UNINITIALIZED_NEW_INT(MAXSYSIDSIZE);
  7903 	arr = __BYTEARRAY_UNINITIALIZED_NEW_INT(MAXSYSIDSIZE);
  7904         bcopy(idBuffer, __byteArrayVal(arr), MAXSYSIDSIZE);
  7904 	bcopy(idBuffer, __byteArrayVal(arr), MAXSYSIDSIZE);
  7905         RETURN (arr);
  7905 	RETURN (arr);
  7906     }
  7906     }
  7907 #endif
  7907 #endif
  7908 %}.
  7908 %}.
  7909     ^ #unknown
  7909     ^ #unknown
  7910 
  7910 
  7924        OS, for example, linux returns 'ix86', while WIN32 returns 'x86'.
  7924        OS, for example, linux returns 'ix86', while WIN32 returns 'x86'.
  7925 
  7925 
  7926        This method is mainly provided to augment error reports with some system
  7926        This method is mainly provided to augment error reports with some system
  7927        information.
  7927        information.
  7928        (in case of system/version specific OS errors, conditional workarounds and patches
  7928        (in case of system/version specific OS errors, conditional workarounds and patches
  7929         may be based upon this info).
  7929 	may be based upon this info).
  7930        Also, applications could enable/disable buffering or otherwise reduce
  7930        Also, applications could enable/disable buffering or otherwise reduce
  7931        their memory usage depending upon the amount of memory installed.
  7931        their memory usage depending upon the amount of memory installed.
  7932        Your application may make use of available information for tuning,
  7932        Your application may make use of available information for tuning,
  7933        but should NEVER DEPEND upon this in any way.
  7933        but should NEVER DEPEND upon this in any way.
  7934 
  7934 
  7935      The returned info may (or may not) contain:
  7935      The returned info may (or may not) contain:
  7936         #system -> some operating system identification (irix, Linux, nt, win32s ...)
  7936 	#system -> some operating system identification (irix, Linux, nt, win32s ...)
  7937         #version -> OS version (some os version identification)
  7937 	#version -> OS version (some os version identification)
  7938         #release -> OS release (3.5, 1.2.1 ...)
  7938 	#release -> OS release (3.5, 1.2.1 ...)
  7939         #node   -> some host identification (hostname)
  7939 	#node   -> some host identification (hostname)
  7940         #domain  -> domain name (hosts domain)
  7940 	#domain  -> domain name (hosts domain)
  7941         #machine -> type of CPU (i586, mips ...)
  7941 	#machine -> type of CPU (i586, mips ...)
  7942 
  7942 
  7943      those are currently returned on some machines (no warranty)
  7943      those are currently returned on some machines (no warranty)
  7944      linux:
  7944      linux:
  7945         #totalRam         -> total amount of memory available
  7945 	#totalRam         -> total amount of memory available
  7946         #sharedRam        -> amount of memory which is shared among processes
  7946 	#sharedRam        -> amount of memory which is shared among processes
  7947                              (i.e. shared code)
  7947 			     (i.e. shared code)
  7948         #bufferRam        -> amount used for buffers
  7948 	#bufferRam        -> amount used for buffers
  7949         #swapSize         -> total size of swap space
  7949 	#swapSize         -> total size of swap space
  7950         #freeSwap         -> free amount in swapSpace
  7950 	#freeSwap         -> free amount in swapSpace
  7951         #numberOfCPUs     -> number of cpus in box
  7951 	#numberOfCPUs     -> number of cpus in box
  7952         #extendedInstructions -> extended instruction set info
  7952 	#extendedInstructions -> extended instruction set info
  7953 
  7953 
  7954      osf:
  7954      osf:
  7955         #physicalRam      -> total amount of physical memory
  7955 	#physicalRam      -> total amount of physical memory
  7956         #cpuType          -> type of cpu (more detailed than machine)
  7956 	#cpuType          -> type of cpu (more detailed than machine)
  7957         #numberOfCPUs     -> number of cpus in box
  7957 	#numberOfCPUs     -> number of cpus in box
  7958 
  7958 
  7959      osx:
  7959      osx:
  7960         #physicalRam      -> total amount of physical memory
  7960 	#physicalRam      -> total amount of physical memory
  7961 
  7961 
  7962      solaris:
  7962      solaris:
  7963         #physicalRam      -> total amount of physical memory
  7963 	#physicalRam      -> total amount of physical memory
  7964         #availableRam     -> total available amount of physical memory (i.e. unused ram)
  7964 	#availableRam     -> total available amount of physical memory (i.e. unused ram)
  7965         #freeRam          -> amount of free memory
  7965 	#freeRam          -> amount of free memory
  7966         #numberOfCPUs     -> number of cpus in box (online CPUS)
  7966 	#numberOfCPUs     -> number of cpus in box (online CPUS)
  7967         [#dCacheSize]     -> bytes in data cache (only available on some solaris versions)
  7967 	[#dCacheSize]     -> bytes in data cache (only available on some solaris versions)
  7968         [#iCacheSize]     -> bytes in data cache (only available on some solaris versions)
  7968 	[#iCacheSize]     -> bytes in data cache (only available on some solaris versions)
  7969         [#instructionSets]-> instruction sets available (only available on some solaris versions)
  7969 	[#instructionSets]-> instruction sets available (only available on some solaris versions)
  7970         [#platform]       -> platform name (only available on some solaris versions)
  7970 	[#platform]       -> platform name (only available on some solaris versions)
  7971 
  7971 
  7972      hpux:
  7972      hpux:
  7973         #physicalRam      -> total amount of physical memory in box
  7973 	#physicalRam      -> total amount of physical memory in box
  7974         #activeRealMemory -> ? - read pstat documentation
  7974 	#activeRealMemory -> ? - read pstat documentation
  7975         #activeVirtualRam -> ? - read pstat documentation
  7975 	#activeVirtualRam -> ? - read pstat documentation
  7976         #freeMemory       -> ? - read pstat documentation
  7976 	#freeMemory       -> ? - read pstat documentation
  7977         #realMemory       -> ? (amount of memory left to user programs)
  7977 	#realMemory       -> ? (amount of memory left to user programs)
  7978         #virtualRam       -> ? - read pstat documentation
  7978 	#virtualRam       -> ? - read pstat documentation
  7979     "
  7979     "
  7980 
  7980 
  7981     |sys node rel ver mach dom mtyp brel info arch cpuType cpuSpeed
  7981     |sys node rel ver mach dom mtyp brel info arch cpuType cpuSpeed
  7982      physicalRam availableRam totalRam sharedRam bufferRam swapSize freeSwap
  7982      physicalRam availableRam totalRam sharedRam bufferRam swapSize freeSwap
  7983      numberOfCPUs numberOfPhysicalCPUs pageSize physicalPages availablePages dCacheSize iCacheSize
  7983      numberOfCPUs numberOfPhysicalCPUs pageSize physicalPages availablePages dCacheSize iCacheSize
  7991      * additional info available ...
  7991      * additional info available ...
  7992      */
  7992      */
  7993     struct sysinfo infoBuffer;
  7993     struct sysinfo infoBuffer;
  7994 
  7994 
  7995     if (sysinfo(&infoBuffer) >= 0) {
  7995     if (sysinfo(&infoBuffer) >= 0) {
  7996         totalRam   = __MKUINT(infoBuffer.totalram);
  7996 	totalRam   = __MKUINT(infoBuffer.totalram);
  7997         sharedRam = __MKUINT(infoBuffer.sharedram);
  7997 	sharedRam = __MKUINT(infoBuffer.sharedram);
  7998         bufferRam = __MKUINT(infoBuffer.bufferram);
  7998 	bufferRam = __MKUINT(infoBuffer.bufferram);
  7999         swapSize  = __MKUINT(infoBuffer.totalswap);
  7999 	swapSize  = __MKUINT(infoBuffer.totalswap);
  8000         freeSwap  = __MKUINT(infoBuffer.freeswap);
  8000 	freeSwap  = __MKUINT(infoBuffer.freeswap);
  8001     }
  8001     }
  8002 # endif
  8002 # endif
  8003 #endif /* LINUX */
  8003 #endif /* LINUX */
  8004 
  8004 
  8005 #if defined(hpux) && !defined(__GNUC__)
  8005 #if defined(hpux) && !defined(__GNUC__)
  8022     freeMemory         = __MKUINT(dynam_buf.psd_free/256*1024*1024);
  8022     freeMemory         = __MKUINT(dynam_buf.psd_free/256*1024*1024);
  8023 #endif
  8023 #endif
  8024 
  8024 
  8025 #if defined(HAS_UNAME)
  8025 #if defined(HAS_UNAME)
  8026     {
  8026     {
  8027         struct utsname ubuff;
  8027 	struct utsname ubuff;
  8028 
  8028 
  8029         if (uname(&ubuff) >= 0) {
  8029 	if (uname(&ubuff) >= 0) {
  8030             sys  = __MKSTRING(ubuff.sysname);
  8030 	    sys  = __MKSTRING(ubuff.sysname);
  8031             node = __MKSTRING(ubuff.nodename);
  8031 	    node = __MKSTRING(ubuff.nodename);
  8032             rel  = __MKSTRING(ubuff.release);
  8032 	    rel  = __MKSTRING(ubuff.release);
  8033             ver  = __MKSTRING(ubuff.version);
  8033 	    ver  = __MKSTRING(ubuff.version);
  8034             mach = __MKSTRING(ubuff.machine);
  8034 	    mach = __MKSTRING(ubuff.machine);
  8035 # if defined(HAS_UTS_DOMAINNAME) || defined(_GNU_SOURCE)
  8035 # if defined(HAS_UTS_DOMAINNAME) || defined(_GNU_SOURCE)
  8036             dom  = __MKSTRING(ubuff.domainname);
  8036 	    dom  = __MKSTRING(ubuff.domainname);
  8037 # endif /* no HAS_UTS_DOMAINNAME */
  8037 # endif /* no HAS_UTS_DOMAINNAME */
  8038         }
  8038 	}
  8039     }
  8039     }
  8040 
  8040 
  8041 #else /* no UNAME */
  8041 #else /* no UNAME */
  8042 
  8042 
  8043     /*
  8043     /*
  8046 #endif /* no UNAME */
  8046 #endif /* no UNAME */
  8047 
  8047 
  8048 #if defined(HAS_SYSINFO)
  8048 #if defined(HAS_SYSINFO)
  8049 # if defined(SI_ARCHITECTURE)
  8049 # if defined(SI_ARCHITECTURE)
  8050     if (arch == nil) {
  8050     if (arch == nil) {
  8051         char buffer[128];
  8051 	char buffer[128];
  8052 
  8052 
  8053         if (sysinfo(SI_ARCHITECTURE, buffer, sizeof(buffer))) {
  8053 	if (sysinfo(SI_ARCHITECTURE, buffer, sizeof(buffer))) {
  8054             arch = __MKSTRING(buffer);
  8054 	    arch = __MKSTRING(buffer);
  8055         }
  8055 	}
  8056     }
  8056     }
  8057 # endif /* SI_ARCHITECTURE */
  8057 # endif /* SI_ARCHITECTURE */
  8058 
  8058 
  8059 # if defined(SI_ISALIST)
  8059 # if defined(SI_ISALIST)
  8060     {
  8060     {
  8061         char buffer[128];
  8061 	char buffer[128];
  8062 
  8062 
  8063         if (sysinfo(SI_ISALIST, buffer, sizeof(buffer))) {
  8063 	if (sysinfo(SI_ISALIST, buffer, sizeof(buffer))) {
  8064             instructionSets = __MKSTRING(buffer);
  8064 	    instructionSets = __MKSTRING(buffer);
  8065         }
  8065 	}
  8066     }
  8066     }
  8067 # endif /* SI_ISALIST */
  8067 # endif /* SI_ISALIST */
  8068 
  8068 
  8069 # if defined(SI_PLATFORM)
  8069 # if defined(SI_PLATFORM)
  8070     {
  8070     {
  8071         char buffer[128];
  8071 	char buffer[128];
  8072 
  8072 
  8073         if (sysinfo(SI_PLATFORM, buffer, sizeof(buffer))) {
  8073 	if (sysinfo(SI_PLATFORM, buffer, sizeof(buffer))) {
  8074             platform = __MKSTRING(buffer);
  8074 	    platform = __MKSTRING(buffer);
  8075         }
  8075 	}
  8076     }
  8076     }
  8077 # endif /* SI_PLATFORM */
  8077 # endif /* SI_PLATFORM */
  8078 
  8078 
  8079 # if defined(SI_RELEASE)
  8079 # if defined(SI_RELEASE)
  8080     {
  8080     {
  8081         char buffer[128];
  8081 	char buffer[128];
  8082 
  8082 
  8083         if (sysinfo(SI_RELEASE, buffer, sizeof(buffer))) {
  8083 	if (sysinfo(SI_RELEASE, buffer, sizeof(buffer))) {
  8084             rel = __MKSTRING(buffer);
  8084 	    rel = __MKSTRING(buffer);
  8085         }
  8085 	}
  8086     }
  8086     }
  8087 # endif /* SI_RELEASE */
  8087 # endif /* SI_RELEASE */
  8088 #endif /* HAS_SYSINFO */
  8088 #endif /* HAS_SYSINFO */
  8089 
  8089 
  8090 #if defined(HAS_SYSCONF)
  8090 #if defined(HAS_SYSCONF)
  8091 # ifdef _SC_NPROCESSORS_ONLN
  8091 # ifdef _SC_NPROCESSORS_ONLN
  8092     {
  8092     {
  8093         long val;
  8093 	long val;
  8094 
  8094 
  8095         val = sysconf(_SC_NPROCESSORS_ONLN);
  8095 	val = sysconf(_SC_NPROCESSORS_ONLN);
  8096         if (val > 0) {
  8096 	if (val > 0) {
  8097             numberOfCPUs = __MKINT(val);
  8097 	    numberOfCPUs = __MKINT(val);
  8098         }
  8098 	}
  8099     }
  8099     }
  8100 # endif
  8100 # endif
  8101 # ifdef _SC_NPROCESSORS_CONF
  8101 # ifdef _SC_NPROCESSORS_CONF
  8102     {
  8102     {
  8103         long val;
  8103 	long val;
  8104 
  8104 
  8105         val = sysconf(_SC_NPROCESSORS_CONF);
  8105 	val = sysconf(_SC_NPROCESSORS_CONF);
  8106         if (val > 0) {
  8106 	if (val > 0) {
  8107             numberOfPhysicalCPUs = __MKINT(val);
  8107 	    numberOfPhysicalCPUs = __MKINT(val);
  8108         }
  8108 	}
  8109     }
  8109     }
  8110 # endif
  8110 # endif
  8111 
  8111 
  8112 # if defined(_SC_PAGESIZE)
  8112 # if defined(_SC_PAGESIZE)
  8113     {
  8113     {
  8114         long val;
  8114 	long val;
  8115 
  8115 
  8116         val = sysconf(_SC_PAGESIZE);
  8116 	val = sysconf(_SC_PAGESIZE);
  8117         if (val != -1) {
  8117 	if (val != -1) {
  8118             pageSize = __MKUINT(val);
  8118 	    pageSize = __MKUINT(val);
  8119         }
  8119 	}
  8120     }
  8120     }
  8121 # endif
  8121 # endif
  8122 
  8122 
  8123 # if defined(_SC_PHYS_PAGES)
  8123 # if defined(_SC_PHYS_PAGES)
  8124     {
  8124     {
  8125         long val;
  8125 	long val;
  8126 
  8126 
  8127         val = sysconf(_SC_PHYS_PAGES);
  8127 	val = sysconf(_SC_PHYS_PAGES);
  8128         if (val != -1) {
  8128 	if (val != -1) {
  8129             physicalPages = __MKUINT(val);
  8129 	    physicalPages = __MKUINT(val);
  8130         }
  8130 	}
  8131     }
  8131     }
  8132 # endif
  8132 # endif
  8133 
  8133 
  8134 # if defined(_SC_AVPHYS_PAGES)
  8134 # if defined(_SC_AVPHYS_PAGES)
  8135     {
  8135     {
  8136         long val;
  8136 	long val;
  8137 
  8137 
  8138         val = sysconf(_SC_AVPHYS_PAGES);
  8138 	val = sysconf(_SC_AVPHYS_PAGES);
  8139         if (val != -1) {
  8139 	if (val != -1) {
  8140             availablePages = __MKUINT(val);
  8140 	    availablePages = __MKUINT(val);
  8141         }
  8141 	}
  8142     }
  8142     }
  8143 # endif
  8143 # endif
  8144 
  8144 
  8145 # if defined(_SC_ICACHE_SZ)
  8145 # if defined(_SC_ICACHE_SZ)
  8146     {
  8146     {
  8147         long val;
  8147 	long val;
  8148 
  8148 
  8149         val = sysconf(_SC_ICACHE_SZ);
  8149 	val = sysconf(_SC_ICACHE_SZ);
  8150         if (val != -1) {
  8150 	if (val != -1) {
  8151             iCacheSize = __MKUINT(val);
  8151 	    iCacheSize = __MKUINT(val);
  8152         }
  8152 	}
  8153     }
  8153     }
  8154 # endif
  8154 # endif
  8155 
  8155 
  8156 # if defined(_SC_DCACHE_SZ)
  8156 # if defined(_SC_DCACHE_SZ)
  8157     {
  8157     {
  8158         long val;
  8158 	long val;
  8159 
  8159 
  8160         val = sysconf(_SC_DCACHE_SZ);
  8160 	val = sysconf(_SC_DCACHE_SZ);
  8161         if (val != -1) {
  8161 	if (val != -1) {
  8162             dCacheSize = __MKUINT(val);
  8162 	    dCacheSize = __MKUINT(val);
  8163         }
  8163 	}
  8164     }
  8164     }
  8165 # endif
  8165 # endif
  8166 #endif /* HAS_SYSCONF */
  8166 #endif /* HAS_SYSCONF */
  8167 
  8167 
  8168 #if defined(HAS_GETSYSINFO)
  8168 #if defined(HAS_GETSYSINFO)
  8169     {
  8169     {
  8170         INT index;
  8170 	INT index;
  8171         int retInt32 = 0;
  8171 	int retInt32 = 0;
  8172 
  8172 
  8173 # if defined(GSI_CPU)
  8173 # if defined(GSI_CPU)
  8174         index = 0;
  8174 	index = 0;
  8175         if (getsysinfo(GSI_CPU, &retInt32, sizeof(retInt32), &index, NULL) > 0) {
  8175 	if (getsysinfo(GSI_CPU, &retInt32, sizeof(retInt32), &index, NULL) > 0) {
  8176             switch (retInt32) {
  8176 	    switch (retInt32) {
  8177 #  ifdef VAX_780
  8177 #  ifdef VAX_780
  8178                 case VAX_780:
  8178 		case VAX_780:
  8179                     cpuType = __MKSTRING("VAX_780");
  8179 		    cpuType = __MKSTRING("VAX_780");
  8180                     break;
  8180 		    break;
  8181 #  endif
  8181 #  endif
  8182 #  ifdef VAX_750
  8182 #  ifdef VAX_750
  8183                 case VAX_750:
  8183 		case VAX_750:
  8184                     cpuType = __MKSTRING("VAX_750");
  8184 		    cpuType = __MKSTRING("VAX_750");
  8185                     break;
  8185 		    break;
  8186 #  endif
  8186 #  endif
  8187 #  ifdef VAX_730
  8187 #  ifdef VAX_730
  8188                 case VAX_730:
  8188 		case VAX_730:
  8189                     cpuType = __MKSTRING("VAX_730");
  8189 		    cpuType = __MKSTRING("VAX_730");
  8190                     break;
  8190 		    break;
  8191 #  endif
  8191 #  endif
  8192 #  ifdef VAX_8600
  8192 #  ifdef VAX_8600
  8193                 case VAX_8600:
  8193 		case VAX_8600:
  8194                     cpuType = __MKSTRING("VAX_8600");
  8194 		    cpuType = __MKSTRING("VAX_8600");
  8195                     break;
  8195 		    break;
  8196 #  endif
  8196 #  endif
  8197 #  ifdef VAX_8200
  8197 #  ifdef VAX_8200
  8198                 case VAX_8200:
  8198 		case VAX_8200:
  8199                     cpuType = __MKSTRING("VAX_8200");
  8199 		    cpuType = __MKSTRING("VAX_8200");
  8200                     break;
  8200 		    break;
  8201 #  endif
  8201 #  endif
  8202 #  ifdef VAX_8800
  8202 #  ifdef VAX_8800
  8203                 case VAX_8800:
  8203 		case VAX_8800:
  8204                     cpuType = __MKSTRING("VAX_8800");
  8204 		    cpuType = __MKSTRING("VAX_8800");
  8205                     break;
  8205 		    break;
  8206 #  endif
  8206 #  endif
  8207 #  ifdef MVAX_I
  8207 #  ifdef MVAX_I
  8208                 case MVAX_I:
  8208 		case MVAX_I:
  8209                     cpuType = __MKSTRING("MVAX_I");
  8209 		    cpuType = __MKSTRING("MVAX_I");
  8210                     break;
  8210 		    break;
  8211 #  endif
  8211 #  endif
  8212 #  ifdef MVAX_II
  8212 #  ifdef MVAX_II
  8213                 case MVAX_II:
  8213 		case MVAX_II:
  8214                     cpuType = __MKSTRING("MVAX_II");
  8214 		    cpuType = __MKSTRING("MVAX_II");
  8215                     break;
  8215 		    break;
  8216 #  endif
  8216 #  endif
  8217 #  ifdef V_VAX
  8217 #  ifdef V_VAX
  8218                 case V_VAX:
  8218 		case V_VAX:
  8219                     cpuType = __MKSTRING("V_VAX");
  8219 		    cpuType = __MKSTRING("V_VAX");
  8220                     break;
  8220 		    break;
  8221 #  endif
  8221 #  endif
  8222 #  ifdef VAX_3600
  8222 #  ifdef VAX_3600
  8223                 case VAX_3600:
  8223 		case VAX_3600:
  8224                     cpuType = __MKSTRING("VAX_3600");
  8224 		    cpuType = __MKSTRING("VAX_3600");
  8225                     break;
  8225 		    break;
  8226 #  endif
  8226 #  endif
  8227 #  ifdef VAX_6200
  8227 #  ifdef VAX_6200
  8228                 case VAX_6200:
  8228 		case VAX_6200:
  8229                     cpuType = __MKSTRING("VAX_6200");
  8229 		    cpuType = __MKSTRING("VAX_6200");
  8230                     break;
  8230 		    break;
  8231 #  endif
  8231 #  endif
  8232 #  ifdef VAX_3400
  8232 #  ifdef VAX_3400
  8233                 case VAX_3400:
  8233 		case VAX_3400:
  8234                     cpuType = __MKSTRING("VAX_3400");
  8234 		    cpuType = __MKSTRING("VAX_3400");
  8235                     break;
  8235 		    break;
  8236 #  endif
  8236 #  endif
  8237 #  ifdef C_VAXSTAR
  8237 #  ifdef C_VAXSTAR
  8238                 case C_VAXSTAR:
  8238 		case C_VAXSTAR:
  8239                     cpuType = __MKSTRING("C_VAXSTAR");
  8239 		    cpuType = __MKSTRING("C_VAXSTAR");
  8240                     break;
  8240 		    break;
  8241 #  endif
  8241 #  endif
  8242 #  ifdef VAX_60
  8242 #  ifdef VAX_60
  8243                 case VAX_60:
  8243 		case VAX_60:
  8244                     cpuType = __MKSTRING("VAX_60");
  8244 		    cpuType = __MKSTRING("VAX_60");
  8245                     break;
  8245 		    break;
  8246 #  endif
  8246 #  endif
  8247 #  ifdef VAX_3900
  8247 #  ifdef VAX_3900
  8248                 case VAX_3900:
  8248 		case VAX_3900:
  8249                     cpuType = __MKSTRING("VAX_3900");
  8249 		    cpuType = __MKSTRING("VAX_3900");
  8250                     break;
  8250 		    break;
  8251 #  endif
  8251 #  endif
  8252 #  ifdef DS_3100
  8252 #  ifdef DS_3100
  8253                 case DS_3100:
  8253 		case DS_3100:
  8254                     cpuType = __MKSTRING("DS_3100");
  8254 		    cpuType = __MKSTRING("DS_3100");
  8255                     break;
  8255 		    break;
  8256 #  endif
  8256 #  endif
  8257 #  ifdef VAX_8820
  8257 #  ifdef VAX_8820
  8258                 case VAX_8820:
  8258 		case VAX_8820:
  8259                     cpuType = __MKSTRING("VAX_8820");
  8259 		    cpuType = __MKSTRING("VAX_8820");
  8260                     break;
  8260 		    break;
  8261 #  endif
  8261 #  endif
  8262 #  ifdef DS_5400
  8262 #  ifdef DS_5400
  8263                 case DS_5400:
  8263 		case DS_5400:
  8264                     cpuType = __MKSTRING("DS_5400");
  8264 		    cpuType = __MKSTRING("DS_5400");
  8265                     break;
  8265 		    break;
  8266 #  endif
  8266 #  endif
  8267 #  ifdef DS_5800
  8267 #  ifdef DS_5800
  8268                 case DS_5800:
  8268 		case DS_5800:
  8269                     cpuType = __MKSTRING("DS_5800");
  8269 		    cpuType = __MKSTRING("DS_5800");
  8270                     break;
  8270 		    break;
  8271 #  endif
  8271 #  endif
  8272 #  ifdef DS_5000
  8272 #  ifdef DS_5000
  8273                 case DS_5000:
  8273 		case DS_5000:
  8274                     cpuType = __MKSTRING("DS_5000");
  8274 		    cpuType = __MKSTRING("DS_5000");
  8275                     break;
  8275 		    break;
  8276 #  endif
  8276 #  endif
  8277 #  ifdef DS_CMAX
  8277 #  ifdef DS_CMAX
  8278                 case DS_CMAX:
  8278 		case DS_CMAX:
  8279                     cpuType = __MKSTRING("DS_CMAX");
  8279 		    cpuType = __MKSTRING("DS_CMAX");
  8280                     break;
  8280 		    break;
  8281 #  endif
  8281 #  endif
  8282 #  ifdef VAX_6400
  8282 #  ifdef VAX_6400
  8283                 case VAX_6400:
  8283 		case VAX_6400:
  8284                     cpuType = __MKSTRING("VAX_6400");
  8284 		    cpuType = __MKSTRING("VAX_6400");
  8285                     break;
  8285 		    break;
  8286 #  endif
  8286 #  endif
  8287 #  ifdef VAXSTAR
  8287 #  ifdef VAXSTAR
  8288                 case VAXSTAR:
  8288 		case VAXSTAR:
  8289                     cpuType = __MKSTRING("VAXSTAR");
  8289 		    cpuType = __MKSTRING("VAXSTAR");
  8290                     break;
  8290 		    break;
  8291 #  endif
  8291 #  endif
  8292 #  ifdef DS_5500
  8292 #  ifdef DS_5500
  8293                 case DS_5500:
  8293 		case DS_5500:
  8294                     cpuType = __MKSTRING("DS_5500");
  8294 		    cpuType = __MKSTRING("DS_5500");
  8295                     break;
  8295 		    break;
  8296 #  endif
  8296 #  endif
  8297 #  ifdef DS_5100
  8297 #  ifdef DS_5100
  8298                 case DS_5100:
  8298 		case DS_5100:
  8299                     cpuType = __MKSTRING("DS_5100");
  8299 		    cpuType = __MKSTRING("DS_5100");
  8300                     break;
  8300 		    break;
  8301 #  endif
  8301 #  endif
  8302 #  ifdef VAX_9000
  8302 #  ifdef VAX_9000
  8303                 case VAX_9000:
  8303 		case VAX_9000:
  8304                     cpuType = __MKSTRING("VAX_9000");
  8304 		    cpuType = __MKSTRING("VAX_9000");
  8305                     break;
  8305 		    break;
  8306 #  endif
  8306 #  endif
  8307 #  ifdef DS_500_100
  8307 #  ifdef DS_500_100
  8308                 case DS_500_100:
  8308 		case DS_500_100:
  8309                     cpuType = __MKSTRING("DS_500_100");
  8309 		    cpuType = __MKSTRING("DS_500_100");
  8310                     break;
  8310 		    break;
  8311 #  endif
  8311 #  endif
  8312 
  8312 
  8313 
  8313 
  8314 #  ifdef ALPHA_ADU
  8314 #  ifdef ALPHA_ADU
  8315                 case ALPHA_ADU:
  8315 		case ALPHA_ADU:
  8316                     cpuType = __MKSTRING("ALPHA_ADU");
  8316 		    cpuType = __MKSTRING("ALPHA_ADU");
  8317                     break;
  8317 		    break;
  8318 #  endif
  8318 #  endif
  8319 #  ifdef DEC_4000
  8319 #  ifdef DEC_4000
  8320                 case DEC_4000:
  8320 		case DEC_4000:
  8321                     cpuType = __MKSTRING("DEC_4000");
  8321 		    cpuType = __MKSTRING("DEC_4000");
  8322                     break;
  8322 		    break;
  8323 #  endif
  8323 #  endif
  8324 #  ifdef DEC_3000_500
  8324 #  ifdef DEC_3000_500
  8325                 case DEC_3000_500:
  8325 		case DEC_3000_500:
  8326                     cpuType = __MKSTRING("DEC_3000_500");
  8326 		    cpuType = __MKSTRING("DEC_3000_500");
  8327                     break;
  8327 		    break;
  8328 #  endif
  8328 #  endif
  8329 #  ifdef DEC_7000
  8329 #  ifdef DEC_7000
  8330                 case DEC_7000:
  8330 		case DEC_7000:
  8331                     cpuType = __MKSTRING("DEC_7000");
  8331 		    cpuType = __MKSTRING("DEC_7000");
  8332                     break;
  8332 		    break;
  8333 #  endif
  8333 #  endif
  8334 #  ifdef DS_5000_300
  8334 #  ifdef DS_5000_300
  8335                 case DS_5000_300:
  8335 		case DS_5000_300:
  8336                     cpuType = __MKSTRING("DS_5000_300");
  8336 		    cpuType = __MKSTRING("DS_5000_300");
  8337                     break;
  8337 		    break;
  8338 #  endif
  8338 #  endif
  8339 #  ifdef DEC_3000_300
  8339 #  ifdef DEC_3000_300
  8340                 case DEC_3000_300:
  8340 		case DEC_3000_300:
  8341                     cpuType = __MKSTRING("DEC_3000_300");
  8341 		    cpuType = __MKSTRING("DEC_3000_300");
  8342                     break;
  8342 		    break;
  8343 #  endif
  8343 #  endif
  8344 #  ifdef DEC_2000_300
  8344 #  ifdef DEC_2000_300
  8345                 case DEC_2000_300:
  8345 		case DEC_2000_300:
  8346                     cpuType = __MKSTRING("DEC_2000_300");
  8346 		    cpuType = __MKSTRING("DEC_2000_300");
  8347                     break;
  8347 		    break;
  8348 #  endif
  8348 #  endif
  8349 #  ifdef DEC_2100_A500
  8349 #  ifdef DEC_2100_A500
  8350                 case DEC_2100_A500:
  8350 		case DEC_2100_A500:
  8351                     cpuType = __MKSTRING("DEC_2100_A500");
  8351 		    cpuType = __MKSTRING("DEC_2100_A500");
  8352                     break;
  8352 		    break;
  8353 #  endif
  8353 #  endif
  8354 #  ifdef DEC_2100_A50
  8354 #  ifdef DEC_2100_A50
  8355                 case DEC_2100_A50:
  8355 		case DEC_2100_A50:
  8356                     cpuType = __MKSTRING("DEC_2100_A50");
  8356 		    cpuType = __MKSTRING("DEC_2100_A50");
  8357                     break;
  8357 		    break;
  8358 #  endif
  8358 #  endif
  8359 #  ifdef ALPHA_KN20AA
  8359 #  ifdef ALPHA_KN20AA
  8360                 case ALPHA_KN20AA:
  8360 		case ALPHA_KN20AA:
  8361                     cpuType = __MKSTRING("ALPHA_KN20AA");
  8361 		    cpuType = __MKSTRING("ALPHA_KN20AA");
  8362                     break;
  8362 		    break;
  8363 #  endif
  8363 #  endif
  8364 #  ifdef DEC_21000
  8364 #  ifdef DEC_21000
  8365                 case DEC_21000:
  8365 		case DEC_21000:
  8366                     cpuType = __MKSTRING("DEC_21000");
  8366 		    cpuType = __MKSTRING("DEC_21000");
  8367                     break;
  8367 		    break;
  8368 #  endif
  8368 #  endif
  8369 #  ifdef DEC_AXPVME_64
  8369 #  ifdef DEC_AXPVME_64
  8370                 case DEC_AXPVME_64:
  8370 		case DEC_AXPVME_64:
  8371                     cpuType = __MKSTRING("DEC_AXPVME_64");
  8371 		    cpuType = __MKSTRING("DEC_AXPVME_64");
  8372                     break;
  8372 		    break;
  8373 #  endif
  8373 #  endif
  8374 #  ifdef DEC_2100_C500
  8374 #  ifdef DEC_2100_C500
  8375                 case DEC_2100_C500:
  8375 		case DEC_2100_C500:
  8376                     cpuType = __MKSTRING("DEC_2100_C500");
  8376 		    cpuType = __MKSTRING("DEC_2100_C500");
  8377                     break;
  8377 		    break;
  8378 #  endif
  8378 #  endif
  8379 #  ifdef DEC_AXPPCI_33
  8379 #  ifdef DEC_AXPPCI_33
  8380                 case DEC_AXPPCI_33:
  8380 		case DEC_AXPPCI_33:
  8381                     cpuType = __MKSTRING("DEC_AXPPCI_33");
  8381 		    cpuType = __MKSTRING("DEC_AXPPCI_33");
  8382                     break;
  8382 		    break;
  8383 #  endif
  8383 #  endif
  8384 #  ifdef DEC_1000
  8384 #  ifdef DEC_1000
  8385                 case DEC_1000:
  8385 		case DEC_1000:
  8386                     cpuType = __MKSTRING("DEC_1000");
  8386 		    cpuType = __MKSTRING("DEC_1000");
  8387                     break;
  8387 		    break;
  8388 #  endif
  8388 #  endif
  8389 #  ifdef EB64_PLUS
  8389 #  ifdef EB64_PLUS
  8390                 case EB64_PLUS:
  8390 		case EB64_PLUS:
  8391                     cpuType = __MKSTRING("EB64_PLUS");
  8391 		    cpuType = __MKSTRING("EB64_PLUS");
  8392                     break;
  8392 		    break;
  8393 #  endif
  8393 #  endif
  8394 #  ifdef LCA_EB66
  8394 #  ifdef LCA_EB66
  8395                 case LCA_EB66:
  8395 		case LCA_EB66:
  8396                     cpuType = __MKSTRING("LCA_EB66");
  8396 		    cpuType = __MKSTRING("LCA_EB66");
  8397                     break;
  8397 		    break;
  8398 #  endif
  8398 #  endif
  8399 #  ifdef ALPHA_EB164
  8399 #  ifdef ALPHA_EB164
  8400                 case ALPHA_EB164:
  8400 		case ALPHA_EB164:
  8401                     cpuType = __MKSTRING("ALPHA_EB164");
  8401 		    cpuType = __MKSTRING("ALPHA_EB164");
  8402                     break;
  8402 		    break;
  8403 #  endif
  8403 #  endif
  8404 #  ifdef DEC_EV45_PBP
  8404 #  ifdef DEC_EV45_PBP
  8405                 case DEC_EV45_PBP:
  8405 		case DEC_EV45_PBP:
  8406                     cpuType = __MKSTRING("DEC_EV45_PBP");
  8406 		    cpuType = __MKSTRING("DEC_EV45_PBP");
  8407                     break;
  8407 		    break;
  8408 #  endif
  8408 #  endif
  8409 #  ifdef DEC_1000A
  8409 #  ifdef DEC_1000A
  8410                 case DEC_1000A:
  8410 		case DEC_1000A:
  8411                     cpuType = __MKSTRING("DEC_1000A");
  8411 		    cpuType = __MKSTRING("DEC_1000A");
  8412                     break;
  8412 		    break;
  8413 #  endif
  8413 #  endif
  8414 #  ifdef DEC_4100
  8414 #  ifdef DEC_4100
  8415                 case DEC_4100:
  8415 		case DEC_4100:
  8416                     cpuType = __MKSTRING("DEC_4100");
  8416 		    cpuType = __MKSTRING("DEC_4100");
  8417                     break;
  8417 		    break;
  8418 #  endif
  8418 #  endif
  8419 #  ifdef DEC_ALPHAVME_224
  8419 #  ifdef DEC_ALPHAVME_224
  8420                 case DEC_ALPHAVME_224:
  8420 		case DEC_ALPHAVME_224:
  8421                     cpuType = __MKSTRING("DEC_ALPHAVME_224");
  8421 		    cpuType = __MKSTRING("DEC_ALPHAVME_224");
  8422                     break;
  8422 		    break;
  8423 #  endif
  8423 #  endif
  8424 #  ifdef DEC_1000_5
  8424 #  ifdef DEC_1000_5
  8425                 case DEC_1000_5:
  8425 		case DEC_1000_5:
  8426                     cpuType = __MKSTRING("DEC_1000_5");
  8426 		    cpuType = __MKSTRING("DEC_1000_5");
  8427                     break;
  8427 		    break;
  8428 #  endif
  8428 #  endif
  8429 #  ifdef DEC_1000A_5
  8429 #  ifdef DEC_1000A_5
  8430                 case DEC_1000A_5:
  8430 		case DEC_1000A_5:
  8431                     cpuType = __MKSTRING("DEC_1000A_5");
  8431 		    cpuType = __MKSTRING("DEC_1000A_5");
  8432                     break;
  8432 		    break;
  8433 #  endif
  8433 #  endif
  8434 #  ifdef DEC_EV56_PBP
  8434 #  ifdef DEC_EV56_PBP
  8435                 case DEC_EV56_PBP:
  8435 		case DEC_EV56_PBP:
  8436                     cpuType = __MKSTRING("DEC_EV56_PBP");
  8436 		    cpuType = __MKSTRING("DEC_EV56_PBP");
  8437                     break;
  8437 		    break;
  8438 #  endif
  8438 #  endif
  8439 #  ifdef ALPHABOOK
  8439 #  ifdef ALPHABOOK
  8440                 case ALPHABOOK:
  8440 		case ALPHABOOK:
  8441                     cpuType = __MKSTRING("ALPHABOOK");
  8441 		    cpuType = __MKSTRING("ALPHABOOK");
  8442                     break;
  8442 		    break;
  8443 #  endif
  8443 #  endif
  8444 #  ifdef DEC_ALPHAVME_320
  8444 #  ifdef DEC_ALPHAVME_320
  8445                 case DEC_ALPHAVME_320:
  8445 		case DEC_ALPHAVME_320:
  8446                     cpuType = __MKSTRING("DEC_ALPHAVME_320");
  8446 		    cpuType = __MKSTRING("DEC_ALPHAVME_320");
  8447                     break;
  8447 		    break;
  8448 #  endif
  8448 #  endif
  8449 #  ifdef DEC_550
  8449 #  ifdef DEC_550
  8450                 case DEC_550:
  8450 		case DEC_550:
  8451                     cpuType = __MKSTRING("DEC_550");
  8451 		    cpuType = __MKSTRING("DEC_550");
  8452                     break;
  8452 		    break;
  8453 #  endif
  8453 #  endif
  8454 #  ifdef DEC_6600
  8454 #  ifdef DEC_6600
  8455                 case DEC_6600:
  8455 		case DEC_6600:
  8456                     cpuType = __MKSTRING("DEC_6600");
  8456 		    cpuType = __MKSTRING("DEC_6600");
  8457                     break;
  8457 		    break;
  8458 #  endif
  8458 #  endif
  8459 #  ifdef UNKN_SYSTEM
  8459 #  ifdef UNKN_SYSTEM
  8460                 case UNKN_SYSTEM:
  8460 		case UNKN_SYSTEM:
  8461                     cpuType = __MKSTRING("UNKN_SYSTEM");
  8461 		    cpuType = __MKSTRING("UNKN_SYSTEM");
  8462                     break;
  8462 		    break;
  8463 #  endif
  8463 #  endif
  8464                 default:
  8464 		default:
  8465                     cpuType = __MKSTRING("OTHER_DEC_SYSTEM");
  8465 		    cpuType = __MKSTRING("OTHER_DEC_SYSTEM");
  8466                     break;
  8466 		    break;
  8467             }
  8467 	    }
  8468         }
  8468 	}
  8469 # endif /* GSI_CPU */
  8469 # endif /* GSI_CPU */
  8470 
  8470 
  8471 # if defined(GSI_CPU_INFO)
  8471 # if defined(GSI_CPU_INFO)
  8472         /*
  8472 	/*
  8473          * stupid: OSF1 pre V4.0 has no mhz, but V4.0 has it.
  8473 	 * stupid: OSF1 pre V4.0 has no mhz, but V4.0 has it.
  8474          * use the GSI_PLATFORM_NAME as a hint - it is only defined in
  8474 	 * use the GSI_PLATFORM_NAME as a hint - it is only defined in
  8475          * V4.0 and higher ... (sigh)
  8475 	 * V4.0 and higher ... (sigh)
  8476          */
  8476 	 */
  8477 #  if defined GSI_PLATFORM_NAME
  8477 #  if defined GSI_PLATFORM_NAME
  8478         {
  8478 	{
  8479             struct cpu_info cpuInfo;
  8479 	    struct cpu_info cpuInfo;
  8480 
  8480 
  8481             index = 0;
  8481 	    index = 0;
  8482             if (getsysinfo(GSI_CPU_INFO, &cpuInfo, sizeof(cpuInfo), &index, NULL) > 0) {
  8482 	    if (getsysinfo(GSI_CPU_INFO, &cpuInfo, sizeof(cpuInfo), &index, NULL) > 0) {
  8483                 cpuSpeed   = __MKUINT(cpuInfo.mhz);
  8483 		cpuSpeed   = __MKUINT(cpuInfo.mhz);
  8484             }
  8484 	    }
  8485         }
  8485 	}
  8486 #  endif
  8486 #  endif
  8487 # endif /* GSI_CPU_INFO */
  8487 # endif /* GSI_CPU_INFO */
  8488 
  8488 
  8489 # if defined(GSI_CPUS_IN_BOX)
  8489 # if defined(GSI_CPUS_IN_BOX)
  8490         index = 0;
  8490 	index = 0;
  8491         if (getsysinfo(GSI_CPUS_IN_BOX, &retInt32, sizeof(retInt32), &index, NULL) > 0) {
  8491 	if (getsysinfo(GSI_CPUS_IN_BOX, &retInt32, sizeof(retInt32), &index, NULL) > 0) {
  8492             numberOfCPUs   = __MKUINT(retInt32);
  8492 	    numberOfCPUs   = __MKUINT(retInt32);
  8493         }
  8493 	}
  8494 # endif /* GSI_CPUS_IN_BOX */
  8494 # endif /* GSI_CPUS_IN_BOX */
  8495 
  8495 
  8496 # if defined(GSI_PHYSMEM)
  8496 # if defined(GSI_PHYSMEM)
  8497         index = 0;
  8497 	index = 0;
  8498         if (getsysinfo(GSI_PHYSMEM, &retInt32, sizeof(retInt32), &index, NULL) > 0) {
  8498 	if (getsysinfo(GSI_PHYSMEM, &retInt32, sizeof(retInt32), &index, NULL) > 0) {
  8499             INT bytes = retInt32 * 1024;
  8499 	    INT bytes = retInt32 * 1024;
  8500 
  8500 
  8501             physicalRam   = __MKUINT(bytes);
  8501 	    physicalRam   = __MKUINT(bytes);
  8502         }
  8502 	}
  8503 # endif /* GSI_PHYSMEM */
  8503 # endif /* GSI_PHYSMEM */
  8504 
  8504 
  8505 # if defined(GSI_PLATFORM_NAME) && (!defined(HAS_SYSINFO) || !defined(SI_PLATFORM))
  8505 # if defined(GSI_PLATFORM_NAME) && (!defined(HAS_SYSINFO) || !defined(SI_PLATFORM))
  8506     {
  8506     {
  8507         char buffer[128];
  8507 	char buffer[128];
  8508 
  8508 
  8509         index = 0;
  8509 	index = 0;
  8510         if (getsysinfo(GSI_PLATFORM_NAME, buffer, sizeof(buffer), &index, NULL) > 0) {
  8510 	if (getsysinfo(GSI_PLATFORM_NAME, buffer, sizeof(buffer), &index, NULL) > 0) {
  8511             platform = __MKSTRING(buffer);
  8511 	    platform = __MKSTRING(buffer);
  8512         }
  8512 	}
  8513     }
  8513     }
  8514 # endif /* GSI_PLATFORM_NAME */
  8514 # endif /* GSI_PLATFORM_NAME */
  8515 
  8515 
  8516     }
  8516     }
  8517 #endif /* HAS_GETSYSINFO */
  8517 #endif /* HAS_GETSYSINFO */
  8532     cpuType = __MKSTRING("x86_64");
  8532     cpuType = __MKSTRING("x86_64");
  8533 #endif
  8533 #endif
  8534 
  8534 
  8535 
  8535 
  8536     {
  8536     {
  8537         extern OBJ __getInstructionSetInfo();
  8537 	extern OBJ __getInstructionSetInfo();
  8538 
  8538 
  8539         extendedInstructions = __getInstructionSetInfo();
  8539 	extendedInstructions = __getInstructionSetInfo();
  8540     }
  8540     }
  8541 %}.
  8541 %}.
  8542     sys isNil ifTrue:[
  8542     sys isNil ifTrue:[
  8543         sys := self getSystemType.
  8543 	sys := self getSystemType.
  8544     ].
  8544     ].
  8545     node isNil ifTrue:[
  8545     node isNil ifTrue:[
  8546         node := self getHostName.
  8546 	node := self getHostName.
  8547     ].
  8547     ].
  8548     dom isNil ifTrue:[
  8548     dom isNil ifTrue:[
  8549         dom := self getDomainName.
  8549 	dom := self getDomainName.
  8550     ].
  8550     ].
  8551     mach isNil ifTrue:[
  8551     mach isNil ifTrue:[
  8552         mach := self getCPUType.
  8552 	mach := self getCPUType.
  8553     ].
  8553     ].
  8554     arch isNil ifTrue:[
  8554     arch isNil ifTrue:[
  8555         arch := sys.
  8555 	arch := sys.
  8556     ].
  8556     ].
  8557 
  8557 
  8558     info := IdentityDictionary new.
  8558     info := IdentityDictionary new.
  8559     info at:#system put:sys.
  8559     info at:#system put:sys.
  8560     info at:#node put:node.
  8560     info at:#node put:node.
  8562     ver notNil ifTrue:[info at:#version put:ver].
  8562     ver notNil ifTrue:[info at:#version put:ver].
  8563     mach notNil ifTrue:[info at:#machine put:mach].
  8563     mach notNil ifTrue:[info at:#machine put:mach].
  8564     arch notNil ifTrue:[info at:#architecture put:arch].
  8564     arch notNil ifTrue:[info at:#architecture put:arch].
  8565     dom notNil ifTrue:[info at:#domain put:dom].
  8565     dom notNil ifTrue:[info at:#domain put:dom].
  8566     (pageSize notNil and:[physicalPages notNil]) ifTrue:[
  8566     (pageSize notNil and:[physicalPages notNil]) ifTrue:[
  8567         physicalRam := pageSize * physicalPages. "/ done here - could be largeInt.
  8567 	physicalRam := pageSize * physicalPages. "/ done here - could be largeInt.
  8568     ].
  8568     ].
  8569     physicalRam notNil ifTrue:[info at:#physicalRam put:physicalRam].
  8569     physicalRam notNil ifTrue:[info at:#physicalRam put:physicalRam].
  8570     (pageSize notNil and:[availablePages notNil]) ifTrue:[
  8570     (pageSize notNil and:[availablePages notNil]) ifTrue:[
  8571         availableRam := pageSize * availablePages. "/ done here - could be largeInt.
  8571 	availableRam := pageSize * availablePages. "/ done here - could be largeInt.
  8572         availableRam notNil ifTrue:[info at:#availableRam put:availableRam].
  8572 	availableRam notNil ifTrue:[info at:#availableRam put:availableRam].
  8573     ].
  8573     ].
  8574     totalRam notNil ifTrue:[info at:#totalRam put:totalRam].
  8574     totalRam notNil ifTrue:[info at:#totalRam put:totalRam].
  8575     sharedRam notNil ifTrue:[info at:#sharedRam put:sharedRam].
  8575     sharedRam notNil ifTrue:[info at:#sharedRam put:sharedRam].
  8576     bufferRam notNil ifTrue:[info at:#bufferRam put:bufferRam].
  8576     bufferRam notNil ifTrue:[info at:#bufferRam put:bufferRam].
  8577     virtualRam notNil ifTrue:[info at:#virtualRam put:virtualRam].
  8577     virtualRam notNil ifTrue:[info at:#virtualRam put:virtualRam].
  8622 #    undef SYS_SYMBOL
  8622 #    undef SYS_SYMBOL
  8623 #   endif
  8623 #   endif
  8624 
  8624 
  8625 %}.
  8625 %}.
  8626     sys isNil ifTrue:[
  8626     sys isNil ifTrue:[
  8627         ^ self getOSType
  8627 	^ self getOSType
  8628     ].
  8628     ].
  8629     ^ sys
  8629     ^ sys
  8630 
  8630 
  8631     "
  8631     "
  8632      OperatingSystem getSystemType
  8632      OperatingSystem getSystemType
  8649     "
  8649     "
  8650 !
  8650 !
  8651 
  8651 
  8652 isLinuxLike
  8652 isLinuxLike
  8653     "return true, if the OS we're running on is a linux."
  8653     "return true, if the OS we're running on is a linux."
  8654     
  8654 
  8655     
  8655 
  8656 %{  /* NOCONTEXT */
  8656 %{  /* NOCONTEXT */
  8657 
  8657 
  8658 #if defined(LINUX)
  8658 #if defined(LINUX)
  8659     RETURN ( true );
  8659     RETURN ( true );
  8660 #endif
  8660 #endif
  8685 isProcessIdPresent:pid
  8685 isProcessIdPresent:pid
  8686     "answer true, if a process with process id pid is present, false if not"
  8686     "answer true, if a process with process id pid is present, false if not"
  8687 
  8687 
  8688 %{
  8688 %{
  8689     if (__isSmallInteger(pid)) {
  8689     if (__isSmallInteger(pid)) {
  8690         /* in UNIX, a kill(pid, 0) is a noop used to check if a pid exists */
  8690 	/* in UNIX, a kill(pid, 0) is a noop used to check if a pid exists */
  8691         if (kill(__smallIntegerVal(pid), 0) < 0 && errno != EPERM) {
  8691 	if (kill(__smallIntegerVal(pid), 0) < 0 && errno != EPERM) {
  8692             RETURN ( false );
  8692 	    RETURN ( false );
  8693         }
  8693 	}
  8694         RETURN ( true );
  8694 	RETURN ( true );
  8695     }
  8695     }
  8696 %}.
  8696 %}.
  8697 
  8697 
  8698     ^ self primitiveFailed:#invalidParameter
  8698     ^ self primitiveFailed:#invalidParameter
  8699 
  8699 
  8716 !
  8716 !
  8717 
  8717 
  8718 maxFileNameLength
  8718 maxFileNameLength
  8719     "return the max number of characters in a filename.
  8719     "return the max number of characters in a filename.
  8720      CAVEAT:
  8720      CAVEAT:
  8721          Actually, the following is somewhat wrong - some systems
  8721 	 Actually, the following is somewhat wrong - some systems
  8722          support different sizes, depending on the volume.
  8722 	 support different sizes, depending on the volume.
  8723          We return a somewhat conservative number here.
  8723 	 We return a somewhat conservative number here.
  8724          Another entry, to query for volume specific max
  8724 	 Another entry, to query for volume specific max
  8725          will be added in the future."
  8725 	 will be added in the future."
  8726 
  8726 
  8727 %{  /* NOCONTEXT */
  8727 %{  /* NOCONTEXT */
  8728 
  8728 
  8729     /*
  8729     /*
  8730      * TODO: new systems provide a query function for this ... use it
  8730      * TODO: new systems provide a query function for this ... use it
  8759 %{
  8759 %{
  8760      long l;
  8760      long l;
  8761 
  8761 
  8762      l = sysconf(_SC_OPEN_MAX);
  8762      l = sysconf(_SC_OPEN_MAX);
  8763      if (l >= 0) {
  8763      if (l >= 0) {
  8764          RETURN(__mkSmallInteger(l));
  8764 	 RETURN(__mkSmallInteger(l));
  8765      }
  8765      }
  8766 %}.
  8766 %}.
  8767      self primitiveFailed
  8767      self primitiveFailed
  8768 
  8768 
  8769      "
  8769      "
  8792 !
  8792 !
  8793 
  8793 
  8794 primGetDomainName
  8794 primGetDomainName
  8795     "return the domain this host is in.
  8795     "return the domain this host is in.
  8796      Notice:
  8796      Notice:
  8797         not all systems support this; on some, nil is returned."
  8797 	not all systems support this; on some, nil is returned."
  8798 
  8798 
  8799 %{  /* STACK: 2048 */
  8799 %{  /* STACK: 2048 */
  8800 #if defined(HAS_GETDOMAINNAME)
  8800 #if defined(HAS_GETDOMAINNAME)
  8801     char buffer[256];
  8801     char buffer[256];
  8802 
  8802 
  8803     if (getdomainname(buffer, sizeof(buffer)) == 0) {
  8803     if (getdomainname(buffer, sizeof(buffer)) == 0) {
  8804         RETURN (__MKSTRING(buffer));
  8804 	RETURN (__MKSTRING(buffer));
  8805     }
  8805     }
  8806 #else
  8806 #else
  8807 # if defined(HAS_UNAME) && defined(HAS_UTS_DOMAINNAME)
  8807 # if defined(HAS_UNAME) && defined(HAS_UTS_DOMAINNAME)
  8808     struct utsname ubuff;
  8808     struct utsname ubuff;
  8809 
  8809 
  8810     if (uname(&ubuff) >= 0) {
  8810     if (uname(&ubuff) >= 0) {
  8811         RETURN (__MKSTRING(ubuff.domainname));
  8811 	RETURN (__MKSTRING(ubuff.domainname));
  8812     }
  8812     }
  8813 # else
  8813 # else
  8814 #  if defined(HAS_SYSINFO) && defined(SI_SRPC_DOMAIN)
  8814 #  if defined(HAS_SYSINFO) && defined(SI_SRPC_DOMAIN)
  8815     char buffer[256];
  8815     char buffer[256];
  8816     int ret;
  8816     int ret;
  8817 
  8817 
  8818     if ((ret = sysinfo(SI_SRPC_DOMAIN, buffer, sizeof(buffer))) >= 0 && ret <= sizeof(buffer)) {
  8818     if ((ret = sysinfo(SI_SRPC_DOMAIN, buffer, sizeof(buffer))) >= 0 && ret <= sizeof(buffer)) {
  8819         RETURN (__MKSTRING(buffer));
  8819 	RETURN (__MKSTRING(buffer));
  8820     }
  8820     }
  8821 #  endif
  8821 #  endif
  8822 # endif
  8822 # endif
  8823 #endif
  8823 #endif
  8824 %}.
  8824 %}.
  8833 
  8833 
  8834 primGetHostName
  8834 primGetHostName
  8835     "return the hostname we are running on - if there is
  8835     "return the hostname we are running on - if there is
  8836      a HOST environment variable, we are much faster here ...
  8836      a HOST environment variable, we are much faster here ...
  8837      Notice:
  8837      Notice:
  8838         not all systems support this; on some, nil is returned."
  8838 	not all systems support this; on some, nil is returned."
  8839 
  8839 
  8840 %{  /* STACK: 100000 */
  8840 %{  /* STACK: 100000 */
  8841 
  8841 
  8842     /* sigh - with libc.so.6, gethostname needs huge amounts of stack
  8842     /* sigh - with libc.so.6, gethostname needs huge amounts of stack
  8843      * actually this is linux specific, but should not hurt others
  8843      * actually this is linux specific, but should not hurt others
  8844      */
  8844      */
  8845 #if defined(HAS_GETHOSTNAME)
  8845 #if defined(HAS_GETHOSTNAME)
  8846     char buffer[256];
  8846     char buffer[256];
  8847 
  8847 
  8848     if (gethostname(buffer, sizeof(buffer)) == 0) {
  8848     if (gethostname(buffer, sizeof(buffer)) == 0) {
  8849         RETURN (__MKSTRING(buffer));
  8849 	RETURN (__MKSTRING(buffer));
  8850     }
  8850     }
  8851 #else
  8851 #else
  8852 # if defined(HAS_UNAME)
  8852 # if defined(HAS_UNAME)
  8853     struct utsname ubuff;
  8853     struct utsname ubuff;
  8854 
  8854 
  8855     if (uname(&ubuff) >= 0) {
  8855     if (uname(&ubuff) >= 0) {
  8856         RETURN (__MKSTRING(ubuff.nodename));
  8856 	RETURN (__MKSTRING(ubuff.nodename));
  8857     }
  8857     }
  8858 # else
  8858 # else
  8859 #  if defined(HAS_SYSINFO) && defined(SI_HOSTNAME)
  8859 #  if defined(HAS_SYSINFO) && defined(SI_HOSTNAME)
  8860     char buffer[256];
  8860     char buffer[256];
  8861     int ret;
  8861     int ret;
  8862 
  8862 
  8863     if ((ret = sysinfo(SI_HOSTNAME, buffer, sizeof(buffer))) >= 0 && ret <= sizeof(buffer)) {
  8863     if ((ret = sysinfo(SI_HOSTNAME, buffer, sizeof(buffer))) >= 0 && ret <= sizeof(buffer)) {
  8864         RETURN (__MKSTRING(buffer));
  8864 	RETURN (__MKSTRING(buffer));
  8865     }
  8865     }
  8866 #  endif
  8866 #  endif
  8867 # endif
  8867 # endif
  8868 #endif
  8868 #endif
  8869 %}.
  8869 %}.
  8874     "
  8874     "
  8875 !
  8875 !
  8876 
  8876 
  8877 randomBytesInto:bufferOrInteger
  8877 randomBytesInto:bufferOrInteger
  8878     "If bufferOrInteger is a String or a ByteArray,
  8878     "If bufferOrInteger is a String or a ByteArray,
  8879         fill a given buffer with random bytes from the RtlGenRandom function
  8879 	fill a given buffer with random bytes from the RtlGenRandom function
  8880         and answer the buffer.
  8880 	and answer the buffer.
  8881 
  8881 
  8882      If bufferOrInteger is a SmallInteger,
  8882      If bufferOrInteger is a SmallInteger,
  8883         return this many bytes (max 4) as a SmallInteger.
  8883 	return this many bytes (max 4) as a SmallInteger.
  8884 
  8884 
  8885      Return nil on error (may raise PrimitiveFailure, too).
  8885      Return nil on error (may raise PrimitiveFailure, too).
  8886 
  8886 
  8887      NOTE: This is a private interface, please use RandomGenerator!!"
  8887      NOTE: This is a private interface, please use RandomGenerator!!"
  8888 
  8888 
  8894 
  8894 
  8895     int wanted, cnt, gotSoFar = 0;
  8895     int wanted, cnt, gotSoFar = 0;
  8896     char *buffer;
  8896     char *buffer;
  8897 
  8897 
  8898     if (__isSmallInteger(bufferOrInteger) && (wanted = __smallIntegerVal(bufferOrInteger) <= 4)) {
  8898     if (__isSmallInteger(bufferOrInteger) && (wanted = __smallIntegerVal(bufferOrInteger) <= 4)) {
  8899         int buf = 0;
  8899 	int buf = 0;
  8900 
  8900 
  8901         do {
  8901 	do {
  8902             cnt = getrandom(&buf + gotSoFar, wanted - gotSoFar, 0);
  8902 	    cnt = getrandom(&buf + gotSoFar, wanted - gotSoFar, 0);
  8903             if (cnt < 0) {
  8903 	    if (cnt < 0) {
  8904                 if (errno != EINTR && errno != EAGAIN))
  8904 		if (errno != EINTR && errno != EAGAIN))
  8905                     goto error;
  8905 		    goto error;
  8906             } else {
  8906 	    } else {
  8907                 gotSoFar = gotSoFar + cnt;
  8907 		gotSoFar = gotSoFar + cnt;
  8908             }
  8908 	    }
  8909         } while (gotSoFar < wanted);
  8909 	} while (gotSoFar < wanted);
  8910         RETURN(__mkSmallInteger(buf));
  8910 	RETURN(__mkSmallInteger(buf));
  8911     } else if (__isByteArray(bufferOrinteger)) {
  8911     } else if (__isByteArray(bufferOrinteger)) {
  8912         wanted = __byteArraySize(bufferOrinteger);
  8912 	wanted = __byteArraySize(bufferOrinteger);
  8913         buffer = __byteArrayVal(bufferOrinteger);
  8913 	buffer = __byteArrayVal(bufferOrinteger);
  8914     } else if (__isString(bufferOrinteger)) {
  8914     } else if (__isString(bufferOrinteger)) {
  8915         wanted = __stringSize(bufferOrinteger);
  8915 	wanted = __stringSize(bufferOrinteger);
  8916         buffer = __stringVal(bufferOrinteger);
  8916 	buffer = __stringVal(bufferOrinteger);
  8917     } else
  8917     } else
  8918         goto error;
  8918 	goto error;
  8919 
  8919 
  8920     do {
  8920     do {
  8921         cnt = getrandom(buffer + gotSoFar, wanted - gotSoFar, 0);
  8921 	cnt = getrandom(buffer + gotSoFar, wanted - gotSoFar, 0);
  8922         if (cnt < 0) {
  8922 	if (cnt < 0) {
  8923             if (errno != EINTR && errno != EAGAIN))
  8923 	    if (errno != EINTR && errno != EAGAIN))
  8924                 goto error;
  8924 		goto error;
  8925             buffer = __isByteArray(bufferOrinteger) ?
  8925 	    buffer = __isByteArray(bufferOrinteger) ?
  8926                         __byteArrayVal(bufferOrinteger) : __stringVal(bufferOrinteger);
  8926 			__byteArrayVal(bufferOrinteger) : __stringVal(bufferOrinteger);
  8927         } else {
  8927 	} else {
  8928             gotSoFar = gotSoFar + cnt;
  8928 	    gotSoFar = gotSoFar + cnt;
  8929         }
  8929 	}
  8930     } while (gotSoFar < wanted);
  8930     } while (gotSoFar < wanted);
  8931     RETURN(bufferOrinteger);
  8931     RETURN(bufferOrinteger);
  8932 
  8932 
  8933 # endif // linux
  8933 # endif // linux
  8934 #endif  // GRND_RANDOM
  8934 #endif  // GRND_RANDOM
  8936 %}.
  8936 %}.
  8937 
  8937 
  8938     ^ self primitiveFailed.
  8938     ^ self primitiveFailed.
  8939 
  8939 
  8940     "
  8940     "
  8941         self randomBytesInto:2.
  8941 	self randomBytesInto:2.
  8942         self randomBytesInto:(ByteArray new:16).
  8942 	self randomBytesInto:(ByteArray new:16).
  8943         self randomBytesInto:(String new:16).
  8943 	self randomBytesInto:(String new:16).
  8944     "
  8944     "
  8945 !
  8945 !
  8946 
  8946 
  8947 setEnvironment:aKeyStringOrSymbol to:aString
  8947 setEnvironment:aKeyStringOrSymbol to:aString
  8948     "put a string to the environment.
  8948     "put a string to the environment.
  8955 
  8955 
  8956     char *env;
  8956     char *env;
  8957     int valueSize;
  8957     int valueSize;
  8958 
  8958 
  8959     if (__isStringLike(aKeyStringOrSymbol)) {
  8959     if (__isStringLike(aKeyStringOrSymbol)) {
  8960         if (aString == nil) {
  8960 	if (aString == nil) {
  8961             /* env used only temporary for deregistration */
  8961 	    /* env used only temporary for deregistration */
  8962             valueSize = 0;
  8962 	    valueSize = 0;
  8963             env = __stringVal(aKeyStringOrSymbol);
  8963 	    env = __stringVal(aKeyStringOrSymbol);
  8964         } else if (__isStringLike(aString)) {
  8964 	} else if (__isStringLike(aString)) {
  8965             /* have to use stable memory for env */
  8965 	    /* have to use stable memory for env */
  8966             valueSize = __stringSize(aString);
  8966 	    valueSize = __stringSize(aString);
  8967             env = (char *)malloc(__stringSize(aKeyStringOrSymbol) + valueSize + 2);
  8967 	    env = (char *)malloc(__stringSize(aKeyStringOrSymbol) + valueSize + 2);
  8968             if (env == 0)
  8968 	    if (env == 0)
  8969                 goto err;
  8969 		goto err;
  8970             strcpy(env, __stringVal(aKeyStringOrSymbol));
  8970 	    strcpy(env, __stringVal(aKeyStringOrSymbol));
  8971             strcat(env, "=");
  8971 	    strcat(env, "=");
  8972             strncat(env, __stringVal(aString), valueSize);
  8972 	    strncat(env, __stringVal(aString), valueSize);
  8973         } else
  8973 	} else
  8974             goto err;
  8974 	    goto err;
  8975 
  8975 
  8976         if (putenv(env) == 0) {
  8976 	if (putenv(env) == 0) {
  8977             RETURN(self);
  8977 	    RETURN(self);
  8978         }
  8978 	}
  8979 
  8979 
  8980         if (valueSize > 0) {
  8980 	if (valueSize > 0) {
  8981             /* could not register, free */
  8981 	    /* could not register, free */
  8982             free(env);
  8982 	    free(env);
  8983         }
  8983 	}
  8984 err:;
  8984 err:;
  8985     }
  8985     }
  8986 %}.
  8986 %}.
  8987     ^ self primitiveFailed
  8987     ^ self primitiveFailed
  8988 
  8988 
  9011 %{
  9011 %{
  9012     int __category;
  9012     int __category;
  9013     char *__locale, *ret;
  9013     char *__locale, *ret;
  9014 
  9014 
  9015     if (categorySymbol == @symbol(LC_ALL)) {
  9015     if (categorySymbol == @symbol(LC_ALL)) {
  9016         __category = LC_ALL;
  9016 	__category = LC_ALL;
  9017     } else if (categorySymbol == @symbol(LC_COLLATE)) {
  9017     } else if (categorySymbol == @symbol(LC_COLLATE)) {
  9018         __category = LC_COLLATE;
  9018 	__category = LC_COLLATE;
  9019     } else if (categorySymbol == @symbol(LC_CTYPE)) {
  9019     } else if (categorySymbol == @symbol(LC_CTYPE)) {
  9020         __category = LC_CTYPE;
  9020 	__category = LC_CTYPE;
  9021     } else if (categorySymbol == @symbol(LC_MESSAGES)) {
  9021     } else if (categorySymbol == @symbol(LC_MESSAGES)) {
  9022         __category = LC_MESSAGES;
  9022 	__category = LC_MESSAGES;
  9023     } else if (categorySymbol == @symbol(LC_MONETARY)) {
  9023     } else if (categorySymbol == @symbol(LC_MONETARY)) {
  9024         __category = LC_MONETARY;
  9024 	__category = LC_MONETARY;
  9025     } else if (categorySymbol == @symbol(LC_NUMERIC)) {
  9025     } else if (categorySymbol == @symbol(LC_NUMERIC)) {
  9026         __category = LC_NUMERIC;
  9026 	__category = LC_NUMERIC;
  9027     } else if (categorySymbol == @symbol(LC_TIME)) {
  9027     } else if (categorySymbol == @symbol(LC_TIME)) {
  9028         __category = LC_TIME;
  9028 	__category = LC_TIME;
  9029     } else {
  9029     } else {
  9030         error = @symbol(argument1);
  9030 	error = @symbol(argument1);
  9031         goto out;
  9031 	goto out;
  9032     }
  9032     }
  9033 
  9033 
  9034     if (localeStringOrNil == nil) {
  9034     if (localeStringOrNil == nil) {
  9035         __locale = 0;
  9035 	__locale = 0;
  9036     } else if (__isStringLike(localeStringOrNil)){
  9036     } else if (__isStringLike(localeStringOrNil)){
  9037         __locale = __stringVal(localeStringOrNil);
  9037 	__locale = __stringVal(localeStringOrNil);
  9038     } else {
  9038     } else {
  9039         error = @symbol(argument1);
  9039 	error = @symbol(argument1);
  9040         goto out;
  9040 	goto out;
  9041     }
  9041     }
  9042 
  9042 
  9043     ret = setlocale(__category, __locale);
  9043     ret = setlocale(__category, __locale);
  9044     if (ret) {
  9044     if (ret) {
  9045         locale = __MKSTRING(ret);
  9045 	locale = __MKSTRING(ret);
  9046     }
  9046     }
  9047 
  9047 
  9048 out:;
  9048 out:;
  9049 %}.
  9049 %}.
  9050     locale notNil ifTrue:[
  9050     locale notNil ifTrue:[
  9051         ^ locale.
  9051 	^ locale.
  9052     ].
  9052     ].
  9053     ^ self primitiveFailed:error.
  9053     ^ self primitiveFailed:error.
  9054 
  9054 
  9055     "
  9055     "
  9056      OperatingSystem setLocale:#LC_ALL to:nil
  9056      OperatingSystem setLocale:#LC_ALL to:nil
  9184      E.g. linux system calls return single byte strings only,
  9184      E.g. linux system calls return single byte strings only,
  9185      so pathNames and command output comes UTF-8 encoded.
  9185      so pathNames and command output comes UTF-8 encoded.
  9186      (actually, on a mac, it comes utf8-mac encoded)."
  9186      (actually, on a mac, it comes utf8-mac encoded)."
  9187 
  9187 
  9188     Codeset notNil ifTrue:[
  9188     Codeset notNil ifTrue:[
  9189         encodedPathNameOrOutputLine notNil ifTrue:[
  9189 	encodedPathNameOrOutputLine notNil ifTrue:[
  9190             [
  9190 	    [
  9191                 "/ cg: I am not sure, why this shortcut.
  9191 		"/ cg: I am not sure, why this shortcut.
  9192                 "/ calling the decoder directly should be much faster
  9192 		"/ calling the decoder directly should be much faster
  9193                 Codeset == #utf8 ifTrue:[
  9193 		Codeset == #utf8 ifTrue:[
  9194                     ^ encodedPathNameOrOutputLine utf8Decoded.
  9194 		    ^ encodedPathNameOrOutputLine utf8Decoded.
  9195                 ].
  9195 		].
  9196                 "/ Codeset encoder might not yet be initialized, sigh...
  9196 		"/ Codeset encoder might not yet be initialized, sigh...
  9197                 CodesetEncoder isNil ifTrue:[
  9197 		CodesetEncoder isNil ifTrue:[
  9198                     self getCodesetEncoder
  9198 		    self getCodesetEncoder
  9199                 ].
  9199 		].
  9200                 CodesetEncoder notNil ifTrue:[
  9200 		CodesetEncoder notNil ifTrue:[
  9201                     ^ CodesetEncoder decodeString: encodedPathNameOrOutputLine
  9201 		    ^ CodesetEncoder decodeString: encodedPathNameOrOutputLine
  9202                 ].
  9202 		].
  9203             ] on:InvalidEncodingError do:[:ex|
  9203 	    ] on:InvalidEncodingError do:[:ex|
  9204                 "maybe there are old filenames in ISO8859-x,
  9204 		"maybe there are old filenames in ISO8859-x,
  9205                  just keep them untranslated"
  9205 		 just keep them untranslated"
  9206             ].
  9206 	    ].
  9207         ].
  9207 	].
  9208     ].
  9208     ].
  9209     ^ encodedPathNameOrOutputLine
  9209     ^ encodedPathNameOrOutputLine
  9210 
  9210 
  9211     "Modified: / 23-01-2013 / 10:02:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  9211     "Modified: / 23-01-2013 / 10:02:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  9212 !
  9212 !
  9221     minorVersionNr := Smalltalk minorVersionNr.
  9221     minorVersionNr := Smalltalk minorVersionNr.
  9222     vsnDirName := '%1.%2' bindWith:majorVersionNr with:minorVersionNr.
  9222     vsnDirName := '%1.%2' bindWith:majorVersionNr with:minorVersionNr.
  9223 
  9223 
  9224     sysPath := super defaultSystemPath.
  9224     sysPath := super defaultSystemPath.
  9225     places :=
  9225     places :=
  9226         #(
  9226 	#(
  9227             '/usr/local/lib/stx'
  9227 	    '/usr/local/lib/stx'
  9228             '/usr/local/lib/smalltalk'
  9228 	    '/usr/local/lib/smalltalk'
  9229             '/usr/local/lib/smalltalk-x'
  9229 	    '/usr/local/lib/smalltalk-x'
  9230             '/usr/lib/stx'
  9230 	    '/usr/lib/stx'
  9231             '/usr/lib/smalltalk'
  9231 	    '/usr/lib/smalltalk'
  9232             '/usr/lib/smalltalk-x'
  9232 	    '/usr/lib/smalltalk-x'
  9233             '/lib/stx'
  9233 	    '/lib/stx'
  9234             '/lib/smalltalk'
  9234 	    '/lib/smalltalk'
  9235             '/lib/smalltalk-x'
  9235 	    '/lib/smalltalk-x'
  9236             '/opt/stx'
  9236 	    '/opt/stx'
  9237             '/opt/smalltalk'
  9237 	    '/opt/smalltalk'
  9238             '/opt/smalltalk-x'
  9238 	    '/opt/smalltalk-x'
  9239         ).
  9239 	).
  9240 
  9240 
  9241     self isOSXlike ifTrue:[
  9241     self isOSXlike ifTrue:[
  9242         places :=
  9242 	places :=
  9243             {
  9243 	    {
  9244                 '/Library/Smalltalk-x' .
  9244 		'/Library/Smalltalk-x' .
  9245 
  9245 
  9246                 (OperatingSystem pathOfSTXExecutable asFilename
  9246 		(OperatingSystem pathOfSTXExecutable asFilename
  9247                     directory directory directory / 'Packages') name .
  9247 		    directory directory directory / 'Packages') name .
  9248 
  9248 
  9249 "/                (OperatingSystem pathOfSTXExecutable asFilename
  9249 "/                (OperatingSystem pathOfSTXExecutable asFilename
  9250 "/                    directory directory directory directory directory / 'Packages') name
  9250 "/                    directory directory directory directory directory / 'Packages') name
  9251             } , places.
  9251 	    } , places.
  9252     ].
  9252     ].
  9253     places do:[:dirName |
  9253     places do:[:dirName |
  9254         |dir vsnDir|
  9254 	|dir vsnDir|
  9255 
  9255 
  9256         dir := dirName asFilename.
  9256 	dir := dirName asFilename.
  9257         (dir isDirectory) ifTrue:[
  9257 	(dir isDirectory) ifTrue:[
  9258             "/ try to guess a gnu-smalltalk; skip it
  9258 	    "/ try to guess a gnu-smalltalk; skip it
  9259             (dir construct:'initialize.st') exists ifFalse:[
  9259 	    (dir construct:'initialize.st') exists ifFalse:[
  9260                 vsnDir := dir / vsnDirName.
  9260 		vsnDir := dir / vsnDirName.
  9261                 vsnDir exists ifTrue:[
  9261 		vsnDir exists ifTrue:[
  9262                     "/ new style: look for a major.minor directory there
  9262 		    "/ new style: look for a major.minor directory there
  9263                     sysPath add:vsnDir.
  9263 		    sysPath add:vsnDir.
  9264                 ] ifFalse:[
  9264 		] ifFalse:[
  9265                     "/ old style: look for a RELEASE file there and check if it matches
  9265 		    "/ old style: look for a RELEASE file there and check if it matches
  9266                     releaseFile := dir construct:'RELEASE'.
  9266 		    releaseFile := dir construct:'RELEASE'.
  9267                     releaseFile exists ifTrue:[
  9267 		    releaseFile exists ifTrue:[
  9268                         s := releaseFile readStreamOrNil.
  9268 			s := releaseFile readStreamOrNil.
  9269                         s notNil ifTrue:[
  9269 			s notNil ifTrue:[
  9270                             v := Integer readFrom:s onError:-1.
  9270 			    v := Integer readFrom:s onError:-1.
  9271                             s close.
  9271 			    s close.
  9272                             v == majorVersionNr ifTrue:[
  9272 			    v == majorVersionNr ifTrue:[
  9273                                 sysPath add:dirName
  9273 				sysPath add:dirName
  9274                             ] ifFalse:[
  9274 			    ] ifFalse:[
  9275                                 ('UnixOperatingSystem [info]: ignore files in ' , dir pathName , ' (RELEASE mismatch)') infoPrintCR.
  9275 				('UnixOperatingSystem [info]: ignore files in ' , dir pathName , ' (RELEASE mismatch)') infoPrintCR.
  9276                             ]
  9276 			    ]
  9277                         ] ifFalse:[
  9277 			] ifFalse:[
  9278                             ('UnixOperatingSystem [info]: ignore files in ' , dir pathName , ' (RELEASE missing)') infoPrintCR.
  9278 			    ('UnixOperatingSystem [info]: ignore files in ' , dir pathName , ' (RELEASE missing)') infoPrintCR.
  9279                         ]
  9279 			]
  9280                     ]
  9280 		    ]
  9281                 ]
  9281 		]
  9282             ]
  9282 	    ]
  9283         ]
  9283 	]
  9284     ].
  9284     ].
  9285     ^ sysPath
  9285     ^ sysPath
  9286 
  9286 
  9287     "
  9287     "
  9288      OperatingSystem defaultSystemPath
  9288      OperatingSystem defaultSystemPath
  9294      E.g. linux system calls accept single byte strings only,
  9294      E.g. linux system calls accept single byte strings only,
  9295      so the pathName has been UTF-8 encoded, before using it in a system call
  9295      so the pathName has been UTF-8 encoded, before using it in a system call
  9296      (actually, on a mac, it has to be utf8-mac encoded)."
  9296      (actually, on a mac, it has to be utf8-mac encoded)."
  9297 
  9297 
  9298     Codeset notNil ifTrue:[
  9298     Codeset notNil ifTrue:[
  9299         pathName notNil ifTrue:[
  9299 	pathName notNil ifTrue:[
  9300             "/ cg: I am not sure, why this shortcut.
  9300 	    "/ cg: I am not sure, why this shortcut.
  9301             "/ calling the encoder directly should be much faster
  9301 	    "/ calling the encoder directly should be much faster
  9302             Codeset == #utf8 ifTrue:[
  9302 	    Codeset == #utf8 ifTrue:[
  9303                 ^ pathName utf8Encoded
  9303 		^ pathName utf8Encoded
  9304             ].
  9304 	    ].
  9305             "/ Codeset encoder might not yet be initialized, sigh...
  9305 	    "/ Codeset encoder might not yet be initialized, sigh...
  9306             CodesetEncoder isNil ifTrue:[
  9306 	    CodesetEncoder isNil ifTrue:[
  9307                 self getCodesetEncoder
  9307 		self getCodesetEncoder
  9308             ].
  9308 	    ].
  9309             CodesetEncoder notNil ifTrue:[
  9309 	    CodesetEncoder notNil ifTrue:[
  9310                 ^ CodesetEncoder encodeString: pathName.
  9310 		^ CodesetEncoder encodeString: pathName.
  9311             ].
  9311 	    ].
  9312         ].
  9312 	].
  9313     ].
  9313     ].
  9314     ^ pathName
  9314     ^ pathName
  9315 
  9315 
  9316     "
  9316     "
  9317      Codeset := #'utf8-mac'.
  9317      Codeset := #'utf8-mac'.
  9330 
  9330 
  9331     |entries|
  9331     |entries|
  9332 
  9332 
  9333     entries := OrderedCollection new.
  9333     entries := OrderedCollection new.
  9334     ('/proc/mounts' asFilename) readingLinesDo:[:eachLine |
  9334     ('/proc/mounts' asFilename) readingLinesDo:[:eachLine |
  9335         |items mountInfo|
  9335 	|items mountInfo|
  9336 
  9336 
  9337         items := eachLine asCollectionOfWords.
  9337 	items := eachLine asCollectionOfWords.
  9338         mountInfo := (MountInfo new
  9338 	mountInfo := (MountInfo new
  9339             mountPointPath:(items at:2)
  9339 	    mountPointPath:(items at:2)
  9340             deviceOrRemotePath:(items at:1)
  9340 	    deviceOrRemotePath:(items at:1)
  9341             fsType:(items at:3)
  9341 	    fsType:(items at:3)
  9342             attributeString:(items at:4)).
  9342 	    attributeString:(items at:4)).
  9343         entries add:mountInfo
  9343 	entries add:mountInfo
  9344     ].
  9344     ].
  9345     ^ entries
  9345     ^ entries
  9346 
  9346 
  9347     "
  9347     "
  9348      OperatingSystem mountPointsFromProcFS
  9348      OperatingSystem mountPointsFromProcFS
  9366     void *address, *shmaddr;
  9366     void *address, *shmaddr;
  9367     int shmflg, shmid;
  9367     int shmflg, shmid;
  9368 
  9368 
  9369     if (__isSmallInteger(addr)
  9369     if (__isSmallInteger(addr)
  9370      && __bothSmallInteger(flags, id)) {
  9370      && __bothSmallInteger(flags, id)) {
  9371         shmaddr = (void *) __intVal(addr);
  9371 	shmaddr = (void *) __intVal(addr);
  9372         shmflg = __intVal(flags);
  9372 	shmflg = __intVal(flags);
  9373         shmid = __intVal(id);
  9373 	shmid = __intVal(id);
  9374 
  9374 
  9375         address = shmat(shmid, shmaddr, shmflg);
  9375 	address = shmat(shmid, shmaddr, shmflg);
  9376         if (address != (void *)-1) {
  9376 	if (address != (void *)-1) {
  9377             RETURN (__MKEXTERNALBYTES(addr));
  9377 	    RETURN (__MKEXTERNALBYTES(addr));
  9378         }
  9378 	}
  9379         @global(LastErrorNumber) = __mkSmallInteger(errno);
  9379 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  9380         RETURN (nil);
  9380 	RETURN (nil);
  9381     }
  9381     }
  9382 #endif
  9382 #endif
  9383 %}.
  9383 %}.
  9384     ^ self primitiveFailed
  9384     ^ self primitiveFailed
  9385 
  9385 
  9394 #ifdef WANT_SHM
  9394 #ifdef WANT_SHM
  9395     void *shmaddr;
  9395     void *shmaddr;
  9396     int rslt;
  9396     int rslt;
  9397 
  9397 
  9398     if (__isSmallInteger(addr)) {
  9398     if (__isSmallInteger(addr)) {
  9399         shmaddr = (void *) __intVal(addr);
  9399 	shmaddr = (void *) __intVal(addr);
  9400 
  9400 
  9401         rslt = shmdt(shmaddr);
  9401 	rslt = shmdt(shmaddr);
  9402         if (rslt != -1) {
  9402 	if (rslt != -1) {
  9403             RETURN (true);
  9403 	    RETURN (true);
  9404         }
  9404 	}
  9405         @global(LastErrorNumber) = __mkSmallInteger(errno);
  9405 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  9406         RETURN (false);
  9406 	RETURN (false);
  9407     }
  9407     }
  9408 #endif
  9408 #endif
  9409 %}.
  9409 %}.
  9410     ^ self primitiveFailed
  9410     ^ self primitiveFailed
  9411 
  9411 
  9419 
  9419 
  9420 %{  /* NOCONTEXT */
  9420 %{  /* NOCONTEXT */
  9421 #ifdef WANT_SHM
  9421 #ifdef WANT_SHM
  9422     if (__bothSmallInteger(key, size)
  9422     if (__bothSmallInteger(key, size)
  9423      && __isSmallInteger(flags)) {
  9423      && __isSmallInteger(flags)) {
  9424         int rslt;
  9424 	int rslt;
  9425 
  9425 
  9426         rslt = shmget(__intVal(key), __intVal(size), __intVal(flags));
  9426 	rslt = shmget(__intVal(key), __intVal(size), __intVal(flags));
  9427         if (rslt != -1) {
  9427 	if (rslt != -1) {
  9428             RETURN (__mkSmallInteger(rslt));
  9428 	    RETURN (__mkSmallInteger(rslt));
  9429         }
  9429 	}
  9430         @global(LastErrorNumber) = __mkSmallInteger(errno);
  9430 	@global(LastErrorNumber) = __mkSmallInteger(errno);
  9431         RETURN (nil);
  9431 	RETURN (nil);
  9432     }
  9432     }
  9433 #endif
  9433 #endif
  9434 %}.
  9434 %}.
  9435     ^ self primitiveFailed
  9435     ^ self primitiveFailed
  9436 
  9436 
  9471     TIME_T t;
  9471     TIME_T t;
  9472 
  9472 
  9473     if (__bothSmallInteger(y, m)
  9473     if (__bothSmallInteger(y, m)
  9474      && __bothSmallInteger(d, h)
  9474      && __bothSmallInteger(d, h)
  9475      && __bothSmallInteger(min, s)) {
  9475      && __bothSmallInteger(min, s)) {
  9476         tm.tm_hour = __intVal(h);
  9476 	tm.tm_hour = __intVal(h);
  9477         tm.tm_min = __intVal(min);
  9477 	tm.tm_min = __intVal(min);
  9478         tm.tm_sec = __intVal(s);
  9478 	tm.tm_sec = __intVal(s);
  9479 
  9479 
  9480         tm.tm_year = __intVal(y) - 1900;
  9480 	tm.tm_year = __intVal(y) - 1900;
  9481         tm.tm_mon = __intVal(m) - 1;
  9481 	tm.tm_mon = __intVal(m) - 1;
  9482         tm.tm_mday = __intVal(d);
  9482 	tm.tm_mday = __intVal(d);
  9483         tm.tm_isdst = -1;
  9483 	tm.tm_isdst = -1;
  9484 
  9484 
  9485 #ifndef HAS_MKTIME64
  9485 #ifndef HAS_MKTIME64
  9486         if (__intVal(y) > 2038) goto outOfRange;
  9486 	if (__intVal(y) > 2038) goto outOfRange;
  9487         if (__intVal(y) == 2038) {
  9487 	if (__intVal(y) == 2038) {
  9488             if (__intVal(m) > 1) goto outOfRange;
  9488 	    if (__intVal(m) > 1) goto outOfRange;
  9489             if (__intVal(d) > 19) goto outOfRange;
  9489 	    if (__intVal(d) > 19) goto outOfRange;
  9490             if (__intVal(d) == 19) {
  9490 	    if (__intVal(d) == 19) {
  9491                 if (__intVal(h) > 3) goto outOfRange;
  9491 		if (__intVal(h) > 3) goto outOfRange;
  9492                 if (__intVal(h) == 3) {
  9492 		if (__intVal(h) == 3) {
  9493                     if (__intVal(min) > 14) goto outOfRange;
  9493 		    if (__intVal(min) > 14) goto outOfRange;
  9494                     if (__intVal(min) == 14) {
  9494 		    if (__intVal(min) == 14) {
  9495                         if (__intVal(s) > 7) goto outOfRange;
  9495 			if (__intVal(s) > 7) goto outOfRange;
  9496                     }
  9496 		    }
  9497                 }
  9497 		}
  9498             }
  9498 	    }
  9499         }
  9499 	}
  9500 #endif
  9500 #endif
  9501 
  9501 
  9502 #ifdef HAS_TIMEGM
  9502 #ifdef HAS_TIMEGM
  9503         if (utcBoolean == true) {               /* convert to utc time */
  9503 	if (utcBoolean == true) {               /* convert to utc time */
  9504 # ifdef HAS_MKTIME64
  9504 # ifdef HAS_MKTIME64
  9505             t = timegm64(&tm);                  /* timegm() interprets tm as utc time */
  9505 	    t = timegm64(&tm);                  /* timegm() interprets tm as utc time */
  9506 # else
  9506 # else
  9507             t = timegm(&tm);                    /* timegm() interprets tm as utc time */
  9507 	    t = timegm(&tm);                    /* timegm() interprets tm as utc time */
  9508 # endif
  9508 # endif
  9509         } else
  9509 	} else
  9510 #endif
  9510 #endif
  9511         {
  9511 	{
  9512 #ifdef HAS_MKTIME64
  9512 #ifdef HAS_MKTIME64
  9513             t = mktime64(&tm);                  /* mktime() interprets tm as localtime */
  9513 	    t = mktime64(&tm);                  /* mktime() interprets tm as localtime */
  9514 #else
  9514 #else
  9515             t = mktime(&tm);                    /* mktime() interprets tm as localtime */
  9515 	    t = mktime(&tm);                    /* mktime() interprets tm as localtime */
  9516 #endif
  9516 #endif
  9517         }
  9517 	}
  9518         if (t != (TIME_T)-1) {
  9518 	if (t != (TIME_T)-1) {
  9519 #ifndef HAS_TIMEGM
  9519 #ifndef HAS_TIMEGM
  9520             if (utcBoolean == true) {           /* convert to utc time */
  9520 	    if (utcBoolean == true) {           /* convert to utc time */
  9521                 // printf("tz=%d\n", TIMEZONE(&tm));
  9521 		// printf("tz=%d\n", TIMEZONE(&tm));
  9522                 t = t - TIMEZONE(&tm);          /* TIMZONE = seconds westward from 0 */
  9522 		t = t - TIMEZONE(&tm);          /* TIMZONE = seconds westward from 0 */
  9523             }
  9523 	    }
  9524 #endif
  9524 #endif
  9525 #ifdef HAS_MKTIME64
  9525 #ifdef HAS_MKTIME64
  9526             osSeconds = __MKLARGEINT64(1, (t & 0xFFFFFFFF), (t>>32)& 0xFFFFFFFF);
  9526 	    osSeconds = __MKLARGEINT64(1, (t & 0xFFFFFFFF), (t>>32)& 0xFFFFFFFF);
  9527 #else
  9527 #else
  9528             /* be careful, t can be negative at the start of the epoch ! */
  9528 	    /* be careful, t can be negative at the start of the epoch ! */
  9529             osSeconds = __MKINT((INT)t);
  9529 	    osSeconds = __MKINT((INT)t);
  9530 #endif
  9530 #endif
  9531         }
  9531 	}
  9532     }
  9532     }
  9533   outOfRange: ;
  9533   outOfRange: ;
  9534 %}.
  9534 %}.
  9535     osSeconds notNil ifTrue:[
  9535     osSeconds notNil ifTrue:[
  9536         ^ osSeconds * 1000 + millis
  9536 	^ osSeconds * 1000 + millis
  9537     ].
  9537     ].
  9538     ^ TimeConversionError raiseRequest.
  9538     ^ TimeConversionError raiseRequest.
  9539 
  9539 
  9540     "
  9540     "
  9541      OperatingSystem computeOSTimeFromYear:1970 month:1 day:1 hour:0 minute:0 second:0 millisecond:0 utc:true
  9541      OperatingSystem computeOSTimeFromYear:1970 month:1 day:1 hour:0 minute:0 second:0 millisecond:0 utc:true
  9569 #if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC) && !defined(NO_CLOCK_GETTIME)
  9569 #if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC) && !defined(NO_CLOCK_GETTIME)
  9570     struct timespec ts;
  9570     struct timespec ts;
  9571     static int has_clock_gettime = 1;
  9571     static int has_clock_gettime = 1;
  9572 
  9572 
  9573     if (has_clock_gettime) {
  9573     if (has_clock_gettime) {
  9574         if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1) {
  9574 	if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1) {
  9575             _secs = ts.tv_sec;
  9575 	    _secs = ts.tv_sec;
  9576             _micros  = ts.tv_nsec / 1000;
  9576 	    _micros  = ts.tv_nsec / 1000;
  9577             goto out;
  9577 	    goto out;
  9578         } else {
  9578 	} else {
  9579             /*
  9579 	    /*
  9580              * clock_gettime is not implemented in the kernel
  9580 	     * clock_gettime is not implemented in the kernel
  9581              * fall through to alternative implementation
  9581 	     * fall through to alternative implementation
  9582              */
  9582 	     */
  9583             has_clock_gettime = 0;
  9583 	    has_clock_gettime = 0;
  9584         }
  9584 	}
  9585     }
  9585     }
  9586 #endif
  9586 #endif
  9587 
  9587 
  9588 #if defined(HAS_GETTIMEOFDAY)
  9588 #if defined(HAS_GETTIMEOFDAY)
  9589     struct timeval tb;
  9589     struct timeval tb;
  9590 
  9590 
  9591     gettimeofday(&tb, NULL /* &tzb */);
  9591     gettimeofday(&tb, NULL /* &tzb */);
  9592     if (tb.tv_usec >= (1000000)) {
  9592     if (tb.tv_usec >= (1000000)) {
  9593         error = @symbol(bad);
  9593 	error = @symbol(bad);
  9594         goto err;
  9594 	goto err;
  9595     }
  9595     }
  9596 
  9596 
  9597     _secs = tb.tv_sec;
  9597     _secs = tb.tv_sec;
  9598     _micros  = tb.tv_usec;
  9598     _micros  = tb.tv_usec;
  9599 #endif
  9599 #endif
  9600 
  9600 
  9601 out:
  9601 out:
  9602 
  9602 
  9603 #if __POINTER_SIZE__ == 8
  9603 #if __POINTER_SIZE__ == 8
  9604     {
  9604     {
  9605         unsigned INT rslt;
  9605 	unsigned INT rslt;
  9606 
  9606 
  9607         rslt = (unsigned INT)_secs * 1000000 + _micros;
  9607 	rslt = (unsigned INT)_secs * 1000000 + _micros;
  9608         RETURN (__MKUINT(rslt));
  9608 	RETURN (__MKUINT(rslt));
  9609     }
  9609     }
  9610 #else
  9610 #else
  9611 # ifdef HAS_LONGLONG
  9611 # ifdef HAS_LONGLONG
  9612     {
  9612     {
  9613         unsigned long long rslt;
  9613 	unsigned long long rslt;
  9614 
  9614 
  9615         rslt = (unsigned long long)_secs * 1000000 + _micros;
  9615 	rslt = (unsigned long long)_secs * 1000000 + _micros;
  9616         RETURN (__MKLARGEINT64(1, (unsigned INT)(rslt & 0xFFFFFFFF), (unsigned INT)(rslt >> 32)));
  9616 	RETURN (__MKLARGEINT64(1, (unsigned INT)(rslt & 0xFFFFFFFF), (unsigned INT)(rslt >> 32)));
  9617     }
  9617     }
  9618 # else
  9618 # else
  9619     seconds = __MKUINT(_secs);
  9619     seconds = __MKUINT(_secs);
  9620     micros = __MKUINT(_micros);
  9620     micros = __MKUINT(_micros);
  9621 # endif /* long long */
  9621 # endif /* long long */
  9622 #endif /* __POINTER_SIZE__ == 8 */
  9622 #endif /* __POINTER_SIZE__ == 8 */
  9623 err:;
  9623 err:;
  9624 %}.
  9624 %}.
  9625 
  9625 
  9626     seconds notNil ifTrue:[
  9626     seconds notNil ifTrue:[
  9627         ^ (seconds * 1000000) + micros
  9627 	^ (seconds * 1000000) + micros
  9628     ].
  9628     ].
  9629     error isNil ifTrue:[
  9629     error isNil ifTrue:[
  9630         ^ self getMillisecondTime * 1000
  9630 	^ self getMillisecondTime * 1000
  9631     ].
  9631     ].
  9632     self primitiveFailed:error.
  9632     self primitiveFailed:error.
  9633 
  9633 
  9634     "
  9634     "
  9635      Transcript showCR:(OperatingSystem getMicrosecondTime).
  9635      Transcript showCR:(OperatingSystem getMicrosecondTime).
  9644      Since this value is wrapping around in regular intervals, this can only be used for
  9644      Since this value is wrapping around in regular intervals, this can only be used for
  9645      short relative time deltas.
  9645      short relative time deltas.
  9646      Use the XXXmillisecondTime:-methods to compare and add time deltas - these know about the wrap.
  9646      Use the XXXmillisecondTime:-methods to compare and add time deltas - these know about the wrap.
  9647 
  9647 
  9648      BAD DESIGN:
  9648      BAD DESIGN:
  9649         This should be changed to return some instance of RelativeTime,
  9649 	This should be changed to return some instance of RelativeTime,
  9650         and these computations moved there.
  9650 	and these computations moved there.
  9651 
  9651 
  9652      Don't use this method in application code since it is an internal (private)
  9652      Don't use this method in application code since it is an internal (private)
  9653      interface. For compatibility with ST-80, use Time millisecondClockValue.
  9653      interface. For compatibility with ST-80, use Time millisecondClockValue.
  9654     "
  9654     "
  9655 
  9655 
  9660 #if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC) && !defined(NO_CLOCK_GETTIME)
  9660 #if defined(_POSIX_MONOTONIC_CLOCK) && defined(CLOCK_MONOTONIC) && !defined(NO_CLOCK_GETTIME)
  9661     static has_clock_gettime = 1;
  9661     static has_clock_gettime = 1;
  9662     struct timespec ts;
  9662     struct timespec ts;
  9663 
  9663 
  9664     if (has_clock_gettime) {
  9664     if (has_clock_gettime) {
  9665         if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1) {
  9665 	if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1) {
  9666             t = ts.tv_sec*1000 + ts.tv_nsec/1000000;
  9666 	    t = ts.tv_sec*1000 + ts.tv_nsec/1000000;
  9667             goto out;
  9667 	    goto out;
  9668         } else {
  9668 	} else {
  9669             /*
  9669 	    /*
  9670              * clock_gettime is not implemented in the kernel
  9670 	     * clock_gettime is not implemented in the kernel
  9671              * fall through to alternative implementation
  9671 	     * fall through to alternative implementation
  9672              */
  9672 	     */
  9673             has_clock_gettime = 0;
  9673 	    has_clock_gettime = 0;
  9674         }
  9674 	}
  9675     }
  9675     }
  9676 #endif /*  _POSIX_MONOTONIC_CLOCK */
  9676 #endif /*  _POSIX_MONOTONIC_CLOCK */
  9677 
  9677 
  9678 #if defined(_SC_CLK_TCK)
  9678 #if defined(_SC_CLK_TCK)
  9679 /*
  9679 /*
  9685     static int millisecondsPerTick;
  9685     static int millisecondsPerTick;
  9686     clock_t ticks;
  9686     clock_t ticks;
  9687     struct tms tb;
  9687     struct tms tb;
  9688 
  9688 
  9689     if (!millisecondsPerTick) {
  9689     if (!millisecondsPerTick) {
  9690         int ticksPerSecond = sysconf(_SC_CLK_TCK);
  9690 	int ticksPerSecond = sysconf(_SC_CLK_TCK);
  9691         if (ticksPerSecond <= 0)
  9691 	if (ticksPerSecond <= 0)
  9692             goto err;
  9692 	    goto err;
  9693         if (ticksPerSecond > 1000)
  9693 	if (ticksPerSecond > 1000)
  9694             goto err;
  9694 	    goto err;
  9695         millisecondsPerTick = 1000 / ticksPerSecond;
  9695 	millisecondsPerTick = 1000 / ticksPerSecond;
  9696 /*
  9696 /*
  9697 printf("milliSecondsPerTick: %d\n", millisecondsPerTick);
  9697 printf("milliSecondsPerTick: %d\n", millisecondsPerTick);
  9698 */
  9698 */
  9699     }
  9699     }
  9700 
  9700 
  9701     ticks = times(&tb);
  9701     ticks = times(&tb);
  9702     if (ticks == -1)
  9702     if (ticks == -1)
  9703         goto err;
  9703 	goto err;
  9704 
  9704 
  9705     t = ticks * millisecondsPerTick;
  9705     t = ticks * millisecondsPerTick;
  9706 
  9706 
  9707 #else /* !times */
  9707 #else /* !times */
  9708 
  9708 
  9750     unsigned long _secs, _millis;
  9750     unsigned long _secs, _millis;
  9751 
  9751 
  9752 #if !defined(HAS_GETTIMEOFDAY)
  9752 #if !defined(HAS_GETTIMEOFDAY)
  9753 # if defined(HAS_FTIME)
  9753 # if defined(HAS_FTIME)
  9754     {
  9754     {
  9755         struct timeb timebuffer;
  9755 	struct timeb timebuffer;
  9756 
  9756 
  9757         ftime(&timebuffer);
  9757 	ftime(&timebuffer);
  9758         _secs = timebuffer.time;
  9758 	_secs = timebuffer.time;
  9759         _millis = timebuffer.millitm;
  9759 	_millis = timebuffer.millitm;
  9760     }
  9760     }
  9761 #   define HAVE_TIME
  9761 #   define HAVE_TIME
  9762 # endif /* HAS_FTIME */
  9762 # endif /* HAS_FTIME */
  9763 #endif /* no HAS_GETTIMEOFDAY */
  9763 #endif /* no HAS_GETTIMEOFDAY */
  9764 
  9764 
  9767      * use HAS_GETTIMEOFDAY even if HAS_GETTIMEOFDAY is undefined here.
  9767      * use HAS_GETTIMEOFDAY even if HAS_GETTIMEOFDAY is undefined here.
  9768      * Will result in a linkage error if not fixed and neither ftime() nor time() is used.
  9768      * Will result in a linkage error if not fixed and neither ftime() nor time() is used.
  9769      */
  9769      */
  9770 
  9770 
  9771     {
  9771     {
  9772         /*
  9772 	/*
  9773          * bsd time
  9773 	 * bsd time
  9774          */
  9774 	 */
  9775         struct timeval tb;
  9775 	struct timeval tb;
  9776         /* struct timezone tzb; */
  9776 	/* struct timezone tzb; */
  9777 
  9777 
  9778         gettimeofday(&tb, NULL /* &tzb */);
  9778 	gettimeofday(&tb, NULL /* &tzb */);
  9779 
  9779 
  9780         _secs = tb.tv_sec;
  9780 	_secs = tb.tv_sec;
  9781         _millis = tb.tv_usec / 1000;
  9781 	_millis = tb.tv_usec / 1000;
  9782     }
  9782     }
  9783 #endif
  9783 #endif
  9784 
  9784 
  9785 #if __POINTER_SIZE__ == 8
  9785 #if __POINTER_SIZE__ == 8
  9786     {
  9786     {
  9787         unsigned INT rslt;
  9787 	unsigned INT rslt;
  9788 
  9788 
  9789         rslt = (unsigned INT)_secs * 1000 + _millis;
  9789 	rslt = (unsigned INT)_secs * 1000 + _millis;
  9790         RETURN (__MKUINT(rslt));
  9790 	RETURN (__MKUINT(rslt));
  9791     }
  9791     }
  9792 #else
  9792 #else
  9793 # ifdef HAS_LONGLONG
  9793 # ifdef HAS_LONGLONG
  9794     {
  9794     {
  9795         unsigned long long rslt;
  9795 	unsigned long long rslt;
  9796 
  9796 
  9797         rslt = (unsigned long long)_secs * 1000 + _millis;
  9797 	rslt = (unsigned long long)_secs * 1000 + _millis;
  9798         RETURN (__MKLARGEINT64(1, (unsigned INT)(rslt & 0xFFFFFFFF), (unsigned INT)(rslt >> 32)));
  9798 	RETURN (__MKLARGEINT64(1, (unsigned INT)(rslt & 0xFFFFFFFF), (unsigned INT)(rslt >> 32)));
  9799     }
  9799     }
  9800 # else
  9800 # else
  9801     seconds = __MKUINT(_secs);
  9801     seconds = __MKUINT(_secs);
  9802     millis = __MKUINT(_millis);
  9802     millis = __MKUINT(_millis);
  9803 # endif /* long long */
  9803 # endif /* long long */
  9804 #endif /* __POINTER_SIZE__ == 8 */
  9804 #endif /* __POINTER_SIZE__ == 8 */
  9805 %}.
  9805 %}.
  9806 
  9806 
  9807     seconds notNil ifTrue:[
  9807     seconds notNil ifTrue:[
  9808         ^ (seconds * 1000) + millis
  9808 	^ (seconds * 1000) + millis
  9809     ].
  9809     ].
  9810 
  9810 
  9811     self primitiveFailed.
  9811     self primitiveFailed.
  9812 
  9812 
  9813 
  9813 
  9831      only the calling thread sleep)."
  9831      only the calling thread sleep)."
  9832 
  9832 
  9833 %{  /* NOCONTEXT */
  9833 %{  /* NOCONTEXT */
  9834 
  9834 
  9835     if (__isSmallInteger(numberOfSeconds)) {
  9835     if (__isSmallInteger(numberOfSeconds)) {
  9836         sleep(__intVal(numberOfSeconds));
  9836 	sleep(__intVal(numberOfSeconds));
  9837         RETURN ( self );
  9837 	RETURN ( self );
  9838     }
  9838     }
  9839 %}.
  9839 %}.
  9840     "
  9840     "
  9841      argument not integer
  9841      argument not integer
  9842     "
  9842     "
  9858 %{
  9858 %{
  9859     struct tm tmValue, *result;
  9859     struct tm tmValue, *result;
  9860     time_t tt = __signedLongIntVal(osSeconds);
  9860     time_t tt = __signedLongIntVal(osSeconds);
  9861 
  9861 
  9862     if (tt == 0 && !__isSmallInteger(osSeconds))
  9862     if (tt == 0 && !__isSmallInteger(osSeconds))
  9863         goto out;             // __singedLongIntVal() returns 0 on failure
  9863 	goto out;             // __singedLongIntVal() returns 0 on failure
  9864 
  9864 
  9865     /* try cache */
  9865     /* try cache */
  9866     {
  9866     {
  9867         OBJ lastSeconds = @global(LastTimeInfoSeconds);
  9867 	OBJ lastSeconds = @global(LastTimeInfoSeconds);
  9868 
  9868 
  9869         if (__isInteger(lastSeconds)
  9869 	if (__isInteger(lastSeconds)
  9870              && (__signedLongIntVal(lastSeconds) == tt)
  9870 	     && (__signedLongIntVal(lastSeconds) == tt)
  9871              && (@global(LastTimeInfoIsLocal) == isLocalTime)
  9871 	     && (@global(LastTimeInfoIsLocal) == isLocalTime)
  9872         ) {
  9872 	) {
  9873             OBJ lastTimeInfo = @global(LastTimeInfo);
  9873 	    OBJ lastTimeInfo = @global(LastTimeInfo);
  9874             if (lastTimeInfo != nil) {
  9874 	    if (lastTimeInfo != nil) {
  9875                 info = lastTimeInfo;
  9875 		info = lastTimeInfo;
  9876                 goto out;
  9876 		goto out;
  9877             }
  9877 	    }
  9878         }
  9878 	}
  9879     }
  9879     }
  9880 
  9880 
  9881     result = (isLocalTime == true) ? localtime_r(&tt, &tmValue) :  gmtime_r(&tt, &tmValue);
  9881     result = (isLocalTime == true) ? localtime_r(&tt, &tmValue) :  gmtime_r(&tt, &tmValue);
  9882     if (result != NULL) {
  9882     if (result != NULL) {
  9883         hours = __mkSmallInteger(tmValue.tm_hour);
  9883 	hours = __mkSmallInteger(tmValue.tm_hour);
  9884         minutes = __mkSmallInteger(tmValue.tm_min);
  9884 	minutes = __mkSmallInteger(tmValue.tm_min);
  9885         seconds = __mkSmallInteger(tmValue.tm_sec);
  9885 	seconds = __mkSmallInteger(tmValue.tm_sec);
  9886 
  9886 
  9887         year = __mkSmallInteger(tmValue.tm_year + 1900);
  9887 	year = __mkSmallInteger(tmValue.tm_year + 1900);
  9888         month = __mkSmallInteger(tmValue.tm_mon + 1);
  9888 	month = __mkSmallInteger(tmValue.tm_mon + 1);
  9889         day = __mkSmallInteger(tmValue.tm_mday);
  9889 	day = __mkSmallInteger(tmValue.tm_mday);
  9890 
  9890 
  9891         yDay = __mkSmallInteger(tmValue.tm_yday+1);
  9891 	yDay = __mkSmallInteger(tmValue.tm_yday+1);
  9892         wDay = __mkSmallInteger(tmValue.tm_wday == 0 ? 7 : tmValue.tm_wday);
  9892 	wDay = __mkSmallInteger(tmValue.tm_wday == 0 ? 7 : tmValue.tm_wday);
  9893         utcOffset = __mkSmallInteger(TIMEZONE(&tmValue));
  9893 	utcOffset = __mkSmallInteger(TIMEZONE(&tmValue));
  9894         dst = (tmValue.tm_isdst == 0 ? false : true);
  9894 	dst = (tmValue.tm_isdst == 0 ? false : true);
  9895     }
  9895     }
  9896 out:;
  9896 out:;
  9897 %}.
  9897 %}.
  9898     info notNil ifTrue:[
  9898     info notNil ifTrue:[
  9899         "there is a matching cached value"
  9899 	"there is a matching cached value"
  9900         LastTimeInfoMilliseconds == osMilliseconds ifTrue:[
  9900 	LastTimeInfoMilliseconds == osMilliseconds ifTrue:[
  9901             ^ info.
  9901 	    ^ info.
  9902         ].
  9902 	].
  9903         info := info copy.
  9903 	info := info copy.
  9904         info milliseconds:osMilliseconds.
  9904 	info milliseconds:osMilliseconds.
  9905     ] ifFalse:[
  9905     ] ifFalse:[
  9906         year isNil ifTrue:[
  9906 	year isNil ifTrue:[
  9907             TimeConversionError raiseErrorString:' - out of range'.
  9907 	    TimeConversionError raiseErrorString:' - out of range'.
  9908         ].
  9908 	].
  9909 
  9909 
  9910         info := self timeInfoClass new.
  9910 	info := self timeInfoClass new.
  9911         info
  9911 	info
  9912             year:year
  9912 	    year:year
  9913             month:month
  9913 	    month:month
  9914             day:day
  9914 	    day:day
  9915             hours:hours
  9915 	    hours:hours
  9916             minutes:minutes
  9916 	    minutes:minutes
  9917             seconds:seconds
  9917 	    seconds:seconds
  9918             milliseconds:osMilliseconds
  9918 	    milliseconds:osMilliseconds
  9919             utcOffset:utcOffset
  9919 	    utcOffset:utcOffset
  9920             dst:dst
  9920 	    dst:dst
  9921             dayInYear:yDay
  9921 	    dayInYear:yDay
  9922             dayInWeek:wDay.
  9922 	    dayInWeek:wDay.
  9923     ].
  9923     ].
  9924 
  9924 
  9925 %{
  9925 %{
  9926     @global(LastTimeInfo) = info;                       __GSTORE(info);
  9926     @global(LastTimeInfo) = info;                       __GSTORE(info);
  9927     @global(LastTimeInfoSeconds) = osSeconds;           __GSTORE(osSeconds);
  9927     @global(LastTimeInfoSeconds) = osSeconds;           __GSTORE(osSeconds);
 10014     |info gecos|
 10014     |info gecos|
 10015 
 10015 
 10016     info := self userInfoOf:userID.
 10016     info := self userInfoOf:userID.
 10017     (info notNil
 10017     (info notNil
 10018     and:[info includesKey:#gecos]) ifTrue:[
 10018     and:[info includesKey:#gecos]) ifTrue:[
 10019         gecos := info at:#gecos.
 10019 	gecos := info at:#gecos.
 10020         (gecos includes:$,) ifTrue:[
 10020 	(gecos includes:$,) ifTrue:[
 10021             ^ gecos copyTo:(gecos indexOf:$,) - 1
 10021 	    ^ gecos copyTo:(gecos indexOf:$,) - 1
 10022         ].
 10022 	].
 10023         ^ gecos
 10023 	^ gecos
 10024     ].
 10024     ].
 10025     ^ self getUserNameFromID:userID
 10025     ^ self getUserNameFromID:userID
 10026 
 10026 
 10027     "
 10027     "
 10028      OperatingSystem getFullUserNameFromID:0
 10028      OperatingSystem getFullUserNameFromID:0
 10057 
 10057 
 10058 %{  /* NOCONTEXT */
 10058 %{  /* NOCONTEXT */
 10059     struct group *g;
 10059     struct group *g;
 10060 
 10060 
 10061     if (__isSmallInteger(aNumber)) {
 10061     if (__isSmallInteger(aNumber)) {
 10062         g = getgrgid(__intVal(aNumber));
 10062 	g = getgrgid(__intVal(aNumber));
 10063         if (g) {
 10063 	if (g) {
 10064             RETURN ( __MKSTRING(g->gr_name) );
 10064 	    RETURN ( __MKSTRING(g->gr_name) );
 10065         }
 10065 	}
 10066     }
 10066     }
 10067 %}.
 10067 %}.
 10068     ^ '???'
 10068     ^ '???'
 10069 
 10069 
 10070     "
 10070     "
 10080 
 10080 
 10081     |homeDir|
 10081     |homeDir|
 10082 
 10082 
 10083     homeDir := self getEnvironment:'HOME'.
 10083     homeDir := self getEnvironment:'HOME'.
 10084     homeDir isNil ifTrue:[
 10084     homeDir isNil ifTrue:[
 10085         "/ mhmh - can only happen if started via some uncorrectly
 10085 	"/ mhmh - can only happen if started via some uncorrectly
 10086         "/ initialized subprocess...
 10086 	"/ initialized subprocess...
 10087         'UnixOperatingSystem [warning]: cannot figure out home directory' errorPrintCR.
 10087 	'UnixOperatingSystem [warning]: cannot figure out home directory' errorPrintCR.
 10088         homeDir := '/tmp'.
 10088 	homeDir := '/tmp'.
 10089     ].
 10089     ].
 10090     ^ self decodePath:homeDir
 10090     ^ self decodePath:homeDir
 10091 
 10091 
 10092     "
 10092     "
 10093      OperatingSystem getHomeDirectory
 10093      OperatingSystem getHomeDirectory
 10108     extern char *getlogin();
 10108     extern char *getlogin();
 10109 
 10109 
 10110     char *name = (char *)0;
 10110     char *name = (char *)0;
 10111 
 10111 
 10112     if (firstCall) {
 10112     if (firstCall) {
 10113         /*
 10113 	/*
 10114          * try a few common environment variables ...
 10114 	 * try a few common environment variables ...
 10115          */
 10115 	 */
 10116         name = getenv("LOGNAME");
 10116 	name = getenv("LOGNAME");
 10117         if (! name || (name[0] == 0)) {
 10117 	if (! name || (name[0] == 0)) {
 10118             name = getlogin();
 10118 	    name = getlogin();
 10119             if (! name || (name[0] == 0) ) {
 10119 	    if (! name || (name[0] == 0) ) {
 10120                 name = getenv("LOGIN");
 10120 		name = getenv("LOGIN");
 10121                 if (! name || (name[0] == 0) ) {
 10121 		if (! name || (name[0] == 0) ) {
 10122                     name = getenv("USER");
 10122 		    name = getenv("USER");
 10123                 }
 10123 		}
 10124             }
 10124 	    }
 10125         }
 10125 	}
 10126         if (name && (strlen(name) < sizeof(cachedName))) {
 10126 	if (name && (strlen(name) < sizeof(cachedName))) {
 10127             strcpy(cachedName, name);
 10127 	    strcpy(cachedName, name);
 10128             firstCall = 0;
 10128 	    firstCall = 0;
 10129         }
 10129 	}
 10130     } else {
 10130     } else {
 10131         name = cachedName;
 10131 	name = cachedName;
 10132     }
 10132     }
 10133 
 10133 
 10134     /*
 10134     /*
 10135      * nope - I really font know who you are.
 10135      * nope - I really dont know who you are.
 10136      */
 10136      */
 10137     if (! name || (name[0] == 0) ) {
 10137     if (! name || (name[0] == 0) ) {
 10138         name = "you";
 10138 	name = "you";
 10139     }
 10139     }
 10140 
 10140 
 10141     RETURN ( __MKSTRING(name) );
 10141     RETURN ( __MKSTRING(name) );
 10142 %}.
 10142 %}.
 10143     "
 10143     "
 10170 
 10170 
 10171 # ifndef NO_PWD
 10171 # ifndef NO_PWD
 10172     struct passwd *p;
 10172     struct passwd *p;
 10173 
 10173 
 10174     if (__isSmallInteger(aNumber)) {
 10174     if (__isSmallInteger(aNumber)) {
 10175         p = getpwuid(__intVal(aNumber));
 10175 	p = getpwuid(__intVal(aNumber));
 10176         if (p) {
 10176 	if (p) {
 10177             RETURN ( __MKSTRING(p->pw_name) );
 10177 	    RETURN ( __MKSTRING(p->pw_name) );
 10178         }
 10178 	}
 10179     }
 10179     }
 10180 #endif /* unix-like */
 10180 #endif /* unix-like */
 10181 %}.
 10181 %}.
 10182     aNumber == self getUserID ifTrue:[
 10182     aNumber == self getUserID ifTrue:[
 10183         ^ self getLoginName
 10183 	^ self getLoginName
 10184     ].
 10184     ].
 10185 
 10185 
 10186     ^ '? (' , aNumber printString , ')'
 10186     ^ '? (' , aNumber printString , ')'
 10187 
 10187 
 10188     "
 10188     "
 10234 #if defined(_POSIX_SOURCE)
 10234 #if defined(_POSIX_SOURCE)
 10235     char buf[4096];
 10235     char buf[4096];
 10236     struct passwd pwd;
 10236     struct passwd pwd;
 10237 
 10237 
 10238     if (__isStringLike(aNameOrID)) {
 10238     if (__isStringLike(aNameOrID)) {
 10239         getpwnam_r(__stringVal(aNameOrID), &pwd, buf, sizeof(buf), &result);
 10239 	getpwnam_r(__stringVal(aNameOrID), &pwd, buf, sizeof(buf), &result);
 10240     } else if (__isSmallInteger(aNameOrID)) {
 10240     } else if (__isSmallInteger(aNameOrID)) {
 10241         getpwuid_r(__intVal(aNameOrID), &pwd, buf, sizeof(buf), &result);
 10241 	getpwuid_r(__intVal(aNameOrID), &pwd, buf, sizeof(buf), &result);
 10242     }
 10242     }
 10243 #else
 10243 #else
 10244     if (__isStringLike(aNameOrID)) {
 10244     if (__isStringLike(aNameOrID)) {
 10245         result = getpwnam(__stringVal(aNameOrID));
 10245 	result = getpwnam(__stringVal(aNameOrID));
 10246     } else if (__isSmallInteger(aNameOrID)) {
 10246     } else if (__isSmallInteger(aNameOrID)) {
 10247         result = getpwuid(__intVal(aNameOrID));
 10247 	result = getpwuid(__intVal(aNameOrID));
 10248     }
 10248     }
 10249 #endif /* ! _POSIX_SOURCE */
 10249 #endif /* ! _POSIX_SOURCE */
 10250 
 10250 
 10251     if (result) {
 10251     if (result) {
 10252         returnArray = __ARRAY_NEW_INT(20);
 10252 	returnArray = __ARRAY_NEW_INT(20);
 10253         __PROTECT__(returnArray);
 10253 	__PROTECT__(returnArray);
 10254         tmp = __MKSTRING(result->pw_name);
 10254 	tmp = __MKSTRING(result->pw_name);
 10255         __UNPROTECT__(returnArray);
 10255 	__UNPROTECT__(returnArray);
 10256         __arrayVal(returnArray)[idx++] = @symbol(name);
 10256 	__arrayVal(returnArray)[idx++] = @symbol(name);
 10257         __arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10257 	__arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10258 #  ifndef NO_PWD_PASSWD
 10258 #  ifndef NO_PWD_PASSWD
 10259         __PROTECT__(returnArray);
 10259 	__PROTECT__(returnArray);
 10260         tmp = __MKSTRING(result->pw_passwd);
 10260 	tmp = __MKSTRING(result->pw_passwd);
 10261         __UNPROTECT__(returnArray);
 10261 	__UNPROTECT__(returnArray);
 10262         __arrayVal(returnArray)[idx++] = @symbol(passwd);
 10262 	__arrayVal(returnArray)[idx++] = @symbol(passwd);
 10263         __arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10263 	__arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10264 #  endif
 10264 #  endif
 10265 #  ifdef SYSV4
 10265 #  ifdef SYSV4
 10266         __PROTECT__(returnArray);
 10266 	__PROTECT__(returnArray);
 10267         tmp = __MKSTRING(result->pw_age);
 10267 	tmp = __MKSTRING(result->pw_age);
 10268         __UNPROTECT__(returnArray);
 10268 	__UNPROTECT__(returnArray);
 10269         __arrayVal(returnArray)[idx++] = @symbol(age);
 10269 	__arrayVal(returnArray)[idx++] = @symbol(age);
 10270         __arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10270 	__arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10271         __PROTECT__(returnArray);
 10271 	__PROTECT__(returnArray);
 10272         tmp = __MKSTRING(result->pw_comment);
 10272 	tmp = __MKSTRING(result->pw_comment);
 10273         __UNPROTECT__(returnArray);
 10273 	__UNPROTECT__(returnArray);
 10274         __arrayVal(returnArray)[idx++] = @symbol(comment);
 10274 	__arrayVal(returnArray)[idx++] = @symbol(comment);
 10275         __arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10275 	__arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10276 #  endif
 10276 #  endif
 10277         __PROTECT__(returnArray);
 10277 	__PROTECT__(returnArray);
 10278         tmp = __MKSTRING(result->pw_dir);
 10278 	tmp = __MKSTRING(result->pw_dir);
 10279         __UNPROTECT__(returnArray);
 10279 	__UNPROTECT__(returnArray);
 10280         __arrayVal(returnArray)[idx++] = @symbol(dir);
 10280 	__arrayVal(returnArray)[idx++] = @symbol(dir);
 10281         __arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10281 	__arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10282 #  ifndef NO_PWD_GECOS
 10282 #  ifndef NO_PWD_GECOS
 10283         __PROTECT__(returnArray);
 10283 	__PROTECT__(returnArray);
 10284         tmp = __MKSTRING(result->pw_gecos);
 10284 	tmp = __MKSTRING(result->pw_gecos);
 10285         __UNPROTECT__(returnArray);
 10285 	__UNPROTECT__(returnArray);
 10286         __arrayVal(returnArray)[idx++] = @symbol(gecos);
 10286 	__arrayVal(returnArray)[idx++] = @symbol(gecos);
 10287         __arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10287 	__arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10288 #  endif
 10288 #  endif
 10289         __PROTECT__(returnArray);
 10289 	__PROTECT__(returnArray);
 10290         tmp = __MKSTRING(result->pw_shell);
 10290 	tmp = __MKSTRING(result->pw_shell);
 10291          __UNPROTECT__(returnArray);
 10291 	 __UNPROTECT__(returnArray);
 10292         __arrayVal(returnArray)[idx++] = @symbol(shell);
 10292 	__arrayVal(returnArray)[idx++] = @symbol(shell);
 10293         __arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10293 	__arrayVal(returnArray)[idx++] = tmp; __STORE(returnArray, tmp);
 10294 
 10294 
 10295         __arrayVal(returnArray)[idx++] = @symbol(uid);
 10295 	__arrayVal(returnArray)[idx++] = @symbol(uid);
 10296         __arrayVal(returnArray)[idx++] = __mkSmallInteger(result->pw_uid);
 10296 	__arrayVal(returnArray)[idx++] = __mkSmallInteger(result->pw_uid);
 10297 
 10297 
 10298         __arrayVal(returnArray)[idx++] = @symbol(gid);
 10298 	__arrayVal(returnArray)[idx++] = @symbol(gid);
 10299         __arrayVal(returnArray)[idx++] = __mkSmallInteger(result->pw_gid);
 10299 	__arrayVal(returnArray)[idx++] = __mkSmallInteger(result->pw_gid);
 10300         RETURN(returnArray);
 10300 	RETURN(returnArray);
 10301     }
 10301     }
 10302 # endif /* ! NO_PWD */
 10302 # endif /* ! NO_PWD */
 10303 %}.
 10303 %}.
 10304     ^ nil
 10304     ^ nil
 10305 
 10305 
 10330 
 10330 
 10331     infoArray := self primUserInfoOf:aNameOrID.
 10331     infoArray := self primUserInfoOf:aNameOrID.
 10332     info := IdentityDictionary new.
 10332     info := IdentityDictionary new.
 10333 
 10333 
 10334     infoArray notNil ifTrue:[
 10334     infoArray notNil ifTrue:[
 10335         infoArray pairWiseDo:[:key :value|
 10335 	infoArray pairWiseDo:[:key :value|
 10336             key notNil ifTrue:[
 10336 	    key notNil ifTrue:[
 10337                 info at:key put:value.
 10337 		info at:key put:value.
 10338                 key == #name ifTrue:[name := value].
 10338 		key == #name ifTrue:[name := value].
 10339                 key == #dir  ifTrue:[dir := value].
 10339 		key == #dir  ifTrue:[dir := value].
 10340             ].
 10340 	    ].
 10341         ].
 10341 	].
 10342     ].
 10342     ].
 10343 
 10343 
 10344     name isNil ifTrue:[
 10344     name isNil ifTrue:[
 10345         info at:#name put:#unknown
 10345 	info at:#name put:#unknown
 10346     ].
 10346     ].
 10347     dir isNil ifTrue:[
 10347     dir isNil ifTrue:[
 10348         aNameOrID == self getUserID ifTrue:[
 10348 	aNameOrID == self getUserID ifTrue:[
 10349             info at:#dir put:self getHomeDirectory
 10349 	    info at:#dir put:self getHomeDirectory
 10350         ]
 10350 	]
 10351     ].
 10351     ].
 10352 
 10352 
 10353     ^ info
 10353     ^ info
 10354 
 10354 
 10355     "
 10355     "
 10407     int s;
 10407     int s;
 10408 #   define __WAIT      wait(&s)
 10408 #   define __WAIT      wait(&s)
 10409 #   define __BLOCKING_WAIT__ 1
 10409 #   define __BLOCKING_WAIT__ 1
 10410 
 10410 
 10411     if (blocking != true) {
 10411     if (blocking != true) {
 10412         /*
 10412 	/*
 10413          * We do not support nonBlocking waits, so signal an error
 10413 	 * We do not support nonBlocking waits, so signal an error
 10414          * Sorry about the goto, but with all these ifdefs ...
 10414 	 * Sorry about the goto, but with all these ifdefs ...
 10415          */
 10415 	 */
 10416         goto done;
 10416 	goto done;
 10417     }
 10417     }
 10418 # endif /*!HAS_WAIT3*/
 10418 # endif /*!HAS_WAIT3*/
 10419 #endif  /*!HAS_WAITPID*/
 10419 #endif  /*!HAS_WAITPID*/
 10420 
 10420 
 10421 #if !defined(WIFEXITED)
 10421 #if !defined(WIFEXITED)
 10442 #if __BLOCKING_WAIT__
 10442 #if __BLOCKING_WAIT__
 10443     __BEGIN_INTERRUPTABLE__
 10443     __BEGIN_INTERRUPTABLE__
 10444 #endif
 10444 #endif
 10445 
 10445 
 10446     do {
 10446     do {
 10447         p = __WAIT;
 10447 	p = __WAIT;
 10448     } while (p == -1 && errno == EINTR);
 10448     } while (p == -1 && errno == EINTR);
 10449 
 10449 
 10450 #if __BLOCKING_WAIT__
 10450 #if __BLOCKING_WAIT__
 10451     __END_INTERRUPTABLE__
 10451     __END_INTERRUPTABLE__
 10452 #  undef __BLOCKING_WAIT__
 10452 #  undef __BLOCKING_WAIT__
 10453 #endif
 10453 #endif
 10454 
 10454 
 10455 #undef __WAIT
 10455 #undef __WAIT
 10456 
 10456 
 10457     if (p == 0)
 10457     if (p == 0)
 10458         RETURN(nil)
 10458 	RETURN(nil)
 10459 
 10459 
 10460     if (p == -1) {
 10460     if (p == -1) {
 10461         if (errno == ECHILD)
 10461 	if (errno == ECHILD)
 10462             RETURN(nil);
 10462 	    RETURN(nil);
 10463     } else {
 10463     } else {
 10464         pid = __mkSmallInteger(p);
 10464 	pid = __mkSmallInteger(p);
 10465         if (WIFEXITED(s)) {
 10465 	if (WIFEXITED(s)) {
 10466             status = @symbol(exit);
 10466 	    status = @symbol(exit);
 10467             code = __mkSmallInteger(WEXITSTATUS(s));
 10467 	    code = __mkSmallInteger(WEXITSTATUS(s));
 10468             core = WCOREDUMP(s) ? true : false;
 10468 	    core = WCOREDUMP(s) ? true : false;
 10469         } else if (WIFSIGNALED(s)) {
 10469 	} else if (WIFSIGNALED(s)) {
 10470             status = @symbol(signal);
 10470 	    status = @symbol(signal);
 10471             code = __mkSmallInteger(WTERMSIG(s));
 10471 	    code = __mkSmallInteger(WTERMSIG(s));
 10472         } else if (WIFSTOPPED(s)) {
 10472 	} else if (WIFSTOPPED(s)) {
 10473             status = @symbol(stop);
 10473 	    status = @symbol(stop);
 10474             code = __mkSmallInteger(WSTOPSIG(s));
 10474 	    code = __mkSmallInteger(WSTOPSIG(s));
 10475         }
 10475 	}
 10476 #if defined(WIFCONTINUED)
 10476 #if defined(WIFCONTINUED)
 10477         else if (WIFCONTINUED(s)) {
 10477 	else if (WIFCONTINUED(s)) {
 10478             status = @symbol(continue);
 10478 	    status = @symbol(continue);
 10479         }
 10479 	}
 10480 #endif
 10480 #endif
 10481     }
 10481     }
 10482 done: ;
 10482 done: ;
 10483 %}.
 10483 %}.
 10484 
 10484 
 10485     (status isNil or:[pid isNil]) ifTrue:[
 10485     (status isNil or:[pid isNil]) ifTrue:[
 10486         ^ self primitiveFailed
 10486 	^ self primitiveFailed
 10487     ].
 10487     ].
 10488 
 10488 
 10489 "/ Transcript show:'pid: '; show:pid; show:' status: '; show:status;
 10489 "/ Transcript show:'pid: '; show:pid; show:' status: '; show:status;
 10490 "/ show:' code: '; show:code; show:' core:'; showCR:core.
 10490 "/ show:' code: '; show:code; show:' core:'; showCR:core.
 10491 
 10491 
 10520 # elif defined(FNDELAY)
 10520 # elif defined(FNDELAY)
 10521 #  define DELAY_FLAG FNDELAY
 10521 #  define DELAY_FLAG FNDELAY
 10522 # endif
 10522 # endif
 10523 # if defined(DELAY_FLAG)
 10523 # if defined(DELAY_FLAG)
 10524     if (__isSmallInteger(fd)) {
 10524     if (__isSmallInteger(fd)) {
 10525         int f = __intVal(fd);
 10525 	int f = __intVal(fd);
 10526 
 10526 
 10527         flags = fcntl(f, F_GETFL, 0);
 10527 	flags = fcntl(f, F_GETFL, 0);
 10528         RETURN ((flags & DELAY_FLAG) ? false : true );
 10528 	RETURN ((flags & DELAY_FLAG) ? false : true );
 10529     }
 10529     }
 10530 #  undef DELAY_FLAG
 10530 #  undef DELAY_FLAG
 10531 # endif
 10531 # endif
 10532 #endif
 10532 #endif
 10533 %}.
 10533 %}.
 10544     /*
 10544     /*
 10545      * if available, try FIONREAD first, which is usually done faster.
 10545      * if available, try FIONREAD first, which is usually done faster.
 10546      */
 10546      */
 10547 # if 0 && defined(FIONREAD)
 10547 # if 0 && defined(FIONREAD)
 10548     {
 10548     {
 10549         int n;
 10549 	int n;
 10550 
 10550 
 10551         if (__isSmallInteger(fd)) {
 10551 	if (__isSmallInteger(fd)) {
 10552             if (ioctl(__intVal(fd), FIONREAD, &n) >= 0) {
 10552 	    if (ioctl(__intVal(fd), FIONREAD, &n) >= 0) {
 10553                 RETURN (__MKINT(n));
 10553 		RETURN (__MKINT(n));
 10554             }
 10554 	    }
 10555         }
 10555 	}
 10556     }
 10556     }
 10557 # endif /* FIONREAD */
 10557 # endif /* FIONREAD */
 10558 %}.
 10558 %}.
 10559     ^ (self readCheck:fd) ifTrue:[1] ifFalse:[0]
 10559     ^ (self readCheck:fd) ifTrue:[1] ifFalse:[0]
 10560 !
 10560 !
 10568     /*
 10568     /*
 10569      * if available, try FIONREAD first, which is usually done faster.
 10569      * if available, try FIONREAD first, which is usually done faster.
 10570      */
 10570      */
 10571 #if 0 && defined(FIONREAD)
 10571 #if 0 && defined(FIONREAD)
 10572     if (__isSmallInteger(fd)) {
 10572     if (__isSmallInteger(fd)) {
 10573         int result = 0;
 10573 	int result = 0;
 10574 
 10574 
 10575         if (ioctl(__smallIntegerVal(fd), FIONREAD, &result) >= 0) {
 10575 	if (ioctl(__smallIntegerVal(fd), FIONREAD, &result) >= 0) {
 10576             RETURN(result > 0 ? true : false);
 10576 	    RETURN(result > 0 ? true : false);
 10577         }
 10577 	}
 10578     }
 10578     }
 10579 #endif /* FIONREAD */
 10579 #endif /* FIONREAD */
 10580 %}.
 10580 %}.
 10581 
 10581 
 10582     ^ super readCheck:fd
 10582     ^ super readCheck:fd
 10583 !
 10583 !
 10584 
 10584 
 10585 selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray
 10585 selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray
 10586         readableInto:readableResultFdArray writableInto:writableResultFdArray
 10586 	readableInto:readableResultFdArray writableInto:writableResultFdArray
 10587         exceptionInto:exceptionResultFdArray
 10587 	exceptionInto:exceptionResultFdArray
 10588         withTimeOut:millis
 10588 	withTimeOut:millis
 10589 
 10589 
 10590     "wait for any fd in readFdArray (an Array of integers) to become ready for reading,
 10590     "wait for any fd in readFdArray (an Array of integers) to become ready for reading,
 10591      writeFdArray to become ready for writing,
 10591      writeFdArray to become ready for writing,
 10592      or exceptFdArray to arrive exceptional data (i.e. out-of-band data).
 10592      or exceptFdArray to arrive exceptional data (i.e. out-of-band data).
 10593      Timeout after t milliseconds or - if the timeout time is 0 - immediately.
 10593      Timeout after t milliseconds or - if the timeout time is 0 - immediately.
 10613     int *pcntR = &cntR, *pcntW = &cntW, *pcntE = &cntE;
 10613     int *pcntR = &cntR, *pcntW = &cntW, *pcntE = &cntE;
 10614     int resultSizeReadable = 0, resultSizeWritable = 0, resultSizeException = 0;
 10614     int resultSizeReadable = 0, resultSizeWritable = 0, resultSizeException = 0;
 10615     int numFds = 0;
 10615     int numFds = 0;
 10616 
 10616 
 10617     if (readableResultFdArray != nil) {
 10617     if (readableResultFdArray != nil) {
 10618         if (! __isArrayLike(readableResultFdArray)) {
 10618 	if (! __isArrayLike(readableResultFdArray)) {
 10619             goto fail;
 10619 	    goto fail;
 10620         }
 10620 	}
 10621         resultSizeReadable = __arraySize(readableResultFdArray);
 10621 	resultSizeReadable = __arraySize(readableResultFdArray);
 10622     }
 10622     }
 10623     if (writableResultFdArray != nil) {
 10623     if (writableResultFdArray != nil) {
 10624         if (! __isArrayLike(writableResultFdArray)) {
 10624 	if (! __isArrayLike(writableResultFdArray)) {
 10625             goto fail;
 10625 	    goto fail;
 10626         }
 10626 	}
 10627         resultSizeWritable = __arraySize(writableResultFdArray);
 10627 	resultSizeWritable = __arraySize(writableResultFdArray);
 10628         if (readableResultFdArray == writableResultFdArray) {
 10628 	if (readableResultFdArray == writableResultFdArray) {
 10629             // allow common result set for read/write/except
 10629 	    // allow common result set for read/write/except
 10630             pcntW = &cntR;
 10630 	    pcntW = &cntR;
 10631         }
 10631 	}
 10632     }
 10632     }
 10633     if (exceptionResultFdArray != nil) {
 10633     if (exceptionResultFdArray != nil) {
 10634         if (! __isArrayLike(exceptionResultFdArray)) {
 10634 	if (! __isArrayLike(exceptionResultFdArray)) {
 10635             goto fail;
 10635 	    goto fail;
 10636         }
 10636 	}
 10637         resultSizeException = __arraySize(exceptionResultFdArray);
 10637 	resultSizeException = __arraySize(exceptionResultFdArray);
 10638         if (exceptionResultFdArray == readableResultFdArray) {
 10638 	if (exceptionResultFdArray == readableResultFdArray) {
 10639             // allow common result set for read/write/except
 10639 	    // allow common result set for read/write/except
 10640             pcntE = &cntR;
 10640 	    pcntE = &cntR;
 10641         } else if (exceptionResultFdArray == writableResultFdArray) {
 10641 	} else if (exceptionResultFdArray == writableResultFdArray) {
 10642             pcntE = &cntW;
 10642 	    pcntE = &cntW;
 10643         }
 10643 	}
 10644     }
 10644     }
 10645 
 10645 
 10646     FD_ZERO(&rset);
 10646     FD_ZERO(&rset);
 10647     FD_ZERO(&wset);
 10647     FD_ZERO(&wset);
 10648     FD_ZERO(&eset);
 10648     FD_ZERO(&eset);
 10649 
 10649 
 10650     maxF = -1;
 10650     maxF = -1;
 10651     if (readFdArray != nil) {
 10651     if (readFdArray != nil) {
 10652         int i, count;
 10652 	int i, count;
 10653 
 10653 
 10654         if (! __isArrayLike(readFdArray)) {
 10654 	if (! __isArrayLike(readFdArray)) {
 10655             goto fail;
 10655 	    goto fail;
 10656         }
 10656 	}
 10657         count = __arraySize(readFdArray);
 10657 	count = __arraySize(readFdArray);
 10658 
 10658 
 10659         for (i=0; i<count;i++) {
 10659 	for (i=0; i<count;i++) {
 10660             OBJ fd;
 10660 	    OBJ fd;
 10661 
 10661 
 10662             fd = __arrayVal(readFdArray)[i];
 10662 	    fd = __arrayVal(readFdArray)[i];
 10663             if (fd != nil) {
 10663 	    if (fd != nil) {
 10664                 if (! __isSmallInteger(fd)) {
 10664 		if (! __isSmallInteger(fd)) {
 10665                     if (@global(InfoPrinting) == true) {
 10665 		    if (@global(InfoPrinting) == true) {
 10666                         fprintf(stderr, "OS [warning]: funny read-fd (0x%lx) given to select\n", (unsigned long)fd);
 10666 			fprintf(stderr, "OS [warning]: funny read-fd (0x%lx) given to select\n", (unsigned long)fd);
 10667                     }
 10667 		    }
 10668                 } else {
 10668 		} else {
 10669                     int f;
 10669 		    int f;
 10670 
 10670 
 10671                     f = __intVal(fd);
 10671 		    f = __intVal(fd);
 10672                     if ((unsigned)f < FD_SETSIZE) {
 10672 		    if ((unsigned)f < FD_SETSIZE) {
 10673                         FD_SET(f, &rset);
 10673 			FD_SET(f, &rset);
 10674                         if (f > maxF) maxF = f;
 10674 			if (f > maxF) maxF = f;
 10675                         numFds++;
 10675 			numFds++;
 10676                     } else {
 10676 		    } else {
 10677                         if (@global(InfoPrinting) == true) {
 10677 			if (@global(InfoPrinting) == true) {
 10678                             fprintf(stderr, "OS [warning]: huge read-fd (0x%lx) given to select\n", (unsigned long)fd);
 10678 			    fprintf(stderr, "OS [warning]: huge read-fd (0x%lx) given to select\n", (unsigned long)fd);
 10679                         }
 10679 			}
 10680                     }
 10680 		    }
 10681                 }
 10681 		}
 10682             }
 10682 	    }
 10683         }
 10683 	}
 10684     }
 10684     }
 10685 
 10685 
 10686     if (writeFdArray != nil) {
 10686     if (writeFdArray != nil) {
 10687         int i, count;
 10687 	int i, count;
 10688 
 10688 
 10689         if (! __isArrayLike(writeFdArray)) {
 10689 	if (! __isArrayLike(writeFdArray)) {
 10690             goto fail;
 10690 	    goto fail;
 10691         }
 10691 	}
 10692         count = __arraySize(writeFdArray);
 10692 	count = __arraySize(writeFdArray);
 10693         for (i=0; i<count;i++) {
 10693 	for (i=0; i<count;i++) {
 10694             OBJ fd;
 10694 	    OBJ fd;
 10695 
 10695 
 10696             fd = __arrayVal(writeFdArray)[i];
 10696 	    fd = __arrayVal(writeFdArray)[i];
 10697             if (fd != nil) {
 10697 	    if (fd != nil) {
 10698                 if (! __isSmallInteger(fd)) {
 10698 		if (! __isSmallInteger(fd)) {
 10699                     if (@global(InfoPrinting) == true) {
 10699 		    if (@global(InfoPrinting) == true) {
 10700                         fprintf(stderr, "OS [warning]: funny write-fd (0x%lx) given to select\n", (unsigned long)fd);
 10700 			fprintf(stderr, "OS [warning]: funny write-fd (0x%lx) given to select\n", (unsigned long)fd);
 10701                     }
 10701 		    }
 10702                 } else {
 10702 		} else {
 10703                     int f;
 10703 		    int f;
 10704 
 10704 
 10705                     f = __intVal(fd);
 10705 		    f = __intVal(fd);
 10706                     if ((unsigned)f < FD_SETSIZE) {
 10706 		    if ((unsigned)f < FD_SETSIZE) {
 10707                         FD_SET(f, &wset);
 10707 			FD_SET(f, &wset);
 10708                         if (f > maxF) maxF = f;
 10708 			if (f > maxF) maxF = f;
 10709                         numFds++;
 10709 			numFds++;
 10710                     } else {
 10710 		    } else {
 10711                         if (@global(InfoPrinting) == true) {
 10711 			if (@global(InfoPrinting) == true) {
 10712                             fprintf(stderr, "OS [warning]: huge write-fd (0x%lx) given to select\n", (unsigned long)fd);
 10712 			    fprintf(stderr, "OS [warning]: huge write-fd (0x%lx) given to select\n", (unsigned long)fd);
 10713                         }
 10713 			}
 10714                     }
 10714 		    }
 10715                 }
 10715 		}
 10716             }
 10716 	    }
 10717         }
 10717 	}
 10718     }
 10718     }
 10719 
 10719 
 10720     if (exceptFdArray != nil) {
 10720     if (exceptFdArray != nil) {
 10721         int i, count;
 10721 	int i, count;
 10722 
 10722 
 10723         if (! __isArrayLike(exceptFdArray)) {
 10723 	if (! __isArrayLike(exceptFdArray)) {
 10724             goto fail;
 10724 	    goto fail;
 10725         }
 10725 	}
 10726         count = __arraySize(exceptFdArray);
 10726 	count = __arraySize(exceptFdArray);
 10727         for (i=0; i<count;i++) {
 10727 	for (i=0; i<count;i++) {
 10728             OBJ fd;
 10728 	    OBJ fd;
 10729 
 10729 
 10730             fd = __arrayVal(exceptFdArray)[i];
 10730 	    fd = __arrayVal(exceptFdArray)[i];
 10731             if (fd != nil) {
 10731 	    if (fd != nil) {
 10732                 if (! __isSmallInteger(fd)) {
 10732 		if (! __isSmallInteger(fd)) {
 10733                     if (@global(InfoPrinting) == true) {
 10733 		    if (@global(InfoPrinting) == true) {
 10734                         fprintf(stderr, "OS [warning]: funny except-fd (0x%lx) given to select\n", (unsigned long)fd);
 10734 			fprintf(stderr, "OS [warning]: funny except-fd (0x%lx) given to select\n", (unsigned long)fd);
 10735                     }
 10735 		    }
 10736                 } else {
 10736 		} else {
 10737                     int f;
 10737 		    int f;
 10738 
 10738 
 10739                     f = __intVal(fd);
 10739 		    f = __intVal(fd);
 10740                     if ((unsigned)f < FD_SETSIZE) {
 10740 		    if ((unsigned)f < FD_SETSIZE) {
 10741                         FD_SET(f, &eset);
 10741 			FD_SET(f, &eset);
 10742                         if (f > maxF) maxF = f;
 10742 			if (f > maxF) maxF = f;
 10743                         numFds++;
 10743 			numFds++;
 10744                     } else {
 10744 		    } else {
 10745                         if (@global(InfoPrinting) == true) {
 10745 			if (@global(InfoPrinting) == true) {
 10746                             fprintf(stderr, "OS [warning]: huge except-fd (0x%lx) given to select\n", (unsigned long)fd);
 10746 			    fprintf(stderr, "OS [warning]: huge except-fd (0x%lx) given to select\n", (unsigned long)fd);
 10747                         }
 10747 			}
 10748                     }
 10748 		    }
 10749                 }
 10749 		}
 10750             }
 10750 	    }
 10751         }
 10751 	}
 10752     }
 10752     }
 10753 
 10753 
 10754     if (millis == nil) {
 10754     if (millis == nil) {
 10755         wtp = NULL;         // wait forever
 10755 	wtp = NULL;         // wait forever
 10756     } else if (__isSmallInteger(millis)) {
 10756     } else if (__isSmallInteger(millis)) {
 10757         __millis = __intVal(millis);
 10757 	__millis = __intVal(millis);
 10758         if (__millis > 0) {
 10758 	if (__millis > 0) {
 10759             wt.tv_sec = __millis / 1000;
 10759 	    wt.tv_sec = __millis / 1000;
 10760             wt.tv_usec = (__millis % 1000) * 1000;
 10760 	    wt.tv_usec = (__millis % 1000) * 1000;
 10761         } else {
 10761 	} else {
 10762             wt.tv_sec = wt.tv_usec = 0;
 10762 	    wt.tv_sec = wt.tv_usec = 0;
 10763         }
 10763 	}
 10764         wtp = &wt;
 10764 	wtp = &wt;
 10765     } else {
 10765     } else {
 10766         goto fail;
 10766 	goto fail;
 10767     }
 10767     }
 10768 
 10768 
 10769     /*
 10769     /*
 10770      * make certain, that interrupt gets us out of the select
 10770      * make certain, that interrupt gets us out of the select
 10771      * However, we must then care for moved objects.
 10771      * However, we must then care for moved objects.
 10772      */
 10772      */
 10773     __BEGIN_INTERRUPTABLE__
 10773     __BEGIN_INTERRUPTABLE__
 10774 
 10774 
 10775     if (__millis == 0) {
 10775     if (__millis == 0) {
 10776         /*
 10776 	/*
 10777          * if there is no timeout time, we can stay here interruptable.
 10777 	 * if there is no timeout time, we can stay here interruptable.
 10778          */
 10778 	 */
 10779         do {
 10779 	do {
 10780             ret = select(maxF+1, &rset, &wset, &eset, wtp);
 10780 	    ret = select(maxF+1, &rset, &wset, &eset, wtp);
 10781         } while ((ret < 0) && (errno == EINTR));
 10781 	} while ((ret < 0) && (errno == EINTR));
 10782     } else {
 10782     } else {
 10783         do {
 10783 	do {
 10784             ret = select(maxF+1, &rset, &wset, &eset, wtp);
 10784 	    ret = select(maxF+1, &rset, &wset, &eset, wtp);
 10785             /*
 10785 	    /*
 10786              * for now: don't loop; if we did, we had to adjust the vt-timeval;
 10786 	     * for now: don't loop; if we did, we had to adjust the vt-timeval;
 10787              * could otherwise stay in this loop forever ...
 10787 	     * could otherwise stay in this loop forever ...
 10788              * Premature ret (before the time expired) must be handled by the caller.
 10788 	     * Premature ret (before the time expired) must be handled by the caller.
 10789              * A good solution is to update the wt-timeval and redo the select.
 10789 	     * A good solution is to update the wt-timeval and redo the select.
 10790              */
 10790 	     */
 10791         } while (0 /* (ret < 0) && (errno == EINTR) */ );
 10791 	} while (0 /* (ret < 0) && (errno == EINTR) */ );
 10792     }
 10792     }
 10793     __END_INTERRUPTABLE__
 10793     __END_INTERRUPTABLE__
 10794 
 10794 
 10795     if (ret > 0) {
 10795     if (ret > 0) {
 10796         OBJ *__resultR = __arrayVal(readableResultFdArray);
 10796 	OBJ *__resultR = __arrayVal(readableResultFdArray);
 10797         OBJ *__resultW = __arrayVal(writableResultFdArray);
 10797 	OBJ *__resultW = __arrayVal(writableResultFdArray);
 10798         OBJ *__resultE = __arrayVal(exceptionResultFdArray);
 10798 	OBJ *__resultE = __arrayVal(exceptionResultFdArray);
 10799         int i;
 10799 	int i;
 10800 
 10800 
 10801         for (i=0; i <= maxF; i++) {
 10801 	for (i=0; i <= maxF; i++) {
 10802             if (FD_ISSET(i, &rset)) {
 10802 	    if (FD_ISSET(i, &rset)) {
 10803                 if (*pcntR < resultSizeReadable) {
 10803 		if (*pcntR < resultSizeReadable) {
 10804                     __resultR[*pcntR] = __mkSmallInteger(i);
 10804 		    __resultR[*pcntR] = __mkSmallInteger(i);
 10805                 }
 10805 		}
 10806                 (*pcntR)++; cntAll++;
 10806 		(*pcntR)++; cntAll++;
 10807             }
 10807 	    }
 10808 
 10808 
 10809             if (FD_ISSET(i, &wset)) {
 10809 	    if (FD_ISSET(i, &wset)) {
 10810                 if (*pcntW < resultSizeWritable) {
 10810 		if (*pcntW < resultSizeWritable) {
 10811                     __resultW[*pcntW] = __mkSmallInteger(i);
 10811 		    __resultW[*pcntW] = __mkSmallInteger(i);
 10812                 }
 10812 		}
 10813                 (*pcntW)++; cntAll++;
 10813 		(*pcntW)++; cntAll++;
 10814             }
 10814 	    }
 10815 
 10815 
 10816             if (FD_ISSET(i, &eset)) {
 10816 	    if (FD_ISSET(i, &eset)) {
 10817                 if (*pcntE < resultSizeException) {
 10817 		if (*pcntE < resultSizeException) {
 10818                     __resultE[*pcntE] = __mkSmallInteger(i);
 10818 		    __resultE[*pcntE] = __mkSmallInteger(i);
 10819                 }
 10819 		}
 10820                 (*pcntE)++;  cntAll++;
 10820 		(*pcntE)++;  cntAll++;
 10821             }
 10821 	    }
 10822         }
 10822 	}
 10823         /* add a delimiter */
 10823 	/* add a delimiter */
 10824         if (*pcntR < resultSizeReadable) {
 10824 	if (*pcntR < resultSizeReadable) {
 10825             __resultR[*pcntR] = nil;
 10825 	    __resultR[*pcntR] = nil;
 10826         }
 10826 	}
 10827         if (*pcntW < resultSizeWritable) {
 10827 	if (*pcntW < resultSizeWritable) {
 10828             __resultW[*pcntW] = nil;
 10828 	    __resultW[*pcntW] = nil;
 10829         }
 10829 	}
 10830         if (*pcntE < resultSizeException) {
 10830 	if (*pcntE < resultSizeException) {
 10831             __resultE[*pcntE] = nil;
 10831 	    __resultE[*pcntE] = nil;
 10832         }
 10832 	}
 10833 
 10833 
 10834         RETURN (__mkSmallInteger(cntAll));
 10834 	RETURN (__mkSmallInteger(cntAll));
 10835     } else if (ret < 0 && errno != EINTR) {
 10835     } else if (ret < 0 && errno != EINTR) {
 10836         /*
 10836 	/*
 10837          * Error: Return -1
 10837 	 * Error: Return -1
 10838          */
 10838 	 */
 10839         if (@global(InfoPrinting) == true) {
 10839 	if (@global(InfoPrinting) == true) {
 10840             fprintf(stderr, "OS [info]: select errno = %d\n", errno);
 10840 	    fprintf(stderr, "OS [info]: select errno = %d\n", errno);
 10841         }
 10841 	}
 10842         @global(LastErrorNumber) = __mkSmallInteger(errno);
 10842 	@global(LastErrorNumber) = __mkSmallInteger(errno);
 10843         RETURN (__mkSmallInteger(-1));
 10843 	RETURN (__mkSmallInteger(-1));
 10844     }
 10844     }
 10845 
 10845 
 10846     /*
 10846     /*
 10847      * Return 0 (no filedescriptor ready)
 10847      * Return 0 (no filedescriptor ready)
 10848      */
 10848      */
 10881 # elif defined(FNDELAY)
 10881 # elif defined(FNDELAY)
 10882 #  define DELAY_FLAG FNDELAY
 10882 #  define DELAY_FLAG FNDELAY
 10883 # endif
 10883 # endif
 10884 # if defined(DELAY_FLAG)
 10884 # if defined(DELAY_FLAG)
 10885     if (__isSmallInteger(fd)) {
 10885     if (__isSmallInteger(fd)) {
 10886         int f = __intVal(fd);
 10886 	int f = __intVal(fd);
 10887 
 10887 
 10888         flags = fcntl(f, F_GETFL, 0);
 10888 	flags = fcntl(f, F_GETFL, 0);
 10889         if (aBoolean == true) {
 10889 	if (aBoolean == true) {
 10890             ret = fcntl(f, F_SETFL, flags & ~DELAY_FLAG);
 10890 	    ret = fcntl(f, F_SETFL, flags & ~DELAY_FLAG);
 10891         } else if (aBoolean == false) {
 10891 	} else if (aBoolean == false) {
 10892             ret = fcntl(f, F_SETFL, flags | DELAY_FLAG);
 10892 	    ret = fcntl(f, F_SETFL, flags | DELAY_FLAG);
 10893         }
 10893 	}
 10894         if (ret >= 0) {
 10894 	if (ret >= 0) {
 10895             RETURN ((flags & DELAY_FLAG) ? false : true );
 10895 	    RETURN ((flags & DELAY_FLAG) ? false : true );
 10896         }
 10896 	}
 10897     }
 10897     }
 10898 #  undef DELAY_FLAG
 10898 #  undef DELAY_FLAG
 10899 # endif
 10899 # endif
 10900 #endif
 10900 #endif
 10901 %}.
 10901 %}.
 10909 
 10909 
 10910 update:aspect with:argument from:anObject
 10910 update:aspect with:argument from:anObject
 10911     "one of our registered handles has been collected"
 10911     "one of our registered handles has been collected"
 10912 
 10912 
 10913     aspect == #ElementExpired ifTrue:[
 10913     aspect == #ElementExpired ifTrue:[
 10914         OpenFiles keysAndValuesDo:[:fd :handle |
 10914 	OpenFiles keysAndValuesDo:[:fd :handle |
 10915             handle == 0 ifTrue:[
 10915 	    handle == 0 ifTrue:[
 10916                 "Have to close the file descriptor"
 10916 		"Have to close the file descriptor"
 10917 
 10917 
 10918                 OperatingSystem closeFd:fd.
 10918 		OperatingSystem closeFd:fd.
 10919                 OpenFiles at:fd put:nil.
 10919 		OpenFiles at:fd put:nil.
 10920             ].
 10920 	    ].
 10921         ].
 10921 	].
 10922     ].
 10922     ].
 10923 
 10923 
 10924     "Created: 30.9.1997 / 12:57:35 / stefan"
 10924     "Created: 30.9.1997 / 12:57:35 / stefan"
 10925 ! !
 10925 ! !
 10926 
 10926 
 10929 initialize
 10929 initialize
 10930     OpenFiles := WeakArray new:10.
 10930     OpenFiles := WeakArray new:10.
 10931     OpenFiles addDependent:self.
 10931     OpenFiles addDependent:self.
 10932 
 10932 
 10933     "
 10933     "
 10934         self initialize
 10934 	self initialize
 10935     "
 10935     "
 10936 
 10936 
 10937     "Created: 26.9.1997 / 17:15:50 / stefan"
 10937     "Created: 26.9.1997 / 17:15:50 / stefan"
 10938     "Modified: 30.9.1997 / 12:40:55 / stefan"
 10938     "Modified: 30.9.1997 / 12:40:55 / stefan"
 10939 ! !
 10939 ! !
 10953 error:anErrorSymbolOrErrno
 10953 error:anErrorSymbolOrErrno
 10954     "got an error; arg is either a symbol specifying a primitive error
 10954     "got an error; arg is either a symbol specifying a primitive error
 10955      or the error number as returned by the OperatingSystem"
 10955      or the error number as returned by the OperatingSystem"
 10956 
 10956 
 10957     anErrorSymbolOrErrno isInteger ifTrue:[
 10957     anErrorSymbolOrErrno isInteger ifTrue:[
 10958         (UnixOperatingSystem errorHolderForNumber:anErrorSymbolOrErrno) reportError
 10958 	(UnixOperatingSystem errorHolderForNumber:anErrorSymbolOrErrno) reportError
 10959     ].
 10959     ].
 10960     self primitiveFailed:anErrorSymbolOrErrno.
 10960     self primitiveFailed:anErrorSymbolOrErrno.
 10961 ! !
 10961 ! !
 10962 
 10962 
 10963 !UnixOperatingSystem::FileDescriptorHandle methodsFor:'file access'!
 10963 !UnixOperatingSystem::FileDescriptorHandle methodsFor:'file access'!
 10988      Spotted by Martin Kobetic."
 10988      Spotted by Martin Kobetic."
 10989     oldHandle := OpenFiles at:aFileDescriptor ifAbsent: [nil].
 10989     oldHandle := OpenFiles at:aFileDescriptor ifAbsent: [nil].
 10990     "/ the 0 is possible, if an fd was open when saving a snapshot image,
 10990     "/ the 0 is possible, if an fd was open when saving a snapshot image,
 10991     "/ and we come up in the new image with no one referring to it.
 10991     "/ and we come up in the new image with no one referring to it.
 10992     (oldHandle notNil and:[oldHandle ~~ 0 and:[ oldHandle ~~ self]]) ifTrue:[
 10992     (oldHandle notNil and:[oldHandle ~~ 0 and:[ oldHandle ~~ self]]) ifTrue:[
 10993         oldHandle invalidate.
 10993 	oldHandle invalidate.
 10994     ].
 10994     ].
 10995     self register.
 10995     self register.
 10996 
 10996 
 10997     "Created: 26.9.1997 / 17:14:40 / stefan"
 10997     "Created: 26.9.1997 / 17:14:40 / stefan"
 10998     "Modified: 30.9.1997 / 12:41:43 / stefan"
 10998     "Modified: 30.9.1997 / 12:41:43 / stefan"
 11017     INT fd;
 11017     INT fd;
 11018     INT cnt, offs;
 11018     INT cnt, offs;
 11019     int nInstBytes, objSize;
 11019     int nInstBytes, objSize;
 11020 
 11020 
 11021     if (! __isSmallInteger(__INST(fd))) {
 11021     if (! __isSmallInteger(__INST(fd))) {
 11022         error = @symbol(errorNotOpen);
 11022 	error = @symbol(errorNotOpen);
 11023         goto bad;
 11023 	goto bad;
 11024     }
 11024     }
 11025     if (! __bothSmallInteger(count, firstIndex)) {
 11025     if (! __bothSmallInteger(count, firstIndex)) {
 11026         error = @symbol(badArgument);
 11026 	error = @symbol(badArgument);
 11027         goto bad;
 11027 	goto bad;
 11028     }
 11028     }
 11029     fd = __smallIntegerVal(__INST(fd));
 11029     fd = __smallIntegerVal(__INST(fd));
 11030     cnt = __smallIntegerVal(count);
 11030     cnt = __smallIntegerVal(count);
 11031     offs = __smallIntegerVal(firstIndex) - 1;
 11031     offs = __smallIntegerVal(firstIndex) - 1;
 11032 
 11032 
 11033     if (fd < 0) {
 11033     if (fd < 0) {
 11034         error = @symbol(internalError);
 11034 	error = @symbol(internalError);
 11035         goto bad;
 11035 	goto bad;
 11036     }
 11036     }
 11037     if (__isExternalBytesLike(aByteBuffer)) {
 11037     if (__isExternalBytesLike(aByteBuffer)) {
 11038         OBJ sz;
 11038 	OBJ sz;
 11039 
 11039 
 11040         nInstBytes = 0;
 11040 	nInstBytes = 0;
 11041         extPtr = (char *)(__externalBytesAddress(aByteBuffer));
 11041 	extPtr = (char *)(__externalBytesAddress(aByteBuffer));
 11042         if (extPtr == NULL) goto bad;
 11042 	if (extPtr == NULL) goto bad;
 11043         sz = __externalBytesSize(aByteBuffer);
 11043 	sz = __externalBytesSize(aByteBuffer);
 11044         if (__isSmallInteger(sz)) {
 11044 	if (__isSmallInteger(sz)) {
 11045             objSize = __smallIntegerVal(sz);
 11045 	    objSize = __smallIntegerVal(sz);
 11046         } else {
 11046 	} else {
 11047             objSize = -1; /* unknown */
 11047 	    objSize = -1; /* unknown */
 11048         }
 11048 	}
 11049     } else {
 11049     } else {
 11050         OBJ oClass = __Class(aByteBuffer);
 11050 	OBJ oClass = __Class(aByteBuffer);
 11051         int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
 11051 	int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
 11052 
 11052 
 11053         nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
 11053 	nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
 11054         switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 11054 	switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 11055             case BYTEARRAY:
 11055 	    case BYTEARRAY:
 11056             case WORDARRAY:
 11056 	    case WORDARRAY:
 11057             case LONGARRAY:
 11057 	    case LONGARRAY:
 11058             case SWORDARRAY:
 11058 	    case SWORDARRAY:
 11059             case SLONGARRAY:
 11059 	    case SLONGARRAY:
 11060             case FLOATARRAY:
 11060 	    case FLOATARRAY:
 11061                 break;
 11061 		break;
 11062             case DOUBLEARRAY:
 11062 	    case DOUBLEARRAY:
 11063 #ifdef __NEED_DOUBLE_ALIGN
 11063 #ifdef __NEED_DOUBLE_ALIGN
 11064                 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
 11064 		nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
 11065 #endif
 11065 #endif
 11066                 break;
 11066 		break;
 11067             case LONGLONGARRAY:
 11067 	    case LONGLONGARRAY:
 11068             case SLONGLONGARRAY:
 11068 	    case SLONGLONGARRAY:
 11069 #ifdef __NEED_LONGLONG_ALIGN
 11069 #ifdef __NEED_LONGLONG_ALIGN
 11070                 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
 11070 		nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
 11071 #endif
 11071 #endif
 11072                 break;
 11072 		break;
 11073             default:
 11073 	    default:
 11074                 goto bad;
 11074 		goto bad;
 11075         }
 11075 	}
 11076         extPtr = (char *)0;
 11076 	extPtr = (char *)0;
 11077         objSize = __Size(aByteBuffer) - nInstBytes;
 11077 	objSize = __Size(aByteBuffer) - nInstBytes;
 11078     }
 11078     }
 11079     if ((offs >= 0)
 11079     if ((offs >= 0)
 11080         && (cnt >= 0)
 11080 	&& (cnt >= 0)
 11081         && ((objSize == -1) || (objSize >= (cnt + offs)))) {
 11081 	&& ((objSize == -1) || (objSize >= (cnt + offs)))) {
 11082         nRead = 0;
 11082 	nRead = 0;
 11083 
 11083 
 11084         do {
 11084 	do {
 11085             int n;
 11085 	    int n;
 11086 
 11086 
 11087             if (extPtr) {
 11087 	    if (extPtr) {
 11088                 n = read(fd, extPtr+offs, cnt);
 11088 		n = read(fd, extPtr+offs, cnt);
 11089             } else {
 11089 	    } else {
 11090                 char *bp;
 11090 		char *bp;
 11091 
 11091 
 11092                 /*
 11092 		/*
 11093                  * on interrupt, anObject may be moved to another location.
 11093 		 * on interrupt, anObject may be moved to another location.
 11094                  * So we recompute the byte-address here.
 11094 		 * So we recompute the byte-address here.
 11095                  */
 11095 		 */
 11096                 bp = __byteArrayVal(aByteBuffer) + nInstBytes;
 11096 		bp = __byteArrayVal(aByteBuffer) + nInstBytes;
 11097 
 11097 
 11098                 n = read(fd, bp + offs, cnt);
 11098 		n = read(fd, bp + offs, cnt);
 11099             }
 11099 	    }
 11100             if (n > 0) {
 11100 	    if (n > 0) {
 11101                 cnt -= n;
 11101 		cnt -= n;
 11102                 offs += n;
 11102 		offs += n;
 11103                 nRead += n;
 11103 		nRead += n;
 11104             } else if (n == 0) {
 11104 	    } else if (n == 0) {
 11105                 break;
 11105 		break;
 11106             } else if (n < 0) {
 11106 	    } else if (n < 0) {
 11107                 if (0
 11107 		if (0
 11108 #ifdef EWOULDBLOCK
 11108 #ifdef EWOULDBLOCK
 11109                     || errno == EWOULDBLOCK
 11109 		    || errno == EWOULDBLOCK
 11110 #endif
 11110 #endif
 11111 #ifdef EAGAIN
 11111 #ifdef EAGAIN
 11112                     || errno == EAGAIN
 11112 		    || errno == EAGAIN
 11113 #endif
 11113 #endif
 11114                 ) {
 11114 		) {
 11115                      RETURN(nil);
 11115 		     RETURN(nil);
 11116                 }
 11116 		}
 11117                 if (errno != EINTR) {
 11117 		if (errno != EINTR) {
 11118                      error = __mkSmallInteger(errno);
 11118 		     error = __mkSmallInteger(errno);
 11119                      goto bad;
 11119 		     goto bad;
 11120                 }
 11120 		}
 11121                 __HANDLE_INTERRUPTS__;
 11121 		__HANDLE_INTERRUPTS__;
 11122             }
 11122 	    }
 11123         } while (cnt > 0);
 11123 	} while (cnt > 0);
 11124 
 11124 
 11125         RETURN (__mkSmallInteger(nRead));
 11125 	RETURN (__mkSmallInteger(nRead));
 11126     }
 11126     }
 11127 bad: ;
 11127 bad: ;
 11128 %}.
 11128 %}.
 11129     ^ self error:error.
 11129     ^ self error:error.
 11130 
 11130 
 11159     INT fd;
 11159     INT fd;
 11160     INT cnt, offs;
 11160     INT cnt, offs;
 11161     int nInstBytes, objSize;
 11161     int nInstBytes, objSize;
 11162 
 11162 
 11163     if (! __isSmallInteger(__INST(fd))) {
 11163     if (! __isSmallInteger(__INST(fd))) {
 11164         error = @symbol(errorNotOpen);
 11164 	error = @symbol(errorNotOpen);
 11165         goto bad;
 11165 	goto bad;
 11166     }
 11166     }
 11167     if (! __bothSmallInteger(count, firstIndex)) {
 11167     if (! __bothSmallInteger(count, firstIndex)) {
 11168         error = @symbol(badArgument);
 11168 	error = @symbol(badArgument);
 11169         goto bad;
 11169 	goto bad;
 11170     }
 11170     }
 11171     fd = __smallIntegerVal(__INST(fd));
 11171     fd = __smallIntegerVal(__INST(fd));
 11172     cnt = __smallIntegerVal(count);
 11172     cnt = __smallIntegerVal(count);
 11173     offs = __smallIntegerVal(firstIndex) - 1;
 11173     offs = __smallIntegerVal(firstIndex) - 1;
 11174 
 11174 
 11175     if (fd < 0) {
 11175     if (fd < 0) {
 11176         error = @symbol(internalError);
 11176 	error = @symbol(internalError);
 11177         goto bad;
 11177 	goto bad;
 11178     }
 11178     }
 11179     if (__isExternalBytesLike(aByteBuffer)) {
 11179     if (__isExternalBytesLike(aByteBuffer)) {
 11180         OBJ sz;
 11180 	OBJ sz;
 11181 
 11181 
 11182         nInstBytes = 0;
 11182 	nInstBytes = 0;
 11183         extPtr = (char *)(__externalBytesAddress(aByteBuffer));
 11183 	extPtr = (char *)(__externalBytesAddress(aByteBuffer));
 11184         if (extPtr == NULL) goto bad;
 11184 	if (extPtr == NULL) goto bad;
 11185         sz = __externalBytesSize(aByteBuffer);
 11185 	sz = __externalBytesSize(aByteBuffer);
 11186         if (__isSmallInteger(sz)) {
 11186 	if (__isSmallInteger(sz)) {
 11187             objSize = __smallIntegerVal(sz);
 11187 	    objSize = __smallIntegerVal(sz);
 11188         } else {
 11188 	} else {
 11189             objSize = -1; /* unknown */
 11189 	    objSize = -1; /* unknown */
 11190         }
 11190 	}
 11191     } else {
 11191     } else {
 11192         OBJ oClass = __Class(aByteBuffer);
 11192 	OBJ oClass = __Class(aByteBuffer);
 11193         int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
 11193 	int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
 11194 
 11194 
 11195         nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
 11195 	nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
 11196         switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 11196 	switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 11197             case BYTEARRAY:
 11197 	    case BYTEARRAY:
 11198             case WORDARRAY:
 11198 	    case WORDARRAY:
 11199             case LONGARRAY:
 11199 	    case LONGARRAY:
 11200             case SWORDARRAY:
 11200 	    case SWORDARRAY:
 11201             case SLONGARRAY:
 11201 	    case SLONGARRAY:
 11202             case FLOATARRAY:
 11202 	    case FLOATARRAY:
 11203                 break;
 11203 		break;
 11204             case DOUBLEARRAY:
 11204 	    case DOUBLEARRAY:
 11205 #ifdef __NEED_DOUBLE_ALIGN
 11205 #ifdef __NEED_DOUBLE_ALIGN
 11206                 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
 11206 		nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
 11207 #endif
 11207 #endif
 11208                 break;
 11208 		break;
 11209             case LONGLONGARRAY:
 11209 	    case LONGLONGARRAY:
 11210             case SLONGLONGARRAY:
 11210 	    case SLONGLONGARRAY:
 11211 #ifdef __NEED_LONGLONG_ALIGN
 11211 #ifdef __NEED_LONGLONG_ALIGN
 11212                 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
 11212 		nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
 11213 #endif
 11213 #endif
 11214                 break;
 11214 		break;
 11215             default:
 11215 	    default:
 11216                 goto bad;
 11216 		goto bad;
 11217         }
 11217 	}
 11218         extPtr = (char *)0;
 11218 	extPtr = (char *)0;
 11219         objSize = __Size(aByteBuffer) - nInstBytes;
 11219 	objSize = __Size(aByteBuffer) - nInstBytes;
 11220     }
 11220     }
 11221     if ((offs >= 0)
 11221     if ((offs >= 0)
 11222         && (cnt >= 0)
 11222 	&& (cnt >= 0)
 11223         && ((objSize == -1) || (objSize >= (cnt + offs)))) {
 11223 	&& ((objSize == -1) || (objSize >= (cnt + offs)))) {
 11224         nWritten = 0;
 11224 	nWritten = 0;
 11225 
 11225 
 11226         do {
 11226 	do {
 11227             int n;
 11227 	    int n;
 11228 
 11228 
 11229             if (extPtr) {
 11229 	    if (extPtr) {
 11230                 n = write(fd, extPtr+offs, cnt);
 11230 		n = write(fd, extPtr+offs, cnt);
 11231             } else {
 11231 	    } else {
 11232                 char *bp;
 11232 		char *bp;
 11233 
 11233 
 11234                 /*
 11234 		/*
 11235                  * on interrupt, anObject may be moved to another location.
 11235 		 * on interrupt, anObject may be moved to another location.
 11236                  * So we recompute the byte-address here.
 11236 		 * So we recompute the byte-address here.
 11237                  */
 11237 		 */
 11238                 bp = __byteArrayVal(aByteBuffer) + nInstBytes;
 11238 		bp = __byteArrayVal(aByteBuffer) + nInstBytes;
 11239 
 11239 
 11240                 n = write(fd, bp + offs, cnt);
 11240 		n = write(fd, bp + offs, cnt);
 11241             }
 11241 	    }
 11242             if (n > 0) {
 11242 	    if (n > 0) {
 11243                 cnt -= n;
 11243 		cnt -= n;
 11244                 offs += n;
 11244 		offs += n;
 11245                 nWritten += n;
 11245 		nWritten += n;
 11246             } else if (n == 0) {
 11246 	    } else if (n == 0) {
 11247                 break;
 11247 		break;
 11248             } else if (n < 0) {
 11248 	    } else if (n < 0) {
 11249                 if (0
 11249 		if (0
 11250 #ifdef EWOULDBLOCK
 11250 #ifdef EWOULDBLOCK
 11251                     || errno == EWOULDBLOCK
 11251 		    || errno == EWOULDBLOCK
 11252 #endif
 11252 #endif
 11253 #ifdef EAGAIN
 11253 #ifdef EAGAIN
 11254                     || errno == EAGAIN
 11254 		    || errno == EAGAIN
 11255 #endif
 11255 #endif
 11256                 ) {
 11256 		) {
 11257                      RETURN(nil);
 11257 		     RETURN(nil);
 11258                 }
 11258 		}
 11259                 if (errno != EINTR) {
 11259 		if (errno != EINTR) {
 11260                      error = __mkSmallInteger(errno);
 11260 		     error = __mkSmallInteger(errno);
 11261                      goto bad;
 11261 		     goto bad;
 11262                 }
 11262 		}
 11263                 __HANDLE_INTERRUPTS__;
 11263 		__HANDLE_INTERRUPTS__;
 11264             }
 11264 	    }
 11265         } while (cnt > 0);
 11265 	} while (cnt > 0);
 11266 
 11266 
 11267         RETURN (__mkSmallInteger(nWritten));
 11267 	RETURN (__mkSmallInteger(nWritten));
 11268     }
 11268     }
 11269 bad: ;
 11269 bad: ;
 11270 %}.
 11270 %}.
 11271     ^ self error:error
 11271     ^ self error:error
 11272 
 11272 
 11313     INT __whence;
 11313     INT __whence;
 11314     off_t pos, ret;
 11314     off_t pos, ret;
 11315     OBJ rslt;
 11315     OBJ rslt;
 11316 
 11316 
 11317     if (! __isSmallInteger(__INST(fd))) {
 11317     if (! __isSmallInteger(__INST(fd))) {
 11318         error = @symbol(errorNotOpen);
 11318 	error = @symbol(errorNotOpen);
 11319         goto bad;
 11319 	goto bad;
 11320     }
 11320     }
 11321     if (__isSmallInteger(newPosition)) {
 11321     if (__isSmallInteger(newPosition)) {
 11322         pos = __smallIntegerVal(newPosition);
 11322 	pos = __smallIntegerVal(newPosition);
 11323     } else {
 11323     } else {
 11324         pos = __signedLongIntVal(newPosition);
 11324 	pos = __signedLongIntVal(newPosition);
 11325         if (pos < 0 && (sizeof(pos) < 8 || __signedLong64IntVal(newPosition, &pos) == 0)) {
 11325 	if (pos < 0 && (sizeof(pos) < 8 || __signedLong64IntVal(newPosition, &pos) == 0)) {
 11326             error = @symbol(badArgument1);
 11326 	    error = @symbol(badArgument1);
 11327             goto bad;
 11327 	    goto bad;
 11328         }
 11328 	}
 11329     }
 11329     }
 11330 
 11330 
 11331     fd = __smallIntegerVal(__INST(fd));
 11331     fd = __smallIntegerVal(__INST(fd));
 11332     if (fd < 0) {
 11332     if (fd < 0) {
 11333         error = @symbol(internalError);
 11333 	error = @symbol(internalError);
 11334         goto bad;
 11334 	goto bad;
 11335     }
 11335     }
 11336     if (whence == @symbol(begin)) {
 11336     if (whence == @symbol(begin)) {
 11337         __whence = SEEK_SET;
 11337 	__whence = SEEK_SET;
 11338     } else if (whence == @symbol(current)) {
 11338     } else if (whence == @symbol(current)) {
 11339         __whence = SEEK_CUR;
 11339 	__whence = SEEK_CUR;
 11340     } else if (whence == @symbol(end)) {
 11340     } else if (whence == @symbol(end)) {
 11341         __whence = SEEK_END;
 11341 	__whence = SEEK_END;
 11342     } else {
 11342     } else {
 11343         error = @symbol(badArgument2);
 11343 	error = @symbol(badArgument2);
 11344         goto bad;
 11344 	goto bad;
 11345     }
 11345     }
 11346 
 11346 
 11347 again:
 11347 again:
 11348     ret = lseek(fd, pos, __whence);
 11348     ret = lseek(fd, pos, __whence);
 11349     if (ret < 0) {
 11349     if (ret < 0) {
 11350         if (errno == EINTR) {
 11350 	if (errno == EINTR) {
 11351             __HANDLE_INTERRUPTS__;
 11351 	    __HANDLE_INTERRUPTS__;
 11352             goto again;
 11352 	    goto again;
 11353         }
 11353 	}
 11354         error = __mkSmallInteger(errno);
 11354 	error = __mkSmallInteger(errno);
 11355         goto bad;
 11355 	goto bad;
 11356     }
 11356     }
 11357 
 11357 
 11358     if (sizeof(ret) == 8) {
 11358     if (sizeof(ret) == 8) {
 11359         rslt = __MKINT64 (&ret);
 11359 	rslt = __MKINT64 (&ret);
 11360     } else {
 11360     } else {
 11361         rslt = __MKINT(ret);
 11361 	rslt = __MKINT(ret);
 11362     }
 11362     }
 11363     RETURN (rslt);
 11363     RETURN (rslt);
 11364 
 11364 
 11365 bad: ;
 11365 bad: ;
 11366 %}.
 11366 %}.
 11383      With 0 as timeout argument, this can be used to check for availability
 11383      With 0 as timeout argument, this can be used to check for availability
 11384      of read-data.
 11384      of read-data.
 11385      Experimental."
 11385      Experimental."
 11386 
 11386 
 11387     ^ OperatingSystem selectOnAnyReadable:(Array with:fd)
 11387     ^ OperatingSystem selectOnAnyReadable:(Array with:fd)
 11388                       writable:(Array with:fd)
 11388 		      writable:(Array with:fd)
 11389                      exception:nil
 11389 		     exception:nil
 11390                    withTimeOut:millis
 11390 		   withTimeOut:millis
 11391 
 11391 
 11392     "Created: 1.10.1997 / 08:51:11 / stefan"
 11392     "Created: 1.10.1997 / 08:51:11 / stefan"
 11393 !
 11393 !
 11394 
 11394 
 11395 setBlocking:aBoolean
 11395 setBlocking:aBoolean
 11412 #   define DELAY_FLAG FNDELAY
 11412 #   define DELAY_FLAG FNDELAY
 11413 #  endif
 11413 #  endif
 11414 # endif
 11414 # endif
 11415 # if defined(DELAY_FLAG)
 11415 # if defined(DELAY_FLAG)
 11416     if (__isSmallInteger(__INST(fd))) {
 11416     if (__isSmallInteger(__INST(fd))) {
 11417         int f = __intVal(__INST(fd));
 11417 	int f = __intVal(__INST(fd));
 11418 
 11418 
 11419         flags = fcntl(f, F_GETFL, 0);
 11419 	flags = fcntl(f, F_GETFL, 0);
 11420         if (aBoolean == true) {
 11420 	if (aBoolean == true) {
 11421             ret = fcntl(f, F_SETFL, flags & ~DELAY_FLAG);
 11421 	    ret = fcntl(f, F_SETFL, flags & ~DELAY_FLAG);
 11422         } else {
 11422 	} else {
 11423             ret = fcntl(f, F_SETFL, flags | DELAY_FLAG);
 11423 	    ret = fcntl(f, F_SETFL, flags | DELAY_FLAG);
 11424         }
 11424 	}
 11425         if (ret >= 0) {
 11425 	if (ret >= 0) {
 11426             RETURN(__mkSmallInteger(flags));
 11426 	    RETURN(__mkSmallInteger(flags));
 11427         } else {
 11427 	} else {
 11428             err = __mkSmallInteger(errno);
 11428 	    err = __mkSmallInteger(errno);
 11429         }
 11429 	}
 11430     }
 11430     }
 11431 # undef DELAY_FLAG
 11431 # undef DELAY_FLAG
 11432 # endif /* DELAY_FLAG */
 11432 # endif /* DELAY_FLAG */
 11433 #endif
 11433 #endif
 11434 %}.
 11434 %}.
 11435     err notNil ifTrue:[
 11435     err notNil ifTrue:[
 11436         self error:err
 11436 	self error:err
 11437     ].
 11437     ].
 11438     "
 11438     "
 11439      fd argument not integer
 11439      fd argument not integer
 11440     "
 11440     "
 11441     ^ self primitiveFailed
 11441     ^ self primitiveFailed
 11450 
 11450 
 11451 %{
 11451 %{
 11452     OBJ handle = __externalAddressVal(self);
 11452     OBJ handle = __externalAddressVal(self);
 11453 
 11453 
 11454     if (__isSmallInteger(handle)) {
 11454     if (__isSmallInteger(handle)) {
 11455         RETURN (handle);
 11455 	RETURN (handle);
 11456     }
 11456     }
 11457 %}.
 11457 %}.
 11458     ^ nil
 11458     ^ nil
 11459 !
 11459 !
 11460 
 11460 
 11461 setFileDescriptor:anInteger
 11461 setFileDescriptor:anInteger
 11462 
 11462 
 11463 %{
 11463 %{
 11464     if (__isSmallInteger(anInteger)) {
 11464     if (__isSmallInteger(anInteger)) {
 11465         __externalAddressVal(self) = (OBJ)(__smallIntegerVal(anInteger));
 11465 	__externalAddressVal(self) = (OBJ)(__smallIntegerVal(anInteger));
 11466     }
 11466     }
 11467 %}
 11467 %}
 11468 
 11468 
 11469 
 11469 
 11470 ! !
 11470 ! !
 11478 
 11478 
 11479 %{
 11479 %{
 11480     int fd;
 11480     int fd;
 11481 
 11481 
 11482     if (__isSmallInteger(__INST(fd))) {
 11482     if (__isSmallInteger(__INST(fd))) {
 11483         fd = __smallIntegerVal(__INST(fd));
 11483 	fd = __smallIntegerVal(__INST(fd));
 11484 
 11484 
 11485         /*
 11485 	/*
 11486          * if available, try FIONREAD first, which is usually done faster.
 11486 	 * if available, try FIONREAD first, which is usually done faster.
 11487          */
 11487 	 */
 11488 # ifdef FIONREAD
 11488 # ifdef FIONREAD
 11489         {
 11489 	{
 11490             int result = 0;
 11490 	    int result = 0;
 11491 
 11491 
 11492             if (ioctl(fd, FIONREAD, &result) >= 0) {
 11492 	    if (ioctl(fd, FIONREAD, &result) >= 0) {
 11493                 RETURN(result > 0 ? true : false);
 11493 		RETURN(result > 0 ? true : false);
 11494             }
 11494 	    }
 11495         }
 11495 	}
 11496 # endif /* FIONREAD */
 11496 # endif /* FIONREAD */
 11497     }
 11497     }
 11498 %}.
 11498 %}.
 11499 
 11499 
 11500     OperatingSystem supportsSelect ifFalse:[
 11500     OperatingSystem supportsSelect ifFalse:[
 11501         "/ mhmh - what should we do then ?
 11501 	"/ mhmh - what should we do then ?
 11502         "/ For now, return true as if data was present,
 11502 	"/ For now, return true as if data was present,
 11503         "/ and let the thread fall into the read.
 11503 	"/ and let the thread fall into the read.
 11504         "/ It will then (hopefully) be desceduled there and
 11504 	"/ It will then (hopefully) be desceduled there and
 11505         "/ effectively polling for input.
 11505 	"/ effectively polling for input.
 11506 
 11506 
 11507         ^ true
 11507 	^ true
 11508     ].
 11508     ].
 11509 
 11509 
 11510     ^ (OperatingSystem selectOnAnyReadable:(Array with:fd)
 11510     ^ (OperatingSystem selectOnAnyReadable:(Array with:fd)
 11511                        writable:nil
 11511 		       writable:nil
 11512                        exception:nil
 11512 		       exception:nil
 11513                        withTimeOut:0) == fd
 11513 		       withTimeOut:0) == fd
 11514 
 11514 
 11515     "
 11515     "
 11516      |h n|
 11516      |h n|
 11517      h := OperatingSystem openFileForRead:'/etc/hosts'.
 11517      h := OperatingSystem openFileForRead:'/etc/hosts'.
 11518      n := h canReadWithoutBlocking.
 11518      n := h canReadWithoutBlocking.
 11531 
 11531 
 11532 canWriteWithoutBlocking
 11532 canWriteWithoutBlocking
 11533     "return true, if filedescriptor can be written without blocking"
 11533     "return true, if filedescriptor can be written without blocking"
 11534 
 11534 
 11535     OperatingSystem supportsSelect ifFalse:[
 11535     OperatingSystem supportsSelect ifFalse:[
 11536         "/ mhmh - what should we do then ?
 11536 	"/ mhmh - what should we do then ?
 11537         "/ For now, return true as if data was present,
 11537 	"/ For now, return true as if data was present,
 11538         "/ and let the thread fall into the write.
 11538 	"/ and let the thread fall into the write.
 11539         "/ It will then (hopefully) be desceduled there and
 11539 	"/ It will then (hopefully) be desceduled there and
 11540         "/ effectively polling for output.
 11540 	"/ effectively polling for output.
 11541         ^ true
 11541 	^ true
 11542     ].
 11542     ].
 11543 
 11543 
 11544     ^ (OperatingSystem selectOnAnyReadable:nil
 11544     ^ (OperatingSystem selectOnAnyReadable:nil
 11545                        writable:(Array with:fd)
 11545 		       writable:(Array with:fd)
 11546                        exception:nil
 11546 		       exception:nil
 11547                        withTimeOut:0) == fd
 11547 		       withTimeOut:0) == fd
 11548 !
 11548 !
 11549 
 11549 
 11550 isValid
 11550 isValid
 11551     "answer true, if the handle is valid, i.e. connected to
 11551     "answer true, if the handle is valid, i.e. connected to
 11552      a file or some other OS object"
 11552      a file or some other OS object"
 11561     /*
 11561     /*
 11562      * if available, try FIONREAD first, which is usually done faster.
 11562      * if available, try FIONREAD first, which is usually done faster.
 11563      */
 11563      */
 11564 # if defined(FIONREAD)
 11564 # if defined(FIONREAD)
 11565     {
 11565     {
 11566         int n = 0;
 11566 	int n = 0;
 11567 
 11567 
 11568         if (__isSmallInteger(__INST(fd))) {
 11568 	if (__isSmallInteger(__INST(fd))) {
 11569             if (ioctl(__smallIntegerVal(__INST(fd)), FIONREAD, &n) >= 0) {
 11569 	    if (ioctl(__smallIntegerVal(__INST(fd)), FIONREAD, &n) >= 0) {
 11570                 RETURN (__MKINT(n));
 11570 		RETURN (__MKINT(n));
 11571             }
 11571 	    }
 11572         }
 11572 	}
 11573     }
 11573     }
 11574 # endif /* FIONREAD */
 11574 # endif /* FIONREAD */
 11575 %}.
 11575 %}.
 11576     ^ self canReadWithoutBlocking ifTrue:[1] ifFalse:[0]
 11576     ^ self canReadWithoutBlocking ifTrue:[1] ifFalse:[0]
 11577 
 11577 
 11591 
 11591 
 11592     |sz old|
 11592     |sz old|
 11593 
 11593 
 11594     sz := OpenFiles size.
 11594     sz := OpenFiles size.
 11595     fd > sz ifTrue:[
 11595     fd > sz ifTrue:[
 11596         "grow for more descriptors"
 11596 	"grow for more descriptors"
 11597         old := OpenFiles.
 11597 	old := OpenFiles.
 11598 
 11598 
 11599         "JV@2013-03-15: It may happen that OS returns a filedescriptor whose value
 11599 	"JV@2013-03-15: It may happen that OS returns a filedescriptor whose value
 11600          is larger than twice the lenght of the weakarray. Care for this.
 11600 	 is larger than twice the lenght of the weakarray. Care for this.
 11601          Spotted by Martin Kobetic."
 11601 	 Spotted by Martin Kobetic."
 11602         OpenFiles := WeakArray new:((sz * 2) max:fd).
 11602 	OpenFiles := WeakArray new:((sz * 2) max:fd).
 11603         old removeDependent:(self class).
 11603 	old removeDependent:(self class).
 11604         OpenFiles addDependent:(self class).
 11604 	OpenFiles addDependent:(self class).
 11605         old keysAndValuesDo:[:index :elem|
 11605 	old keysAndValuesDo:[:index :elem|
 11606             "be careful to not overwrite new entries in OpenFiles"
 11606 	    "be careful to not overwrite new entries in OpenFiles"
 11607             elem notNil ifTrue:[
 11607 	    elem notNil ifTrue:[
 11608                 OpenFiles at:index put:elem.
 11608 		OpenFiles at:index put:elem.
 11609             ].
 11609 	    ].
 11610         ].
 11610 	].
 11611     ].
 11611     ].
 11612     OpenFiles at:fd put:self.
 11612     OpenFiles at:fd put:self.
 11613 
 11613 
 11614     "Created: 30.9.1997 / 12:51:48 / stefan"
 11614     "Created: 30.9.1997 / 12:51:48 / stefan"
 11615     "Modified: 30.9.1997 / 12:58:37 / stefan"
 11615     "Modified: 30.9.1997 / 12:58:37 / stefan"
 11639 
 11639 
 11640     |inputSema hasData wasBlocked|
 11640     |inputSema hasData wasBlocked|
 11641 
 11641 
 11642     fd isNil ifTrue:[^ self error:#errorNotOpen].
 11642     fd isNil ifTrue:[^ self error:#errorNotOpen].
 11643     self canReadWithoutBlocking ifTrue:[
 11643     self canReadWithoutBlocking ifTrue:[
 11644         ^ false.
 11644 	^ false.
 11645     ].
 11645     ].
 11646 
 11646 
 11647     wasBlocked := OperatingSystem blockInterrupts.
 11647     wasBlocked := OperatingSystem blockInterrupts.
 11648     inputSema := Semaphore new name:'readWait'.
 11648     inputSema := Semaphore new name:'readWait'.
 11649     [
 11649     [
 11650         timeout notNil ifTrue:[
 11650 	timeout notNil ifTrue:[
 11651             Processor signal:inputSema afterMilliseconds:timeout
 11651 	    Processor signal:inputSema afterMilliseconds:timeout
 11652         ].
 11652 	].
 11653         Processor signal:inputSema onInput:fd.
 11653 	Processor signal:inputSema onInput:fd.
 11654         Processor activeProcess state:#ioWait.
 11654 	Processor activeProcess state:#ioWait.
 11655         inputSema wait.
 11655 	inputSema wait.
 11656         hasData := self canReadWithoutBlocking.
 11656 	hasData := self canReadWithoutBlocking.
 11657     ] ifCurtailed:[
 11657     ] ifCurtailed:[
 11658         Processor disableSemaphore:inputSema.
 11658 	Processor disableSemaphore:inputSema.
 11659         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11659 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11660     ].
 11660     ].
 11661     timeout notNil ifTrue:[
 11661     timeout notNil ifTrue:[
 11662         Processor disableSemaphore:inputSema.
 11662 	Processor disableSemaphore:inputSema.
 11663     ].
 11663     ].
 11664     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11664     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11665     ^ hasData not
 11665     ^ hasData not
 11666 !
 11666 !
 11667 
 11667 
 11674 
 11674 
 11675     |outputSema canWrite wasBlocked|
 11675     |outputSema canWrite wasBlocked|
 11676 
 11676 
 11677     fd isNil ifTrue:[^ self error:#errorNotOpen].
 11677     fd isNil ifTrue:[^ self error:#errorNotOpen].
 11678     self canWriteWithoutBlocking ifTrue:[
 11678     self canWriteWithoutBlocking ifTrue:[
 11679         ^ false.
 11679 	^ false.
 11680     ].
 11680     ].
 11681 
 11681 
 11682     wasBlocked := OperatingSystem blockInterrupts.
 11682     wasBlocked := OperatingSystem blockInterrupts.
 11683     outputSema := Semaphore new name:'writeWait'.
 11683     outputSema := Semaphore new name:'writeWait'.
 11684     [
 11684     [
 11685         timeout notNil ifTrue:[
 11685 	timeout notNil ifTrue:[
 11686             Processor signal:outputSema afterMilliseconds:timeout
 11686 	    Processor signal:outputSema afterMilliseconds:timeout
 11687         ].
 11687 	].
 11688         Processor signal:outputSema onOutput:fd.
 11688 	Processor signal:outputSema onOutput:fd.
 11689         Processor activeProcess state:#ioWait.
 11689 	Processor activeProcess state:#ioWait.
 11690         outputSema wait.
 11690 	outputSema wait.
 11691         canWrite := self canWriteWithoutBlocking.
 11691 	canWrite := self canWriteWithoutBlocking.
 11692     ] ifCurtailed:[
 11692     ] ifCurtailed:[
 11693         Processor disableSemaphore:outputSema.
 11693 	Processor disableSemaphore:outputSema.
 11694         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11694 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11695     ].
 11695     ].
 11696     timeout notNil ifTrue:[
 11696     timeout notNil ifTrue:[
 11697         Processor disableSemaphore:outputSema.
 11697 	Processor disableSemaphore:outputSema.
 11698     ].
 11698     ].
 11699     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11699     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
 11700     ^ canWrite not
 11700     ^ canWrite not
 11701 ! !
 11701 ! !
 11702 
 11702 
 11707 
 11707 
 11708 %{
 11708 %{
 11709     FILE *f = (FILE *)(__externalAddressVal(self));
 11709     FILE *f = (FILE *)(__externalAddressVal(self));
 11710 
 11710 
 11711     if (f) {
 11711     if (f) {
 11712         __externalAddressVal(self) = NULL;
 11712 	__externalAddressVal(self) = NULL;
 11713         fclose(f);
 11713 	fclose(f);
 11714     }
 11714     }
 11715 %}
 11715 %}
 11716 
 11716 
 11717 ! !
 11717 ! !
 11718 
 11718 
 11719 !UnixOperatingSystem::FileStatusInfo class methodsFor:'instance creation'!
 11719 !UnixOperatingSystem::FileStatusInfo class methodsFor:'instance creation'!
 11720 
 11720 
 11721 type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT path:lP numLinks:nL
 11721 type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT path:lP numLinks:nL
 11722     ^ self basicNew
 11722     ^ self basicNew
 11723         type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT path:lP numLinks:nL
 11723 	type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT path:lP numLinks:nL
 11724 !
 11724 !
 11725 
 11725 
 11726 type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT sourcePath:sP targetPath:tP numLinks:nL
 11726 type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT sourcePath:sP targetPath:tP numLinks:nL
 11727     ^ self basicNew
 11727     ^ self basicNew
 11728         type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT sourcePath:sP targetPath:tP numLinks:nL
 11728 	type:t mode:m uid:u gid:g size:s id:i accessed:aT modified:mT statusChanged:sT sourcePath:sP targetPath:tP numLinks:nL
 11729 ! !
 11729 ! !
 11730 
 11730 
 11731 !UnixOperatingSystem::FileStatusInfo methodsFor:'accessing'!
 11731 !UnixOperatingSystem::FileStatusInfo methodsFor:'accessing'!
 11732 
 11732 
 11733 accessTime
 11733 accessTime
 11734     "return accessed"
 11734     "return accessed"
 11735 
 11735 
 11736     accessed isInteger ifTrue:[
 11736     accessed isInteger ifTrue:[
 11737         "/ lazy time conversion
 11737 	"/ lazy time conversion
 11738         accessed := Timestamp fromOSTime:(accessed * 1000).
 11738 	accessed := Timestamp fromOSTime:(accessed * 1000).
 11739     ].
 11739     ].
 11740     ^ accessed
 11740     ^ accessed
 11741 !
 11741 !
 11742 
 11742 
 11743 alternativeName
 11743 alternativeName
 11783 
 11783 
 11784 modificationTime
 11784 modificationTime
 11785     "return modified"
 11785     "return modified"
 11786 
 11786 
 11787     modified isInteger ifTrue:[
 11787     modified isInteger ifTrue:[
 11788         "/ lazy time conversion
 11788 	"/ lazy time conversion
 11789         modified := Timestamp fromOSTime:(modified * 1000).
 11789 	modified := Timestamp fromOSTime:(modified * 1000).
 11790     ].
 11790     ].
 11791     ^ modified
 11791     ^ modified
 11792 !
 11792 !
 11793 
 11793 
 11794 numLinks
 11794 numLinks
 11807     ^ sourcePath
 11807     ^ sourcePath
 11808 !
 11808 !
 11809 
 11809 
 11810 statusChangeTime
 11810 statusChangeTime
 11811     statusChanged isInteger ifTrue:[
 11811     statusChanged isInteger ifTrue:[
 11812         "/ lazy time conversion
 11812 	"/ lazy time conversion
 11813         statusChanged := Timestamp fromOSTime:(statusChanged * 1000).
 11813 	statusChanged := Timestamp fromOSTime:(statusChanged * 1000).
 11814     ].
 11814     ].
 11815     ^ statusChanged
 11815     ^ statusChanged
 11816 !
 11816 !
 11817 
 11817 
 11818 targetPath
 11818 targetPath
 12031     ^ type == #socket
 12031     ^ type == #socket
 12032 !
 12032 !
 12033 
 12033 
 12034 isSpecialFile
 12034 isSpecialFile
 12035     ^ (type ~~ #directory
 12035     ^ (type ~~ #directory
 12036         and:[type ~~ #remoteDirectory
 12036 	and:[type ~~ #remoteDirectory
 12037         and:[type ~~ #regular
 12037 	and:[type ~~ #regular
 12038         and:[type ~~ #symbolicLink
 12038 	and:[type ~~ #symbolicLink
 12039     ]]])
 12039     ]]])
 12040 !
 12040 !
 12041 
 12041 
 12042 isSymbolicLink
 12042 isSymbolicLink
 12043     ^ type == #symbolicLink
 12043     ^ type == #symbolicLink
 12076 
 12076 
 12077 !UnixOperatingSystem::MountInfo methodsFor:'printing'!
 12077 !UnixOperatingSystem::MountInfo methodsFor:'printing'!
 12078 
 12078 
 12079 printOn:aStream
 12079 printOn:aStream
 12080     aStream
 12080     aStream
 12081         nextPutAll:'MountInfo for ';
 12081 	nextPutAll:'MountInfo for ';
 12082         nextPutAll:mountPointPath.
 12082 	nextPutAll:mountPointPath.
 12083 ! !
 12083 ! !
 12084 
 12084 
 12085 !UnixOperatingSystem::MountInfo methodsFor:'queries'!
 12085 !UnixOperatingSystem::MountInfo methodsFor:'queries'!
 12086 
 12086 
 12087 isRemote
 12087 isRemote
 12095     This is an auxillary class, that holds information about status changes of
 12095     This is an auxillary class, that holds information about status changes of
 12096     operating system processes (these are no smalltalk processes!!).
 12096     operating system processes (these are no smalltalk processes!!).
 12097 
 12097 
 12098     [Instance variables:]
 12098     [Instance variables:]
 12099 
 12099 
 12100         pid     <Integer>       OS-Process identifier
 12100 	pid     <Integer>       OS-Process identifier
 12101 
 12101 
 12102         status  <Symbol>        either #exit #signal #stop #continue
 12102 	status  <Symbol>        either #exit #signal #stop #continue
 12103 
 12103 
 12104         code    <Integer>       either exitcode or signalnumber
 12104 	code    <Integer>       either exitcode or signalnumber
 12105 
 12105 
 12106         core    <Boolean>       true if core has been dumped
 12106 	core    <Boolean>       true if core has been dumped
 12107 
 12107 
 12108 
 12108 
 12109     [author:]
 12109     [author:]
 12110         Stefan Vogel
 12110 	Stefan Vogel
 12111 
 12111 
 12112     [see also:]
 12112     [see also:]
 12113         OperatingSystem
 12113 	OperatingSystem
 12114 "
 12114 "
 12115 ! !
 12115 ! !
 12116 
 12116 
 12117 !UnixOperatingSystem::OSProcessStatus class methodsFor:'instance creation'!
 12117 !UnixOperatingSystem::OSProcessStatus class methodsFor:'instance creation'!
 12118 
 12118 
 12270 
 12270 
 12271     |protocolCode protocolSymbol|
 12271     |protocolCode protocolSymbol|
 12272 
 12272 
 12273 %{
 12273 %{
 12274     if (__isSmallInteger(aNameOrNumber) || aNameOrNumber == nil) {
 12274     if (__isSmallInteger(aNameOrNumber) || aNameOrNumber == nil) {
 12275         RETURN(aNameOrNumber);
 12275 	RETURN(aNameOrNumber);
 12276     }
 12276     }
 12277 %}.
 12277 %}.
 12278 
 12278 
 12279     ProtocolCache notNil ifTrue:[
 12279     ProtocolCache notNil ifTrue:[
 12280         protocolCode := ProtocolCache at:(aNameOrNumber asSymbol) ifAbsent:[].
 12280 	protocolCode := ProtocolCache at:(aNameOrNumber asSymbol) ifAbsent:[].
 12281         protocolCode notNil ifTrue:[
 12281 	protocolCode notNil ifTrue:[
 12282             ^ protocolCode.
 12282 	    ^ protocolCode.
 12283         ].
 12283 	].
 12284     ].
 12284     ].
 12285 
 12285 
 12286 %{
 12286 %{
 12287 #ifndef NO_SOCKET
 12287 #ifndef NO_SOCKET
 12288     struct protoent *protoent = 0;
 12288     struct protoent *protoent = 0;
 12289 
 12289 
 12290     if (__isStringLike(aNameOrNumber)) {
 12290     if (__isStringLike(aNameOrNumber)) {
 12291         protoent = getprotobyname((char *) __stringVal(aNameOrNumber));
 12291 	protoent = getprotobyname((char *) __stringVal(aNameOrNumber));
 12292         if (protoent) {
 12292 	if (protoent) {
 12293             protocolCode = __mkSmallInteger(protoent->p_proto);
 12293 	    protocolCode = __mkSmallInteger(protoent->p_proto);
 12294             protocolSymbol = __MKSYMBOL(protoent->p_name, 0);
 12294 	    protocolSymbol = __MKSYMBOL(protoent->p_name, 0);
 12295         }
 12295 	}
 12296     }
 12296     }
 12297 #endif /*NO_SOCKET*/
 12297 #endif /*NO_SOCKET*/
 12298 %}.
 12298 %}.
 12299 
 12299 
 12300     protocolSymbol notNil ifTrue:[
 12300     protocolSymbol notNil ifTrue:[
 12301         ProtocolCache isNil ifTrue:[
 12301 	ProtocolCache isNil ifTrue:[
 12302             ProtocolCache := IdentityDictionary new.
 12302 	    ProtocolCache := IdentityDictionary new.
 12303         ].
 12303 	].
 12304         "beware of polluting the protocol cache with aliases"
 12304 	"beware of polluting the protocol cache with aliases"
 12305         ProtocolCache at:protocolSymbol put:protocolCode.
 12305 	ProtocolCache at:protocolSymbol put:protocolCode.
 12306     ].
 12306     ].
 12307     ^ protocolCode
 12307     ^ protocolCode
 12308 
 12308 
 12309     "
 12309     "
 12310      self protocolCodeOf:#tcp
 12310      self protocolCodeOf:#tcp
 12317     "convert a numeric protocol code to a symbol"
 12317     "convert a numeric protocol code to a symbol"
 12318 
 12318 
 12319     |protocolSymbol|
 12319     |protocolSymbol|
 12320 
 12320 
 12321     ProtocolCache notNil ifTrue:[
 12321     ProtocolCache notNil ifTrue:[
 12322         protocolSymbol := ProtocolCache keyAtIdentityValue:anInteger ifAbsent:[].
 12322 	protocolSymbol := ProtocolCache keyAtIdentityValue:anInteger ifAbsent:[].
 12323         protocolSymbol notNil ifTrue:[
 12323 	protocolSymbol notNil ifTrue:[
 12324             ^ protocolSymbol.
 12324 	    ^ protocolSymbol.
 12325         ].
 12325 	].
 12326     ].
 12326     ].
 12327 
 12327 
 12328 %{
 12328 %{
 12329 #ifndef NO_SOCKET
 12329 #ifndef NO_SOCKET
 12330     struct protoent *protoent = 0;
 12330     struct protoent *protoent = 0;
 12331 
 12331 
 12332     if (__isSmallInteger(anInteger)) {
 12332     if (__isSmallInteger(anInteger)) {
 12333         protoent = getprotobynumber(__intVal(anInteger));
 12333 	protoent = getprotobynumber(__intVal(anInteger));
 12334         if (protoent) {
 12334 	if (protoent) {
 12335             protocolSymbol = __MKSYMBOL(protoent->p_name, 0);
 12335 	    protocolSymbol = __MKSYMBOL(protoent->p_name, 0);
 12336         }
 12336 	}
 12337     }
 12337     }
 12338 #endif /*NO_SOCKET*/
 12338 #endif /*NO_SOCKET*/
 12339 %}.
 12339 %}.
 12340 
 12340 
 12341     protocolSymbol notNil ifTrue:[
 12341     protocolSymbol notNil ifTrue:[
 12342         ProtocolCache isNil ifTrue:[
 12342 	ProtocolCache isNil ifTrue:[
 12343             ProtocolCache := IdentityDictionary new.
 12343 	    ProtocolCache := IdentityDictionary new.
 12344         ].
 12344 	].
 12345         ProtocolCache at:protocolSymbol put:anInteger.
 12345 	ProtocolCache at:protocolSymbol put:anInteger.
 12346     ].
 12346     ].
 12347     ^ protocolSymbol
 12347     ^ protocolSymbol
 12348 
 12348 
 12349 
 12349 
 12350     "
 12350     "
 12373 
 12373 
 12374     domain := OperatingSystem domainCodeOf:domainArg.
 12374     domain := OperatingSystem domainCodeOf:domainArg.
 12375     type := OperatingSystem socketTypeCodeOf:typeArg.
 12375     type := OperatingSystem socketTypeCodeOf:typeArg.
 12376     proto := self protocolCodeOf:protoArg.
 12376     proto := self protocolCodeOf:protoArg.
 12377     serviceNameArg notNil ifTrue:[
 12377     serviceNameArg notNil ifTrue:[
 12378         serviceName := serviceNameArg printString.      "convert integer port numbers"
 12378 	serviceName := serviceNameArg printString.      "convert integer port numbers"
 12379     ].
 12379     ].
 12380 
 12380 
 12381     hostName isNil ifTrue:[
 12381     hostName isNil ifTrue:[
 12382         encodedHostName := nil.
 12382 	encodedHostName := nil.
 12383     ] ifFalse:[
 12383     ] ifFalse:[
 12384         encodedHostName := hostName utf8Encoded.
 12384 	encodedHostName := hostName utf8Encoded.
 12385     ].
 12385     ].
 12386     (encodedHostName ~~ hostName and:[OperatingSystem getCodeset ~~ #utf8]) ifTrue:[
 12386     (encodedHostName ~~ hostName and:[OperatingSystem getCodeset ~~ #utf8]) ifTrue:[
 12387         "hostName is not plain ASCII - so this is an IDN domain name. Have to ensure, that the locale is UTF-8.
 12387 	"hostName is not plain ASCII - so this is an IDN domain name. Have to ensure, that the locale is UTF-8.
 12388          Block interrupt to not affect other ST/X processes while the locale is changed."
 12388 	 Block interrupt to not affect other ST/X processes while the locale is changed."
 12389         |interruptsBlocked oldLocale|
 12389 	|interruptsBlocked oldLocale|
 12390 
 12390 
 12391         interruptsBlocked := OperatingSystem blockInterrupts.
 12391 	interruptsBlocked := OperatingSystem blockInterrupts.
 12392         oldLocale := OperatingSystem setLocale:#'LC_CTYPE' to:nil.
 12392 	oldLocale := OperatingSystem setLocale:#'LC_CTYPE' to:nil.
 12393         OperatingSystem setLocale:#'LC_CTYPE' to:'en_US.UTF-8'.
 12393 	OperatingSystem setLocale:#'LC_CTYPE' to:'en_US.UTF-8'.
 12394         result := self primGetAddressInfo:encodedHostName serviceName:serviceName domainCode:domain socketTypeCode:type protocolCode:proto flags:flags.
 12394 	result := self primGetAddressInfo:encodedHostName serviceName:serviceName domainCode:domain socketTypeCode:type protocolCode:proto flags:flags.
 12395         OperatingSystem setLocale:#'LC_CTYPE' to:oldLocale.
 12395 	OperatingSystem setLocale:#'LC_CTYPE' to:oldLocale.
 12396         interruptsBlocked ifFalse:[
 12396 	interruptsBlocked ifFalse:[
 12397             OperatingSystem unblockInterrupts.
 12397 	    OperatingSystem unblockInterrupts.
 12398         ].
 12398 	].
 12399     ] ifFalse:[
 12399     ] ifFalse:[
 12400         result := self primGetAddressInfo:encodedHostName serviceName:serviceName domainCode:domain socketTypeCode:type protocolCode:proto flags:flags.
 12400 	result := self primGetAddressInfo:encodedHostName serviceName:serviceName domainCode:domain socketTypeCode:type protocolCode:proto flags:flags.
 12401     ].
 12401     ].
 12402     result isArray ifFalse:[
 12402     result isArray ifFalse:[
 12403         |request|
 12403 	|request|
 12404         request := SocketAddressInfo new
 12404 	request := SocketAddressInfo new
 12405             domain:domainArg;
 12405 	    domain:domainArg;
 12406             type:typeArg;
 12406 	    type:typeArg;
 12407             protocol:protoArg;
 12407 	    protocol:protoArg;
 12408             canonicalName:hostName;
 12408 	    canonicalName:hostName;
 12409             serviceName:serviceName.
 12409 	    serviceName:serviceName.
 12410         ^ (HostNameLookupError new
 12410 	^ (HostNameLookupError new
 12411                 parameter:result;
 12411 		parameter:result;
 12412                 messageText:' - ', (result printString);
 12412 		messageText:' - ', (result printString);
 12413                 request:request) raiseRequest.
 12413 		request:request) raiseRequest.
 12414     ].
 12414     ].
 12415     1 to:result size do:[:i |
 12415     1 to:result size do:[:i |
 12416         |entry dom info|
 12416 	|entry dom info|
 12417 
 12417 
 12418         entry := result at:i.
 12418 	entry := result at:i.
 12419 
 12419 
 12420         info := SocketAddressInfo new.
 12420 	info := SocketAddressInfo new.
 12421         info
 12421 	info
 12422             flags:(entry at:1);
 12422 	    flags:(entry at:1);
 12423             domain:(dom := OperatingSystem domainSymbolOf:(entry at:2));
 12423 	    domain:(dom := OperatingSystem domainSymbolOf:(entry at:2));
 12424             type:(OperatingSystem socketTypeSymbolOf:(entry at:3));
 12424 	    type:(OperatingSystem socketTypeSymbolOf:(entry at:3));
 12425             protocol:(self protocolSymbolOf:(entry at:4));
 12425 	    protocol:(self protocolSymbolOf:(entry at:4));
 12426             socketAddress:((SocketAddress newDomain:dom) fromBytes:(entry at:5));
 12426 	    socketAddress:((SocketAddress newDomain:dom) fromBytes:(entry at:5));
 12427             canonicalName:(entry at:6).
 12427 	    canonicalName:(entry at:6).
 12428 
 12428 
 12429         result at:i put:info.
 12429 	result at:i put:info.
 12430     ].
 12430     ].
 12431     ^ result
 12431     ^ result
 12432 
 12432 
 12433     "
 12433     "
 12434      self getAddressInfo:'localhost' serviceName:nil
 12434      self getAddressInfo:'localhost' serviceName:nil
 12435             domain:nil type:nil protocol:nil flags:nil
 12435 	    domain:nil type:nil protocol:nil flags:nil
 12436      self getAddressInfo:'localhost' serviceName:nil
 12436      self getAddressInfo:'localhost' serviceName:nil
 12437             domain:#inet type:#stream protocol:nil flags:nil
 12437 	    domain:#inet type:#stream protocol:nil flags:nil
 12438      self getAddressInfo:'localhost' serviceName:nil
 12438      self getAddressInfo:'localhost' serviceName:nil
 12439             domain:#inet type:#stream protocol:#tcp flags:nil
 12439 	    domain:#inet type:#stream protocol:#tcp flags:nil
 12440      self getAddressInfo:'blurb.exept.de' serviceName:nil
 12440      self getAddressInfo:'blurb.exept.de' serviceName:nil
 12441             domain:#inet type:nil protocol:nil flags:nil
 12441 	    domain:#inet type:nil protocol:nil flags:nil
 12442      self getAddressInfo:'1.2.3.4' serviceName:'bla'
 12442      self getAddressInfo:'1.2.3.4' serviceName:'bla'
 12443             domain:#inet type:nil protocol:nil flags:nil
 12443 	    domain:#inet type:nil protocol:nil flags:nil
 12444      self getAddressInfo:'localhost' serviceName:'echo'
 12444      self getAddressInfo:'localhost' serviceName:'echo'
 12445             domain:#inet type:nil protocol:nil flags:nil
 12445 	    domain:#inet type:nil protocol:nil flags:nil
 12446      self getAddressInfo:nil serviceName:'echo'
 12446      self getAddressInfo:nil serviceName:'echo'
 12447             domain:#inet type:nil protocol:nil flags:nil
 12447 	    domain:#inet type:nil protocol:nil flags:nil
 12448      self getAddressInfo:nil serviceName:nil
 12448      self getAddressInfo:nil serviceName:nil
 12449             domain:#inet type:nil protocol:nil flags:nil
 12449 	    domain:#inet type:nil protocol:nil flags:nil
 12450      self getAddressInfo:'www.google.de' serviceName:nil
 12450      self getAddressInfo:'www.google.de' serviceName:nil
 12451             domain:nil type:nil protocol:nil flags:nil
 12451 	    domain:nil type:nil protocol:nil flags:nil
 12452      self getAddressInfo:'www.exept.de' serviceName:nil
 12452      self getAddressInfo:'www.exept.de' serviceName:nil
 12453             domain:nil type:nil protocol:nil flags:nil
 12453 	    domain:nil type:nil protocol:nil flags:nil
 12454      self getAddressInfo:'www.exept.de' serviceName:nil
 12454      self getAddressInfo:'www.exept.de' serviceName:nil
 12455             domain:#'AF_INET' type:nil protocol:nil flags:nil
 12455 	    domain:#'AF_INET' type:nil protocol:nil flags:nil
 12456      self getAddressInfo:'www.exept.de' serviceName:nil
 12456      self getAddressInfo:'www.exept.de' serviceName:nil
 12457             domain:#'AF_INET6' type:nil protocol:nil flags:nil
 12457 	    domain:#'AF_INET6' type:nil protocol:nil flags:nil
 12458      self getAddressInfo:'www.baden-württemberg.de' serviceName:nil
 12458      self getAddressInfo:'www.baden-württemberg.de' serviceName:nil
 12459             domain:#'AF_INET' type:#stream protocol:nil flags:nil
 12459 	    domain:#'AF_INET' type:#stream protocol:nil flags:nil
 12460     "
 12460     "
 12461 !
 12461 !
 12462 
 12462 
 12463 getNameInfo:socketAddress wantHostName:wantHostName wantServiceName:wantServiceName datagram:useDatagram flags:flags
 12463 getNameInfo:socketAddress wantHostName:wantHostName wantServiceName:wantServiceName datagram:useDatagram flags:flags
 12464     "answer an Array containing the hostName and serviceName
 12464     "answer an Array containing the hostName and serviceName
 12486     int ret, __flags;
 12486     int ret, __flags;
 12487     char *bp;
 12487     char *bp;
 12488     int nInstBytes, sockAddrSize;
 12488     int nInstBytes, sockAddrSize;
 12489 
 12489 
 12490     if (wantHostName == true) {
 12490     if (wantHostName == true) {
 12491         hp = host;
 12491 	hp = host;
 12492         hsz = sizeof(host);
 12492 	hsz = sizeof(host);
 12493     }
 12493     }
 12494     if (wantServiceName == true) {
 12494     if (wantServiceName == true) {
 12495         sp = service;
 12495 	sp = service;
 12496         ssz = sizeof(service);
 12496 	ssz = sizeof(service);
 12497     }
 12497     }
 12498     if (hp == 0 && sp == 0) {
 12498     if (hp == 0 && sp == 0) {
 12499         error = @symbol(badArgument);
 12499 	error = @symbol(badArgument);
 12500         goto err;
 12500 	goto err;
 12501     }
 12501     }
 12502     if (!__isBytes(socketAddress)) {
 12502     if (!__isBytes(socketAddress)) {
 12503         error = @symbol(badArgument1);
 12503 	error = @symbol(badArgument1);
 12504         goto err;
 12504 	goto err;
 12505     }
 12505     }
 12506 
 12506 
 12507     nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_ninstvars));
 12507     nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_ninstvars));
 12508     sockAddrSize = __byteArraySize(socketAddress);
 12508     sockAddrSize = __byteArraySize(socketAddress);
 12509     sockAddrSize -= nInstBytes;
 12509     sockAddrSize -= nInstBytes;
 12510 
 12510 
 12511     if (!__isSmallInteger(flags)) {
 12511     if (!__isSmallInteger(flags)) {
 12512         error = @symbol(badArgument5);
 12512 	error = @symbol(badArgument5);
 12513         goto err;
 12513 	goto err;
 12514     }
 12514     }
 12515     __flags = __intVal(flags);
 12515     __flags = __intVal(flags);
 12516 
 12516 
 12517 #if defined(NI_NUMERICHOST)
 12517 #if defined(NI_NUMERICHOST)
 12518     if (useDatagram == true) {
 12518     if (useDatagram == true) {
 12519         __flags |= NI_DGRAM;
 12519 	__flags |= NI_DGRAM;
 12520     }
 12520     }
 12521 
 12521 
 12522     {
 12522     {
 12523         bp = (char *)(__byteArrayVal(socketAddress));
 12523 	bp = (char *)(__byteArrayVal(socketAddress));
 12524         bp += nInstBytes;
 12524 	bp += nInstBytes;
 12525         __BEGIN_INTERRUPTABLE__
 12525 	__BEGIN_INTERRUPTABLE__
 12526         ret = getnameinfo((struct sockaddr *)bp, sockAddrSize,
 12526 	ret = getnameinfo((struct sockaddr *)bp, sockAddrSize,
 12527                           hp, hsz, sp, ssz, __flags);
 12527 			  hp, hsz, sp, ssz, __flags);
 12528         __END_INTERRUPTABLE__
 12528 	__END_INTERRUPTABLE__
 12529     } while (ret == EAI_SYSTEM && errno == EINTR);
 12529     } while (ret == EAI_SYSTEM && errno == EINTR);
 12530     if (ret != 0) {
 12530     if (ret != 0) {
 12531         switch (ret) {
 12531 	switch (ret) {
 12532         case EAI_FAMILY:
 12532 	case EAI_FAMILY:
 12533             error = @symbol(badProtocol);
 12533 	    error = @symbol(badProtocol);
 12534             break;
 12534 	    break;
 12535         case EAI_SOCKTYPE:
 12535 	case EAI_SOCKTYPE:
 12536             error = @symbol(badSocketType);
 12536 	    error = @symbol(badSocketType);
 12537             break;
 12537 	    break;
 12538         case EAI_BADFLAGS:
 12538 	case EAI_BADFLAGS:
 12539             error = @symbol(badFlags);
 12539 	    error = @symbol(badFlags);
 12540             break;
 12540 	    break;
 12541         case EAI_NONAME:
 12541 	case EAI_NONAME:
 12542             error = @symbol(unknownHost);
 12542 	    error = @symbol(unknownHost);
 12543             break;
 12543 	    break;
 12544         case EAI_SERVICE:
 12544 	case EAI_SERVICE:
 12545             error = @symbol(unknownService);
 12545 	    error = @symbol(unknownService);
 12546             break;
 12546 	    break;
 12547 #ifdef EAI_ADDRFAMILY
 12547 #ifdef EAI_ADDRFAMILY
 12548         case EAI_ADDRFAMILY :
 12548 	case EAI_ADDRFAMILY :
 12549             error = @symbol(unknownHostForProtocol);
 12549 	    error = @symbol(unknownHostForProtocol);
 12550             break;
 12550 	    break;
 12551 #endif
 12551 #endif
 12552 #ifdef EAI_NODATA
 12552 #ifdef EAI_NODATA
 12553         case EAI_NODATA:
 12553 	case EAI_NODATA:
 12554             error = @symbol(noAddress);
 12554 	    error = @symbol(noAddress);
 12555             break;
 12555 	    break;
 12556 #endif
 12556 #endif
 12557         case EAI_MEMORY:
 12557 	case EAI_MEMORY:
 12558             error = @symbol(allocationFailure);
 12558 	    error = @symbol(allocationFailure);
 12559             break;
 12559 	    break;
 12560         case EAI_FAIL:
 12560 	case EAI_FAIL:
 12561             error = @symbol(permanentFailure);
 12561 	    error = @symbol(permanentFailure);
 12562             break;
 12562 	    break;
 12563         case EAI_AGAIN:
 12563 	case EAI_AGAIN:
 12564             error = @symbol(tryAgain);
 12564 	    error = @symbol(tryAgain);
 12565             break;
 12565 	    break;
 12566         case EAI_SYSTEM:
 12566 	case EAI_SYSTEM:
 12567             error = @symbol(systemError);
 12567 	    error = @symbol(systemError);
 12568             break;
 12568 	    break;
 12569         default:
 12569 	default:
 12570             error = @symbol(unknownError);
 12570 	    error = @symbol(unknownError);
 12571         }
 12571 	}
 12572         errorString = __MKSTRING(gai_strerror(ret));
 12572 	errorString = __MKSTRING(gai_strerror(ret));
 12573         goto err;
 12573 	goto err;
 12574     }
 12574     }
 12575 # else /* ! NI_NUMERICHOST */
 12575 # else /* ! NI_NUMERICHOST */
 12576     {
 12576     {
 12577         /*
 12577 	/*
 12578          * Do it using gethostbyaddr()
 12578 	 * Do it using gethostbyaddr()
 12579          */
 12579 	 */
 12580         struct sockaddr_in *sa;
 12580 	struct sockaddr_in *sa;
 12581 
 12581 
 12582         if (sockAddrSize < sizeof(*sa)) {
 12582 	if (sockAddrSize < sizeof(*sa)) {
 12583             error = @symbol(badArgument1);
 12583 	    error = @symbol(badArgument1);
 12584             goto err;
 12584 	    goto err;
 12585         }
 12585 	}
 12586         bp = (char *)(__byteArrayVal(socketAddress));
 12586 	bp = (char *)(__byteArrayVal(socketAddress));
 12587         bp += nInstBytes;
 12587 	bp += nInstBytes;
 12588         sa = (struct sockaddr_in *)bp;
 12588 	sa = (struct sockaddr_in *)bp;
 12589 
 12589 
 12590         if (sp) {
 12590 	if (sp) {
 12591             struct servent *servp;
 12591 	    struct servent *servp;
 12592             char *__proto = 0;
 12592 	    char *__proto = 0;
 12593 
 12593 
 12594             __proto = (useDatagram == true ? "udp" : "tcp");
 12594 	    __proto = (useDatagram == true ? "udp" : "tcp");
 12595 
 12595 
 12596             servp = getservbyport(sa->sin_port, __proto);
 12596 	    servp = getservbyport(sa->sin_port, __proto);
 12597             if (servp) {
 12597 	    if (servp) {
 12598                 sp = servp->s_name;
 12598 		sp = servp->s_name;
 12599             }
 12599 	    }
 12600         }
 12600 	}
 12601         if (hp) {
 12601 	if (hp) {
 12602             struct hostent *hostp;
 12602 	    struct hostent *hostp;
 12603 #  ifdef USE_H_ERRNO
 12603 #  ifdef USE_H_ERRNO
 12604             do {
 12604 	    do {
 12605                 bp = (char *)(__byteArrayVal(socketAddress));
 12605 		bp = (char *)(__byteArrayVal(socketAddress));
 12606                 bp += nInstBytes;
 12606 		bp += nInstBytes;
 12607                 sa = (struct sockaddr_in *)bp;
 12607 		sa = (struct sockaddr_in *)bp;
 12608 
 12608 
 12609                 /* __BEGIN_INTERRUPTABLE__ is dangerous, because gethostbyname uses a static data area
 12609 		/* __BEGIN_INTERRUPTABLE__ is dangerous, because gethostbyname uses a static data area
 12610                  */
 12610 		 */
 12611                 hostp = gethostbyaddr((char *)&sa->sin_addr, sockAddrSize, sa->sin_family);
 12611 		hostp = gethostbyaddr((char *)&sa->sin_addr, sockAddrSize, sa->sin_family);
 12612                 /* __END_INTERRUPTABLE__ */
 12612 		/* __END_INTERRUPTABLE__ */
 12613             } while ((hostp == NULL)
 12613 	    } while ((hostp == NULL)
 12614                       && ((h_errno == TRY_AGAIN)
 12614 		      && ((h_errno == TRY_AGAIN)
 12615                           || errno == EINTR
 12615 			  || errno == EINTR
 12616 #   ifdef IRIX5_3
 12616 #   ifdef IRIX5_3
 12617                           || (errno == ECONNREFUSED)
 12617 			  || (errno == ECONNREFUSED)
 12618 #   endif
 12618 #   endif
 12619                          )
 12619 			 )
 12620             );
 12620 	    );
 12621             if (hostp == 0) {
 12621 	    if (hostp == 0) {
 12622                 switch (h_errno) {
 12622 		switch (h_errno) {
 12623                 case HOST_NOT_FOUND:
 12623 		case HOST_NOT_FOUND:
 12624                     errorString = @symbol(unknownHost);
 12624 		    errorString = @symbol(unknownHost);
 12625                     break;
 12625 		    break;
 12626                 case NO_ADDRESS:
 12626 		case NO_ADDRESS:
 12627                     errorString = @symbol(noAddress);
 12627 		    errorString = @symbol(noAddress);
 12628                     break;
 12628 		    break;
 12629                 case NO_RECOVERY:
 12629 		case NO_RECOVERY:
 12630                     errorString = @symbol(permanentFailure);
 12630 		    errorString = @symbol(permanentFailure);
 12631                     break;
 12631 		    break;
 12632                 case TRY_AGAIN:
 12632 		case TRY_AGAIN:
 12633                     errorString = @symbol(tryAgain);
 12633 		    errorString = @symbol(tryAgain);
 12634                     break;
 12634 		    break;
 12635                 default:
 12635 		default:
 12636                     errorString = @symbol(unknownError);
 12636 		    errorString = @symbol(unknownError);
 12637                     break;
 12637 		    break;
 12638                 }
 12638 		}
 12639                 error = __mkSmallInteger(h_errno);
 12639 		error = __mkSmallInteger(h_errno);
 12640                 goto err;
 12640 		goto err;
 12641             }
 12641 	    }
 12642 #  else /* !USE_H_ERRNO */
 12642 #  else /* !USE_H_ERRNO */
 12643             hostp = gethostbyaddr(sa->sin_addr, sockAddrSize, sa->sin_family);
 12643 	    hostp = gethostbyaddr(sa->sin_addr, sockAddrSize, sa->sin_family);
 12644             if (hostp == 0) {
 12644 	    if (hostp == 0) {
 12645                 errorString = @symbol(unknownHost);
 12645 		errorString = @symbol(unknownHost);
 12646                 error = __mkSmallInteger(-1);
 12646 		error = __mkSmallInteger(-1);
 12647                 goto err;
 12647 		goto err;
 12648             }
 12648 	    }
 12649 #  endif /* !USE_H_ERRNO*/
 12649 #  endif /* !USE_H_ERRNO*/
 12650             hp = hostp->h_name;
 12650 	    hp = hostp->h_name;
 12651         }
 12651 	}
 12652     }
 12652     }
 12653 # endif /* ! NI_NUMERICHOST */
 12653 # endif /* ! NI_NUMERICHOST */
 12654 
 12654 
 12655     if (hp)
 12655     if (hp)
 12656         hostName = __MKSTRING(hp);
 12656 	hostName = __MKSTRING(hp);
 12657     if (sp)
 12657     if (sp)
 12658         serviceName = __MKSTRING(sp);
 12658 	serviceName = __MKSTRING(sp);
 12659 err:;
 12659 err:;
 12660 #else
 12660 #else
 12661     error = @symbol(notImplemented);
 12661     error = @symbol(notImplemented);
 12662 #endif
 12662 #endif
 12663 %}.
 12663 %}.
 12664     error notNil ifTrue:[
 12664     error notNil ifTrue:[
 12665         ^ (HostAddressLookupError new
 12665 	^ (HostAddressLookupError new
 12666                 parameter:error;
 12666 		parameter:error;
 12667                 messageText:' - ', errorString;
 12667 		messageText:' - ', errorString;
 12668                 request:thisContext message) raiseRequest.
 12668 		request:thisContext message) raiseRequest.
 12669     ].
 12669     ].
 12670 
 12670 
 12671     ^ Array with:hostName with:serviceName
 12671     ^ Array with:hostName with:serviceName
 12672 
 12672 
 12673     "
 12673     "
 12674      self getNameInfo:
 12674      self getNameInfo:
 12675         (self getAddressInfo:'localhost' serviceName:'echo'
 12675 	(self getAddressInfo:'localhost' serviceName:'echo'
 12676                 domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12676 		domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12677          wantHostName:true wantServiceName:true datagram:false flags:0
 12677 	 wantHostName:true wantServiceName:true datagram:false flags:0
 12678 
 12678 
 12679      self getNameInfo:
 12679      self getNameInfo:
 12680         (self getAddressInfo:'exept.de' serviceName:'echo'
 12680 	(self getAddressInfo:'exept.de' serviceName:'echo'
 12681                 domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12681 		domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12682          wantHostName:true wantServiceName:true datagram:false flags:0
 12682 	 wantHostName:true wantServiceName:true datagram:false flags:0
 12683 
 12683 
 12684      self getNameInfo:
 12684      self getNameInfo:
 12685         (self getAddressInfo:'217.172.183.25' serviceName:'22'
 12685 	(self getAddressInfo:'217.172.183.25' serviceName:'22'
 12686                 domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12686 		domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12687          wantHostName:true wantServiceName:true datagram:false flags:0
 12687 	 wantHostName:true wantServiceName:true datagram:false flags:0
 12688 
 12688 
 12689      self getNameInfo:
 12689      self getNameInfo:
 12690         (self getAddressInfo:'1.2.3.4' serviceName:'22'
 12690 	(self getAddressInfo:'1.2.3.4' serviceName:'22'
 12691                 domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12691 		domain:#inet type:#stream protocol:nil flags:nil) first socketAddress
 12692          wantHostName:true wantServiceName:true datagram:false flags:0
 12692 	 wantHostName:true wantServiceName:true datagram:false flags:0
 12693     "
 12693     "
 12694 !
 12694 !
 12695 
 12695 
 12696 primGetAddressInfo:hostName serviceName:serviceName domainCode:domain socketTypeCode:type protocolCode:proto flags:flags
 12696 primGetAddressInfo:hostName serviceName:serviceName domainCode:domain socketTypeCode:type protocolCode:proto flags:flags
 12697     "answer an Array of socket addresses for serviceName on hostName
 12697     "answer an Array of socket addresses for serviceName on hostName
 12706 #if !defined(NO_SOCKET)
 12706 #if !defined(NO_SOCKET)
 12707     char *__hostName, *__serviceName;
 12707     char *__hostName, *__serviceName;
 12708     int ret, cnt = 0;
 12708     int ret, cnt = 0;
 12709 
 12709 
 12710     if (hostName == nil) {
 12710     if (hostName == nil) {
 12711         __hostName = 0;
 12711 	__hostName = 0;
 12712     } else if (__isStringLike(hostName)) {
 12712     } else if (__isStringLike(hostName)) {
 12713         __hostName = __stringVal(hostName);
 12713 	__hostName = __stringVal(hostName);
 12714     } else {
 12714     } else {
 12715         error = @symbol(badArgument1);
 12715 	error = @symbol(badArgument1);
 12716         goto out;
 12716 	goto out;
 12717     }
 12717     }
 12718     if (serviceName == nil) {
 12718     if (serviceName == nil) {
 12719         __serviceName = 0;
 12719 	__serviceName = 0;
 12720     } else if (__isStringLike(serviceName)) {
 12720     } else if (__isStringLike(serviceName)) {
 12721         __serviceName = __stringVal(serviceName);
 12721 	__serviceName = __stringVal(serviceName);
 12722     } else {
 12722     } else {
 12723         error = @symbol(badArgument2);
 12723 	error = @symbol(badArgument2);
 12724         goto out;
 12724 	goto out;
 12725     }
 12725     }
 12726     if (__hostName == 0 && __serviceName == 0) {
 12726     if (__hostName == 0 && __serviceName == 0) {
 12727         error = @symbol(badArgument);
 12727 	error = @symbol(badArgument);
 12728         goto out;
 12728 	goto out;
 12729     }
 12729     }
 12730 
 12730 
 12731 {
 12731 {
 12732 # if defined(AI_NUMERICHOST)
 12732 # if defined(AI_NUMERICHOST)
 12733     /*
 12733     /*
 12738 
 12738 
 12739 #if defined(AI_IDN)
 12739 #if defined(AI_IDN)
 12740     hints.ai_flags = AI_IDN | AI_CANONIDN;      // map non-ascii domain names to IDN format
 12740     hints.ai_flags = AI_IDN | AI_CANONIDN;      // map non-ascii domain names to IDN format
 12741 #endif
 12741 #endif
 12742     if (__isSmallInteger(domain))
 12742     if (__isSmallInteger(domain))
 12743         hints.ai_family = __intVal(domain);
 12743 	hints.ai_family = __intVal(domain);
 12744     if (__isSmallInteger(type))
 12744     if (__isSmallInteger(type))
 12745         hints.ai_socktype = __intVal(type);
 12745 	hints.ai_socktype = __intVal(type);
 12746     if (__isSmallInteger(proto))
 12746     if (__isSmallInteger(proto))
 12747         hints.ai_protocol = __intVal(proto);
 12747 	hints.ai_protocol = __intVal(proto);
 12748     if (__isSmallInteger(flags))
 12748     if (__isSmallInteger(flags))
 12749         hints.ai_flags |= __intVal(flags);
 12749 	hints.ai_flags |= __intVal(flags);
 12750 
 12750 
 12751     do {
 12751     do {
 12752         /* reload */
 12752 	/* reload */
 12753         if (__hostName) {
 12753 	if (__hostName) {
 12754             __hostName = __stringVal(hostName);
 12754 	    __hostName = __stringVal(hostName);
 12755         }
 12755 	}
 12756         if (__serviceName) {
 12756 	if (__serviceName) {
 12757             __serviceName = __stringVal(serviceName);
 12757 	    __serviceName = __stringVal(serviceName);
 12758         }
 12758 	}
 12759 
 12759 
 12760 //        __BEGIN_INTERRUPTABLE__
 12760 //        __BEGIN_INTERRUPTABLE__
 12761         ret = getaddrinfo(__hostName, __serviceName, &hints, &info);
 12761 	ret = getaddrinfo(__hostName, __serviceName, &hints, &info);
 12762 //        __END_INTERRUPTABLE__
 12762 //        __END_INTERRUPTABLE__
 12763     } while (ret == EAI_SYSTEM && errno == EINTR);
 12763     } while (ret == EAI_SYSTEM && errno == EINTR);
 12764     if (ret != 0) {
 12764     if (ret != 0) {
 12765         switch (ret) {
 12765 	switch (ret) {
 12766         case EAI_FAMILY:
 12766 	case EAI_FAMILY:
 12767             error = @symbol(badProtocol);
 12767 	    error = @symbol(badProtocol);
 12768             break;
 12768 	    break;
 12769         case EAI_SOCKTYPE:
 12769 	case EAI_SOCKTYPE:
 12770             error = @symbol(badSocketType);
 12770 	    error = @symbol(badSocketType);
 12771             break;
 12771 	    break;
 12772         case EAI_BADFLAGS:
 12772 	case EAI_BADFLAGS:
 12773             error = @symbol(badFlags);
 12773 	    error = @symbol(badFlags);
 12774             break;
 12774 	    break;
 12775         case EAI_NONAME:
 12775 	case EAI_NONAME:
 12776             error = @symbol(unknownHost);
 12776 	    error = @symbol(unknownHost);
 12777             break;
 12777 	    break;
 12778         case EAI_SERVICE:
 12778 	case EAI_SERVICE:
 12779             error = @symbol(unknownService);
 12779 	    error = @symbol(unknownService);
 12780             break;
 12780 	    break;
 12781 #ifdef EAI_ADDRFAMILY
 12781 #ifdef EAI_ADDRFAMILY
 12782         case EAI_ADDRFAMILY :
 12782 	case EAI_ADDRFAMILY :
 12783             error = @symbol(unknownHostForProtocol);
 12783 	    error = @symbol(unknownHostForProtocol);
 12784             break;
 12784 	    break;
 12785 #endif
 12785 #endif
 12786 #ifdef EAI_NODATA
 12786 #ifdef EAI_NODATA
 12787         case EAI_NODATA:
 12787 	case EAI_NODATA:
 12788             error = @symbol(noAddress);
 12788 	    error = @symbol(noAddress);
 12789             break;
 12789 	    break;
 12790 #endif
 12790 #endif
 12791         case EAI_MEMORY:
 12791 	case EAI_MEMORY:
 12792             error = @symbol(allocationFailure);
 12792 	    error = @symbol(allocationFailure);
 12793             break;
 12793 	    break;
 12794         case EAI_FAIL:
 12794 	case EAI_FAIL:
 12795             error = @symbol(permanentFailure);
 12795 	    error = @symbol(permanentFailure);
 12796             break;
 12796 	    break;
 12797         case EAI_AGAIN:
 12797 	case EAI_AGAIN:
 12798             error = @symbol(tryAgain);
 12798 	    error = @symbol(tryAgain);
 12799             break;
 12799 	    break;
 12800         case EAI_SYSTEM:
 12800 	case EAI_SYSTEM:
 12801             error = @symbol(systemError);
 12801 	    error = @symbol(systemError);
 12802             break;
 12802 	    break;
 12803         default:
 12803 	default:
 12804             error = @symbol(unknownError);
 12804 	    error = @symbol(unknownError);
 12805         }
 12805 	}
 12806         errorString = __MKSTRING(gai_strerror(ret));
 12806 	errorString = __MKSTRING(gai_strerror(ret));
 12807         goto err;
 12807 	goto err;
 12808     }
 12808     }
 12809     for (cnt=0, infop=info; infop; infop=infop->ai_next)
 12809     for (cnt=0, infop=info; infop; infop=infop->ai_next)
 12810         cnt++;
 12810 	cnt++;
 12811 
 12811 
 12812     result = __ARRAY_NEW_INT(cnt);
 12812     result = __ARRAY_NEW_INT(cnt);
 12813     if (result == nil) {
 12813     if (result == nil) {
 12814         error = @symbol(allocationFailure);
 12814 	error = @symbol(allocationFailure);
 12815         goto err;
 12815 	goto err;
 12816     }
 12816     }
 12817     for (infop=info, cnt=0; infop; infop=infop->ai_next, cnt++) {
 12817     for (infop=info, cnt=0; infop; infop=infop->ai_next, cnt++) {
 12818         OBJ o, resp;
 12818 	OBJ o, resp;
 12819 
 12819 
 12820         resp = __ARRAY_NEW_INT(6);
 12820 	resp = __ARRAY_NEW_INT(6);
 12821         if (resp == nil) {
 12821 	if (resp == nil) {
 12822             error = @symbol(allocationFailure);
 12822 	    error = @symbol(allocationFailure);
 12823             goto err;
 12823 	    goto err;
 12824         }
 12824 	}
 12825 
 12825 
 12826         __ArrayInstPtr(result)->a_element[cnt] = resp; __STORE(result, resp);
 12826 	__ArrayInstPtr(result)->a_element[cnt] = resp; __STORE(result, resp);
 12827 
 12827 
 12828         __ArrayInstPtr(resp)->a_element[0] = __mkSmallInteger(infop->ai_flags);
 12828 	__ArrayInstPtr(resp)->a_element[0] = __mkSmallInteger(infop->ai_flags);
 12829         __ArrayInstPtr(resp)->a_element[1] = __mkSmallInteger(infop->ai_family);
 12829 	__ArrayInstPtr(resp)->a_element[1] = __mkSmallInteger(infop->ai_family);
 12830         __ArrayInstPtr(resp)->a_element[2] = __mkSmallInteger(infop->ai_socktype);
 12830 	__ArrayInstPtr(resp)->a_element[2] = __mkSmallInteger(infop->ai_socktype);
 12831         __ArrayInstPtr(resp)->a_element[3] = __mkSmallInteger(infop->ai_protocol);
 12831 	__ArrayInstPtr(resp)->a_element[3] = __mkSmallInteger(infop->ai_protocol);
 12832 
 12832 
 12833         __PROTECT__(resp);
 12833 	__PROTECT__(resp);
 12834         o = __BYTEARRAY_NEW_INT(infop->ai_addrlen);
 12834 	o = __BYTEARRAY_NEW_INT(infop->ai_addrlen);
 12835         __UNPROTECT__(resp);
 12835 	__UNPROTECT__(resp);
 12836         if (o == nil) {
 12836 	if (o == nil) {
 12837             error = @symbol(allocationFailure);
 12837 	    error = @symbol(allocationFailure);
 12838             goto err;
 12838 	    goto err;
 12839         }
 12839 	}
 12840         memcpy(__byteArrayVal(o), infop->ai_addr, infop->ai_addrlen);
 12840 	memcpy(__byteArrayVal(o), infop->ai_addr, infop->ai_addrlen);
 12841        __ArrayInstPtr(resp)->a_element[4] = o; __STORE(resp, o);
 12841        __ArrayInstPtr(resp)->a_element[4] = o; __STORE(resp, o);
 12842 
 12842 
 12843         if (infop->ai_canonname) {
 12843 	if (infop->ai_canonname) {
 12844             __PROTECT__(resp);
 12844 	    __PROTECT__(resp);
 12845             o = __MKSTRING(infop->ai_canonname);
 12845 	    o = __MKSTRING(infop->ai_canonname);
 12846             __UNPROTECT__(resp);
 12846 	    __UNPROTECT__(resp);
 12847             if (o == nil) {
 12847 	    if (o == nil) {
 12848                 error = @symbol(allocationFailure);
 12848 		error = @symbol(allocationFailure);
 12849                 goto err;
 12849 		goto err;
 12850             }
 12850 	    }
 12851             __ArrayInstPtr(resp)->a_element[5] = o; __STORE(resp, o);
 12851 	    __ArrayInstPtr(resp)->a_element[5] = o; __STORE(resp, o);
 12852         }
 12852 	}
 12853     }
 12853     }
 12854 
 12854 
 12855 err:
 12855 err:
 12856     if (info) freeaddrinfo(info);
 12856     if (info) freeaddrinfo(info);
 12857 
 12857 
 12864     char **addrpp;
 12864     char **addrpp;
 12865     int port = 0;
 12865     int port = 0;
 12866     int i;
 12866     int i;
 12867 
 12867 
 12868     if (__serviceName) {
 12868     if (__serviceName) {
 12869         struct servent *sp;
 12869 	struct servent *sp;
 12870         char *__proto = 0;
 12870 	char *__proto = 0;
 12871 
 12871 
 12872         if (__isStringLike(protoArg))
 12872 	if (__isStringLike(protoArg))
 12873             __proto = __stringVal(protoArg);
 12873 	    __proto = __stringVal(protoArg);
 12874 
 12874 
 12875         sp = getservbyname(__serviceName, __proto);
 12875 	sp = getservbyname(__serviceName, __proto);
 12876         if (sp == NULL) {
 12876 	if (sp == NULL) {
 12877             errorString = @symbol(unknownService);
 12877 	    errorString = @symbol(unknownService);
 12878             error = __mkSmallInteger(-3);
 12878 	    error = __mkSmallInteger(-3);
 12879             goto err;
 12879 	    goto err;
 12880         }
 12880 	}
 12881         port = sp->s_port;
 12881 	port = sp->s_port;
 12882     }
 12882     }
 12883 
 12883 
 12884     if (__hostName) {
 12884     if (__hostName) {
 12885 #  ifdef USE_H_ERRNO
 12885 #  ifdef USE_H_ERRNO
 12886         do {
 12886 	do {
 12887             if (hostName == nil) {
 12887 	    if (hostName == nil) {
 12888                 __hostName = 0;
 12888 		__hostName = 0;
 12889             } else if (__isStringLike(hostName)) {
 12889 	    } else if (__isStringLike(hostName)) {
 12890                 __hostName = __stringVal(hostName);
 12890 		__hostName = __stringVal(hostName);
 12891             }
 12891 	    }
 12892             /* __BEGIN_INTERRUPTABLE__ is dangerous, because gethostbyname
 12892 	    /* __BEGIN_INTERRUPTABLE__ is dangerous, because gethostbyname
 12893              * uses a static data area
 12893 	     * uses a static data area
 12894              */
 12894 	     */
 12895             __BEGIN_INTERRUPTABLE__
 12895 	    __BEGIN_INTERRUPTABLE__
 12896             hp = gethostbyname(__hostName);
 12896 	    hp = gethostbyname(__hostName);
 12897             __END_INTERRUPTABLE__
 12897 	    __END_INTERRUPTABLE__
 12898         } while ((hp == NULL)
 12898 	} while ((hp == NULL)
 12899                   && (
 12899 		  && (
 12900                         (h_errno == TRY_AGAIN)
 12900 			(h_errno == TRY_AGAIN)
 12901                       || errno == EINTR
 12901 		      || errno == EINTR
 12902 #   ifdef IRIX5_3
 12902 #   ifdef IRIX5_3
 12903                       || (errno == ECONNREFUSED)
 12903 		      || (errno == ECONNREFUSED)
 12904 #   endif
 12904 #   endif
 12905                      )
 12905 		     )
 12906         );
 12906 	);
 12907         if (hp == 0) {
 12907 	if (hp == 0) {
 12908             switch (h_errno) {
 12908 	    switch (h_errno) {
 12909             case HOST_NOT_FOUND:
 12909 	    case HOST_NOT_FOUND:
 12910                 errorString = @symbol(unknownHost);
 12910 		errorString = @symbol(unknownHost);
 12911                 break;
 12911 		break;
 12912             case NO_ADDRESS:
 12912 	    case NO_ADDRESS:
 12913                 errorString = @symbol(noAddress);
 12913 		errorString = @symbol(noAddress);
 12914                 break;
 12914 		break;
 12915             case NO_RECOVERY:
 12915 	    case NO_RECOVERY:
 12916                 errorString = @symbol(permanentFailure);
 12916 		errorString = @symbol(permanentFailure);
 12917                 break;
 12917 		break;
 12918             case TRY_AGAIN:
 12918 	    case TRY_AGAIN:
 12919                 errorString = @symbol(tryAgain);
 12919 		errorString = @symbol(tryAgain);
 12920                 break;
 12920 		break;
 12921             default:
 12921 	    default:
 12922                 errorString = @symbol(unknownError);
 12922 		errorString = @symbol(unknownError);
 12923                 break;
 12923 		break;
 12924             }
 12924 	    }
 12925             error = __mkSmallInteger(h_errno);
 12925 	    error = __mkSmallInteger(h_errno);
 12926             goto err;
 12926 	    goto err;
 12927         }
 12927 	}
 12928 #  else /* !USE_H_ERRNO */
 12928 #  else /* !USE_H_ERRNO */
 12929         hp = gethostbyname(__hostName);
 12929 	hp = gethostbyname(__hostName);
 12930         if (hp == 0) {
 12930 	if (hp == 0) {
 12931             errorString = @symbol(unknownHost);
 12931 	    errorString = @symbol(unknownHost);
 12932             error = __mkSmallInteger(-1);
 12932 	    error = __mkSmallInteger(-1);
 12933             goto err;
 12933 	    goto err;
 12934         }
 12934 	}
 12935 #  endif /* !USE_H_ERRNO*/
 12935 #  endif /* !USE_H_ERRNO*/
 12936 
 12936 
 12937         if (__isSmallInteger(domain) && hp->h_addrtype != __smallIntegerVal(domain)) {
 12937 	if (__isSmallInteger(domain) && hp->h_addrtype != __smallIntegerVal(domain)) {
 12938             errorString = @symbol(unknownHost);
 12938 	    errorString = @symbol(unknownHost);
 12939             error = __mkSmallInteger(-2);
 12939 	    error = __mkSmallInteger(-2);
 12940             goto err;
 12940 	    goto err;
 12941         }
 12941 	}
 12942 
 12942 
 12943         for (cnt = 0, addrpp = hp->h_addr_list; *addrpp; addrpp++)
 12943 	for (cnt = 0, addrpp = hp->h_addr_list; *addrpp; addrpp++)
 12944             cnt++;
 12944 	    cnt++;
 12945         addrpp = hp->h_addr_list;
 12945 	addrpp = hp->h_addr_list;
 12946     } else {
 12946     } else {
 12947         cnt = 1;
 12947 	cnt = 1;
 12948     }
 12948     }
 12949 
 12949 
 12950     result = __ARRAY_NEW_INT(cnt);
 12950     result = __ARRAY_NEW_INT(cnt);
 12951     if (result == nil) {
 12951     if (result == nil) {
 12952         error = @symbol(allocationFailure);
 12952 	error = @symbol(allocationFailure);
 12953         goto err;
 12953 	goto err;
 12954     }
 12954     }
 12955 
 12955 
 12956     for (i = 0; i < cnt; i++) {
 12956     for (i = 0; i < cnt; i++) {
 12957         OBJ o, resp;
 12957 	OBJ o, resp;
 12958         struct sockaddr_in *sa;
 12958 	struct sockaddr_in *sa;
 12959 
 12959 
 12960         resp = __ARRAY_NEW_INT(6);
 12960 	resp = __ARRAY_NEW_INT(6);
 12961         if (resp == nil) {
 12961 	if (resp == nil) {
 12962             error = @symbol(allocationFailure);
 12962 	    error = @symbol(allocationFailure);
 12963             goto err;
 12963 	    goto err;
 12964         }
 12964 	}
 12965 
 12965 
 12966         __ArrayInstPtr(result)->a_element[i] = resp; __STORE(result, resp);
 12966 	__ArrayInstPtr(result)->a_element[i] = resp; __STORE(result, resp);
 12967         __ArrayInstPtr(resp)->a_element[0] = __mkSmallInteger(0);
 12967 	__ArrayInstPtr(resp)->a_element[0] = __mkSmallInteger(0);
 12968         __ArrayInstPtr(resp)->a_element[2] = type; __STORE(result, type);
 12968 	__ArrayInstPtr(resp)->a_element[2] = type; __STORE(result, type);
 12969         __ArrayInstPtr(resp)->a_element[3] = proto; __STORE(result, proto);
 12969 	__ArrayInstPtr(resp)->a_element[3] = proto; __STORE(result, proto);
 12970         __PROTECT__(resp);
 12970 	__PROTECT__(resp);
 12971         o = __BYTEARRAY_NEW_INT(sizeof(*sa));
 12971 	o = __BYTEARRAY_NEW_INT(sizeof(*sa));
 12972         __UNPROTECT__(resp);
 12972 	__UNPROTECT__(resp);
 12973         if (o == nil) {
 12973 	if (o == nil) {
 12974             error = @symbol(allocationFailure);
 12974 	    error = @symbol(allocationFailure);
 12975             goto err;
 12975 	    goto err;
 12976         }
 12976 	}
 12977         __ArrayInstPtr(resp)->a_element[4] = o; __STORE(resp, o);
 12977 	__ArrayInstPtr(resp)->a_element[4] = o; __STORE(resp, o);
 12978         sa = (struct sockaddr_in *)__byteArrayVal(o);
 12978 	sa = (struct sockaddr_in *)__byteArrayVal(o);
 12979         sa->sin_port = port;
 12979 	sa->sin_port = port;
 12980 
 12980 
 12981         if (__hostName) {
 12981 	if (__hostName) {
 12982             sa->sin_family = hp->h_addrtype;
 12982 	    sa->sin_family = hp->h_addrtype;
 12983             memcpy(&sa->sin_addr, *addrpp, hp->h_length);
 12983 	    memcpy(&sa->sin_addr, *addrpp, hp->h_length);
 12984             __ArrayInstPtr(resp)->a_element[1] = __mkSmallInteger(hp->h_addrtype);
 12984 	    __ArrayInstPtr(resp)->a_element[1] = __mkSmallInteger(hp->h_addrtype);
 12985             if (hp->h_name) {
 12985 	    if (hp->h_name) {
 12986                 __PROTECT__(resp);
 12986 		__PROTECT__(resp);
 12987                 o = __MKSTRING(hp->h_name);
 12987 		o = __MKSTRING(hp->h_name);
 12988                 __UNPROTECT__(resp);
 12988 		__UNPROTECT__(resp);
 12989                 if (o == nil) {
 12989 		if (o == nil) {
 12990                     error = @symbol(allocationFailure);
 12990 		    error = @symbol(allocationFailure);
 12991                     goto err;
 12991 		    goto err;
 12992                 }
 12992 		}
 12993                 __ArrayInstPtr(resp)->a_element[5] = o; __STORE(resp, o);
 12993 		__ArrayInstPtr(resp)->a_element[5] = o; __STORE(resp, o);
 12994             }
 12994 	    }
 12995             addrpp++;
 12995 	    addrpp++;
 12996         } else{
 12996 	} else{
 12997             __ArrayInstPtr(resp)->a_element[1] = domain; __STORE(resp, domain);
 12997 	    __ArrayInstPtr(resp)->a_element[1] = domain; __STORE(resp, domain);
 12998         }
 12998 	}
 12999     }
 12999     }
 13000 
 13000 
 13001 err:;
 13001 err:;
 13002 # endif /* ! AI_NUMERICHOST */
 13002 # endif /* ! AI_NUMERICHOST */
 13003 }
 13003 }
 13005     error = @symbol(notImplemented);
 13005     error = @symbol(notImplemented);
 13006 #endif
 13006 #endif
 13007 out:;
 13007 out:;
 13008 %}.
 13008 %}.
 13009     error notNil ifTrue:[
 13009     error notNil ifTrue:[
 13010         errorString notNil ifTrue:[
 13010 	errorString notNil ifTrue:[
 13011             ^ errorString.
 13011 	    ^ errorString.
 13012         ].
 13012 	].
 13013         ^ error.
 13013 	^ error.
 13014     ].
 13014     ].
 13015     ^ result.
 13015     ^ result.
 13016 ! !
 13016 ! !
 13017 
 13017 
 13018 !UnixOperatingSystem::SocketHandle methodsFor:'accepting'!
 13018 !UnixOperatingSystem::SocketHandle methodsFor:'accepting'!
 13031     int sock, newSock;
 13031     int sock, newSock;
 13032     struct sockaddr *sap;
 13032     struct sockaddr *sap;
 13033     int alen;
 13033     int alen;
 13034 
 13034 
 13035     if (!__isSmallInteger(__INST(fd))) {
 13035     if (!__isSmallInteger(__INST(fd))) {
 13036         error = @symbol(badFd);
 13036 	error = @symbol(badFd);
 13037         goto err;
 13037 	goto err;
 13038     }
 13038     }
 13039     if (peerOrNil != nil &&
 13039     if (peerOrNil != nil &&
 13040         (!__isNonNilObject(peerOrNil) ||
 13040 	(!__isNonNilObject(peerOrNil) ||
 13041          (__intVal(__ClassInstPtr(__qClass(peerOrNil))->c_flags) & ARRAYMASK) != BYTEARRAY)) {
 13041 	 (__intVal(__ClassInstPtr(__qClass(peerOrNil))->c_flags) & ARRAYMASK) != BYTEARRAY)) {
 13042         error = @symbol(badArgument2);
 13042 	error = @symbol(badArgument2);
 13043         goto err;
 13043 	goto err;
 13044     }
 13044     }
 13045 
 13045 
 13046     sock = __smallIntegerVal(__INST(fd));
 13046     sock = __smallIntegerVal(__INST(fd));
 13047 
 13047 
 13048 again:
 13048 again:
 13049     if (peerOrNil == nil) {
 13049     if (peerOrNil == nil) {
 13050         alen = 0;
 13050 	alen = 0;
 13051         sap = 0;
 13051 	sap = 0;
 13052     } else {
 13052     } else {
 13053         alen =  __byteArraySize(peerOrNil);
 13053 	alen =  __byteArraySize(peerOrNil);
 13054         sap = (struct sockaddr *)__byteArrayVal(peerOrNil);
 13054 	sap = (struct sockaddr *)__byteArrayVal(peerOrNil);
 13055     }
 13055     }
 13056     newSock = accept(sock, sap, &alen);
 13056     newSock = accept(sock, sap, &alen);
 13057     if (newSock < 0) {
 13057     if (newSock < 0) {
 13058         switch (errno) {
 13058 	switch (errno) {
 13059         case EINTR:
 13059 	case EINTR:
 13060             __HANDLE_INTERRUPTS__;
 13060 	    __HANDLE_INTERRUPTS__;
 13061             goto again;
 13061 	    goto again;
 13062 
 13062 
 13063 #ifdef EWOULDBLOCK
 13063 #ifdef EWOULDBLOCK
 13064         case EWOULDBLOCK:
 13064 	case EWOULDBLOCK:
 13065 # if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK)
 13065 # if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK)
 13066         case EAGAIN:
 13066 	case EAGAIN:
 13067 # endif
 13067 # endif
 13068 #else
 13068 #else
 13069 # ifdef EAGAIN
 13069 # ifdef EAGAIN
 13070         case EAGAIN:
 13070 	case EAGAIN:
 13071 # endif
 13071 # endif
 13072 #endif
 13072 #endif
 13073             RETURN(nil);
 13073 	    RETURN(nil);
 13074 
 13074 
 13075         default:
 13075 	default:
 13076             error = __mkSmallInteger(errno);
 13076 	    error = __mkSmallInteger(errno);
 13077             goto err;
 13077 	    goto err;
 13078         }
 13078 	}
 13079     }
 13079     }
 13080     newFd = __mkSmallInteger(newSock);
 13080     newFd = __mkSmallInteger(newSock);
 13081 
 13081 
 13082 err:;
 13082 err:;
 13083 #endif /* not NO_SOCKET */
 13083 #endif /* not NO_SOCKET */
 13084 %}.
 13084 %}.
 13085     error notNil ifTrue:[
 13085     error notNil ifTrue:[
 13086         ^ self error:error.
 13086 	^ self error:error.
 13087     ].
 13087     ].
 13088     ^ self class for:newFd
 13088     ^ self class for:newFd
 13089 ! !
 13089 ! !
 13090 
 13090 
 13091 !UnixOperatingSystem::SocketHandle methodsFor:'binding'!
 13091 !UnixOperatingSystem::SocketHandle methodsFor:'binding'!
 13101     int sock;
 13101     int sock;
 13102     int sockaddr_size;
 13102     int sockaddr_size;
 13103     int ret;
 13103     int ret;
 13104 
 13104 
 13105     if (!__isSmallInteger(__INST(fd))) {
 13105     if (!__isSmallInteger(__INST(fd))) {
 13106         error = @symbol(badFd);
 13106 	error = @symbol(badFd);
 13107         goto err;
 13107 	goto err;
 13108     }
 13108     }
 13109     if (!__isNonNilObject(socketAddress) ||
 13109     if (!__isNonNilObject(socketAddress) ||
 13110         (__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13110 	(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13111         error = @symbol(badArgument1);
 13111 	error = @symbol(badArgument1);
 13112         goto err;
 13112 	goto err;
 13113     }
 13113     }
 13114     sockaddr_size = __byteArraySize(socketAddress);
 13114     sockaddr_size = __byteArraySize(socketAddress);
 13115     sock = __smallIntegerVal(__INST(fd));
 13115     sock = __smallIntegerVal(__INST(fd));
 13116 
 13116 
 13117 again:
 13117 again:
 13118     ret = bind(sock, (struct sockaddr *)__byteArrayVal(socketAddress), sockaddr_size);
 13118     ret = bind(sock, (struct sockaddr *)__byteArrayVal(socketAddress), sockaddr_size);
 13119     if (ret < 0) {
 13119     if (ret < 0) {
 13120         if (errno == EINTR) {
 13120 	if (errno == EINTR) {
 13121             __HANDLE_INTERRUPTS__;
 13121 	    __HANDLE_INTERRUPTS__;
 13122             goto again;
 13122 	    goto again;
 13123         } else {
 13123 	} else {
 13124             error = __mkSmallInteger(errno);
 13124 	    error = __mkSmallInteger(errno);
 13125             goto err;
 13125 	    goto err;
 13126         }
 13126 	}
 13127     }
 13127     }
 13128 
 13128 
 13129     err:;
 13129     err:;
 13130 #endif /* NO_SOCKET */
 13130 #endif /* NO_SOCKET */
 13131 %}.
 13131 %}.
 13132     error notNil ifTrue:[
 13132     error notNil ifTrue:[
 13133         ^ self error:error.
 13133 	^ self error:error.
 13134     ].
 13134     ].
 13135     ^ nil
 13135     ^ nil
 13136 
 13136 
 13137     "
 13137     "
 13138      (Socket domain:#inet type:#stream)
 13138      (Socket domain:#inet type:#stream)
 13139          bindTo:(IPSocketAddress hostAddress:IPSocketAddress anyAddress port:9999)
 13139 	 bindTo:(IPSocketAddress hostAddress:IPSocketAddress anyAddress port:9999)
 13140          reuseAddress:false ;
 13140 	 reuseAddress:false ;
 13141      yourself
 13141      yourself
 13142     "
 13142     "
 13143 ! !
 13143 ! !
 13144 
 13144 
 13145 !UnixOperatingSystem::SocketHandle methodsFor:'connecting'!
 13145 !UnixOperatingSystem::SocketHandle methodsFor:'connecting'!
 13154     int sock;
 13154     int sock;
 13155     int ret;
 13155     int ret;
 13156     struct sockaddr sockaddr;
 13156     struct sockaddr sockaddr;
 13157 
 13157 
 13158     if (!__isSmallInteger(__INST(fd))) {
 13158     if (!__isSmallInteger(__INST(fd))) {
 13159         error = @symbol(badFd);
 13159 	error = @symbol(badFd);
 13160         goto err;
 13160 	goto err;
 13161     }
 13161     }
 13162     sock = __smallIntegerVal(__INST(fd));
 13162     sock = __smallIntegerVal(__INST(fd));
 13163 
 13163 
 13164     /*
 13164     /*
 13165      * (dis-) connect by connecting to AF_UNSPEC socket
 13165      * (dis-) connect by connecting to AF_UNSPEC socket
 13167 again:
 13167 again:
 13168     sockaddr.sa_family = AF_UNSPEC;
 13168     sockaddr.sa_family = AF_UNSPEC;
 13169     ret = connect(sock, &sockaddr, sizeof(sockaddr));
 13169     ret = connect(sock, &sockaddr, sizeof(sockaddr));
 13170     if (ret < 0) {
 13170     if (ret < 0) {
 13171        switch(errno) {
 13171        switch(errno) {
 13172            case EINTR:
 13172 	   case EINTR:
 13173 # ifdef EAGAIN
 13173 # ifdef EAGAIN
 13174             case EAGAIN:
 13174 	    case EAGAIN:
 13175 # endif
 13175 # endif
 13176                 __HANDLE_INTERRUPTS__;
 13176 		__HANDLE_INTERRUPTS__;
 13177                 goto again;
 13177 		goto again;
 13178 
 13178 
 13179             default:
 13179 	    default:
 13180                 error = __mkSmallInteger(errno);
 13180 		error = __mkSmallInteger(errno);
 13181                 break;
 13181 		break;
 13182         }
 13182 	}
 13183     }
 13183     }
 13184 
 13184 
 13185 err:;
 13185 err:;
 13186 #endif /* NO_SOCKET */
 13186 #endif /* NO_SOCKET */
 13187 %}.
 13187 %}.
 13188 
 13188 
 13189     error notNil ifTrue:[
 13189     error notNil ifTrue:[
 13190         ^ self error:error.
 13190 	^ self error:error.
 13191     ].
 13191     ].
 13192 !
 13192 !
 13193 
 13193 
 13194 connectTo:socketAddress
 13194 connectTo:socketAddress
 13195     "low level connect; connect to a socket address.
 13195     "low level connect; connect to a socket address.
 13204     int sock;
 13204     int sock;
 13205     int ret;
 13205     int ret;
 13206     int sockaddr_size;
 13206     int sockaddr_size;
 13207 
 13207 
 13208     if (!__isSmallInteger(__INST(fd))) {
 13208     if (!__isSmallInteger(__INST(fd))) {
 13209         error = @symbol(badFd);
 13209 	error = @symbol(badFd);
 13210         goto err;
 13210 	goto err;
 13211     }
 13211     }
 13212     if (!__isNonNilObject(socketAddress) ||
 13212     if (!__isNonNilObject(socketAddress) ||
 13213         (__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13213 	(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13214         error = @symbol(badArgument1);
 13214 	error = @symbol(badArgument1);
 13215         goto err;
 13215 	goto err;
 13216     }
 13216     }
 13217     sock = __smallIntegerVal(__INST(fd));
 13217     sock = __smallIntegerVal(__INST(fd));
 13218     sockaddr_size = __qSize(socketAddress);
 13218     sockaddr_size = __qSize(socketAddress);
 13219 
 13219 
 13220 again:
 13220 again:
 13221     ret = connect(sock, (struct sockaddr *)__byteArrayVal(socketAddress), sockaddr_size);
 13221     ret = connect(sock, (struct sockaddr *)__byteArrayVal(socketAddress), sockaddr_size);
 13222     if (ret >= 0) {
 13222     if (ret >= 0) {
 13223         RETURN(true)
 13223 	RETURN(true)
 13224     }
 13224     }
 13225 
 13225 
 13226     switch(errno) {
 13226     switch(errno) {
 13227         case EINTR:
 13227 	case EINTR:
 13228 # ifdef EAGAIN
 13228 # ifdef EAGAIN
 13229         case EAGAIN:
 13229 	case EAGAIN:
 13230 # endif
 13230 # endif
 13231             __HANDLE_INTERRUPTS__;
 13231 	    __HANDLE_INTERRUPTS__;
 13232             goto again;
 13232 	    goto again;
 13233 
 13233 
 13234 # if defined(EINPROGRESS) || defined(EALREADY)
 13234 # if defined(EINPROGRESS) || defined(EALREADY)
 13235 #  ifdef EINPROGRESS
 13235 #  ifdef EINPROGRESS
 13236         case EINPROGRESS:
 13236 	case EINPROGRESS:
 13237 #  endif
 13237 #  endif
 13238 #  ifdef EALREADY
 13238 #  ifdef EALREADY
 13239         case EALREADY:
 13239 	case EALREADY:
 13240 #  endif
 13240 #  endif
 13241             RETURN(false);
 13241 	    RETURN(false);
 13242 # endif
 13242 # endif
 13243 
 13243 
 13244     default:
 13244     default:
 13245         error = __mkSmallInteger(errno);
 13245 	error = __mkSmallInteger(errno);
 13246         break;
 13246 	break;
 13247     }
 13247     }
 13248 
 13248 
 13249 err:;
 13249 err:;
 13250 #endif /* NO_SOCKET */
 13250 #endif /* NO_SOCKET */
 13251 %}.
 13251 %}.
 13252     error notNil ifTrue:[
 13252     error notNil ifTrue:[
 13253          ^ self error:error.
 13253 	 ^ self error:error.
 13254     ].
 13254     ].
 13255     ^ true
 13255     ^ true
 13256 
 13256 
 13257     "
 13257     "
 13258      Socket newTCP connectTo:(IPSocketAddress hostAddress:IPSocketAddress local port:7)
 13258      Socket newTCP connectTo:(IPSocketAddress hostAddress:IPSocketAddress local port:7)
 13259                    withTimeout:nil.
 13259 		   withTimeout:nil.
 13260      Socket newTCP connectTo:(IPSocketAddress hostAddress:IPSocketAddress local port:5768)
 13260      Socket newTCP connectTo:(IPSocketAddress hostAddress:IPSocketAddress local port:5768)
 13261                    withTimeout:nil.
 13261 		   withTimeout:nil.
 13262      Socket newTCP connectTo:(IPSocketAddress hostAddress:#[1 2 3 4] port:7)
 13262      Socket newTCP connectTo:(IPSocketAddress hostAddress:#[1 2 3 4] port:7)
 13263                    withTimeout:nil.
 13263 		   withTimeout:nil.
 13264     "
 13264     "
 13265 ! !
 13265 ! !
 13266 
 13266 
 13267 !UnixOperatingSystem::SocketHandle methodsFor:'datagram transmission'!
 13267 !UnixOperatingSystem::SocketHandle methodsFor:'datagram transmission'!
 13268 
 13268 
 13288     int n;
 13288     int n;
 13289     char *cp;
 13289     char *cp;
 13290     int __flags, __startIndex, __nBytes;
 13290     int __flags, __startIndex, __nBytes;
 13291 
 13291 
 13292     if (!__isSmallInteger(__INST(fd))) {
 13292     if (!__isSmallInteger(__INST(fd))) {
 13293         error = @symbol(badFd);
 13293 	error = @symbol(badFd);
 13294         goto err;
 13294 	goto err;
 13295     }
 13295     }
 13296     if (!__isSmallInteger(startIndex) ||
 13296     if (!__isSmallInteger(startIndex) ||
 13297         (__startIndex = __intVal(startIndex)-1) < 0) {
 13297 	(__startIndex = __intVal(startIndex)-1) < 0) {
 13298         if (startIndex == nil) {
 13298 	if (startIndex == nil) {
 13299             __startIndex = 0;
 13299 	    __startIndex = 0;
 13300         } else {
 13300 	} else {
 13301             error = @symbol(badArgument3);
 13301 	    error = @symbol(badArgument3);
 13302             goto err;
 13302 	    goto err;
 13303         }
 13303 	}
 13304     }
 13304     }
 13305     if (__isSmallInteger(nBytes)) {
 13305     if (__isSmallInteger(nBytes)) {
 13306         __nBytes = __intVal(nBytes);
 13306 	__nBytes = __intVal(nBytes);
 13307     } else if (nBytes == nil) {
 13307     } else if (nBytes == nil) {
 13308         __nBytes = -1;
 13308 	__nBytes = -1;
 13309     } else {
 13309     } else {
 13310         error = @symbol(badArgument4);
 13310 	error = @symbol(badArgument4);
 13311         goto err;
 13311 	goto err;
 13312     }
 13312     }
 13313     if (!__isInteger(flags)) {
 13313     if (!__isInteger(flags)) {
 13314         error = @symbol(badArgument5);
 13314 	error = @symbol(badArgument5);
 13315         goto err;
 13315 	goto err;
 13316     }
 13316     }
 13317     __flags = __longIntVal(flags);
 13317     __flags = __longIntVal(flags);
 13318     sock = __smallIntegerVal(__INST(fd));
 13318     sock = __smallIntegerVal(__INST(fd));
 13319 
 13319 
 13320     oClass = __Class(aDataBuffer);
 13320     oClass = __Class(aDataBuffer);
 13321     switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 13321     switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 13322         case BYTEARRAY:
 13322 	case BYTEARRAY:
 13323         case WORDARRAY:
 13323 	case WORDARRAY:
 13324         case SWORDARRAY:
 13324 	case SWORDARRAY:
 13325         case LONGARRAY:
 13325 	case LONGARRAY:
 13326         case SLONGARRAY:
 13326 	case SLONGARRAY:
 13327         case FLOATARRAY:
 13327 	case FLOATARRAY:
 13328         case DOUBLEARRAY:
 13328 	case DOUBLEARRAY:
 13329             break;
 13329 	    break;
 13330         default:
 13330 	default:
 13331             error = @symbol(badArgument2);
 13331 	    error = @symbol(badArgument2);
 13332             goto err;
 13332 	    goto err;
 13333     }
 13333     }
 13334 
 13334 
 13335     nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
 13335     nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
 13336     nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
 13336     nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
 13337     objSize = __qSize(aDataBuffer) - nInstBytes;
 13337     objSize = __qSize(aDataBuffer) - nInstBytes;
 13338     nInstBytes += __startIndex;
 13338     nInstBytes += __startIndex;
 13339     objSize -= __startIndex;
 13339     objSize -= __startIndex;
 13340 
 13340 
 13341     if (__nBytes >= 0 &&__nBytes < objSize) {
 13341     if (__nBytes >= 0 &&__nBytes < objSize) {
 13342         objSize = __nBytes;
 13342 	objSize = __nBytes;
 13343     }
 13343     }
 13344 
 13344 
 13345     if (socketAddress == nil) {
 13345     if (socketAddress == nil) {
 13346         alen0 = 0;
 13346 	alen0 = 0;
 13347     } else {
 13347     } else {
 13348         if (!__isNonNilObject(socketAddress) ||
 13348 	if (!__isNonNilObject(socketAddress) ||
 13349             (__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13349 	    (__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13350             error = @symbol(badArgument1);
 13350 	    error = @symbol(badArgument1);
 13351             goto err;
 13351 	    goto err;
 13352         }
 13352 	}
 13353         alen0 = __byteArraySize(socketAddress);
 13353 	alen0 = __byteArraySize(socketAddress);
 13354     }
 13354     }
 13355     saPtr = (struct sockaddr *)0;
 13355     saPtr = (struct sockaddr *)0;
 13356 
 13356 
 13357 again:
 13357 again:
 13358     alen = alen0;
 13358     alen = alen0;
 13359     if (alen)
 13359     if (alen)
 13360         saPtr = (struct sockaddr *)__byteArrayVal(socketAddress);
 13360 	saPtr = (struct sockaddr *)__byteArrayVal(socketAddress);
 13361     cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
 13361     cp = (char *)__InstPtr(aDataBuffer) + nInstBytes;
 13362     n = recvfrom(sock, cp, objSize, __flags, saPtr, &alen);
 13362     n = recvfrom(sock, cp, objSize, __flags, saPtr, &alen);
 13363     if (n < 0) {
 13363     if (n < 0) {
 13364         if (errno == EINTR) {
 13364 	if (errno == EINTR) {
 13365             __HANDLE_INTERRUPTS__;
 13365 	    __HANDLE_INTERRUPTS__;
 13366             goto again;
 13366 	    goto again;
 13367         } else {
 13367 	} else {
 13368             error = __mkSmallInteger(errno);
 13368 	    error = __mkSmallInteger(errno);
 13369             goto err;
 13369 	    goto err;
 13370         }
 13370 	}
 13371     }
 13371     }
 13372     RETURN (__mkSmallInteger(n));
 13372     RETURN (__mkSmallInteger(n));
 13373 #endif
 13373 #endif
 13374 err: ;
 13374 err: ;
 13375 %}.
 13375 %}.
 13395     char *cp;
 13395     char *cp;
 13396     int __flags;
 13396     int __flags;
 13397     int offs, __startIndex, __maxBytes;
 13397     int offs, __startIndex, __maxBytes;
 13398 
 13398 
 13399     if (!__isSmallInteger(__INST(fd))) {
 13399     if (!__isSmallInteger(__INST(fd))) {
 13400         error = @symbol(badFd);
 13400 	error = @symbol(badFd);
 13401         goto err;
 13401 	goto err;
 13402     }
 13402     }
 13403     if (!__isSmallInteger(startIndex) ||
 13403     if (!__isSmallInteger(startIndex) ||
 13404         (__startIndex = __intVal(startIndex)-1) < 0) {
 13404 	(__startIndex = __intVal(startIndex)-1) < 0) {
 13405         if (startIndex == nil) {
 13405 	if (startIndex == nil) {
 13406             __startIndex = 0;
 13406 	    __startIndex = 0;
 13407         } else {
 13407 	} else {
 13408             error = @symbol(badArgument3);
 13408 	    error = @symbol(badArgument3);
 13409             goto err;
 13409 	    goto err;
 13410         }
 13410 	}
 13411     }
 13411     }
 13412     if (__isSmallInteger(maxBytes)) {
 13412     if (__isSmallInteger(maxBytes)) {
 13413         __maxBytes = __intVal(maxBytes);
 13413 	__maxBytes = __intVal(maxBytes);
 13414     } else if (maxBytes == nil) {
 13414     } else if (maxBytes == nil) {
 13415         __maxBytes = -1;
 13415 	__maxBytes = -1;
 13416     } else {
 13416     } else {
 13417         error = @symbol(badArgument4);
 13417 	error = @symbol(badArgument4);
 13418         goto err;
 13418 	goto err;
 13419     }
 13419     }
 13420     if (!__isInteger(flags)) {
 13420     if (!__isInteger(flags)) {
 13421         error = @symbol(badArgument5);
 13421 	error = @symbol(badArgument5);
 13422         goto err;
 13422 	goto err;
 13423     }
 13423     }
 13424     __flags = __longIntVal(flags);
 13424     __flags = __longIntVal(flags);
 13425     sock = __smallIntegerVal(__INST(fd));
 13425     sock = __smallIntegerVal(__INST(fd));
 13426 
 13426 
 13427     oClass = __Class(aDataBuffer);
 13427     oClass = __Class(aDataBuffer);
 13428     switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 13428     switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
 13429         case BYTEARRAY:
 13429 	case BYTEARRAY:
 13430             offs = __startIndex;
 13430 	    offs = __startIndex;
 13431             break;
 13431 	    break;
 13432         case WORDARRAY:
 13432 	case WORDARRAY:
 13433         case SWORDARRAY:
 13433 	case SWORDARRAY:
 13434             offs = __startIndex * 2;
 13434 	    offs = __startIndex * 2;
 13435             break;
 13435 	    break;
 13436         case LONGARRAY:
 13436 	case LONGARRAY:
 13437         case SLONGARRAY:
 13437 	case SLONGARRAY:
 13438             offs = __startIndex * 4;
 13438 	    offs = __startIndex * 4;
 13439             break;
 13439 	    break;
 13440         case LONGLONGARRAY:
 13440 	case LONGLONGARRAY:
 13441         case SLONGLONGARRAY:
 13441 	case SLONGLONGARRAY:
 13442             offs = __startIndex * 8;
 13442 	    offs = __startIndex * 8;
 13443 # ifdef __NEED_LONGLONG_ALIGN
 13443 # ifdef __NEED_LONGLONG_ALIGN
 13444             offs += 4;
 13444 	    offs += 4;
 13445 # endif
 13445 # endif
 13446             break;
 13446 	    break;
 13447         case FLOATARRAY:
 13447 	case FLOATARRAY:
 13448             offs = __startIndex * sizeof(float);
 13448 	    offs = __startIndex * sizeof(float);
 13449             break;
 13449 	    break;
 13450         case DOUBLEARRAY:
 13450 	case DOUBLEARRAY:
 13451             offs = __startIndex * sizeof(double);
 13451 	    offs = __startIndex * sizeof(double);
 13452 # ifdef __NEED_DOUBLE_ALIGN
 13452 # ifdef __NEED_DOUBLE_ALIGN
 13453             offs += 4;
 13453 	    offs += 4;
 13454 # endif
 13454 # endif
 13455             break;
 13455 	    break;
 13456         default:
 13456 	default:
 13457             error = @symbol(badArgument2);
 13457 	    error = @symbol(badArgument2);
 13458             goto err;
 13458 	    goto err;
 13459     }
 13459     }
 13460 
 13460 
 13461     nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
 13461     nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
 13462     nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
 13462     nInstBytes = OHDR_SIZE + nInstVars * sizeof(OBJ);
 13463     objSize = __qSize(aDataBuffer) - nInstBytes - offs;
 13463     objSize = __qSize(aDataBuffer) - nInstBytes - offs;
 13464 
 13464 
 13465     if (__maxBytes >= 0 && __maxBytes < objSize) {
 13465     if (__maxBytes >= 0 && __maxBytes < objSize) {
 13466 # ifdef DGRAM_DEBUG
 13466 # ifdef DGRAM_DEBUG
 13467         printf("cut off ...\n");
 13467 	printf("cut off ...\n");
 13468 # endif
 13468 # endif
 13469         objSize = __maxBytes;
 13469 	objSize = __maxBytes;
 13470     }
 13470     }
 13471 
 13471 
 13472     if (socketAddress == nil) {
 13472     if (socketAddress == nil) {
 13473         alen = 0;
 13473 	alen = 0;
 13474     } else {
 13474     } else {
 13475         if (! __isByteArrayLike(socketAddress)) {
 13475 	if (! __isByteArrayLike(socketAddress)) {
 13476             error = @symbol(badArgument1);
 13476 	    error = @symbol(badArgument1);
 13477             goto err;
 13477 	    goto err;
 13478         }
 13478 	}
 13479         alen = __byteArraySize(socketAddress);
 13479 	alen = __byteArraySize(socketAddress);
 13480     }
 13480     }
 13481     saPtr = (struct sockaddr *)0;
 13481     saPtr = (struct sockaddr *)0;
 13482 
 13482 
 13483 again:
 13483 again:
 13484     if (alen)
 13484     if (alen)
 13485         saPtr = (struct sockaddr *)__byteArrayVal(socketAddress);
 13485 	saPtr = (struct sockaddr *)__byteArrayVal(socketAddress);
 13486     cp = (char *)__InstPtr(aDataBuffer) + nInstBytes + offs;
 13486     cp = (char *)__InstPtr(aDataBuffer) + nInstBytes + offs;
 13487     n = sendto(sock, cp, objSize, __flags, saPtr, alen);
 13487     n = sendto(sock, cp, objSize, __flags, saPtr, alen);
 13488     if (n < 0) {
 13488     if (n < 0) {
 13489         if (errno == EINTR) {
 13489 	if (errno == EINTR) {
 13490             __HANDLE_INTERRUPTS__;
 13490 	    __HANDLE_INTERRUPTS__;
 13491             goto again;
 13491 	    goto again;
 13492         } else {
 13492 	} else {
 13493             error = __mkSmallInteger(errno);
 13493 	    error = __mkSmallInteger(errno);
 13494             goto err;
 13494 	    goto err;
 13495         }
 13495 	}
 13496     }
 13496     }
 13497     RETURN (__mkSmallInteger(n));
 13497     RETURN (__mkSmallInteger(n));
 13498 #endif
 13498 #endif
 13499 err: ;
 13499 err: ;
 13500 %}.
 13500 %}.
 13515     |error domainCode typeCode protocolNumber|
 13515     |error domainCode typeCode protocolNumber|
 13516 
 13516 
 13517     domainCode := OperatingSystem domainCodeOf:domainArg.
 13517     domainCode := OperatingSystem domainCodeOf:domainArg.
 13518     typeCode := OperatingSystem socketTypeCodeOf:typeArg.
 13518     typeCode := OperatingSystem socketTypeCodeOf:typeArg.
 13519     protocolArg notNil ifTrue:[
 13519     protocolArg notNil ifTrue:[
 13520         protocolNumber := self class protocolCodeOf:protocolArg
 13520 	protocolNumber := self class protocolCodeOf:protocolArg
 13521     ].
 13521     ].
 13522 
 13522 
 13523 %{
 13523 %{
 13524 #if 0 && !defined(NO_SOCKET)
 13524 #if 0 && !defined(NO_SOCKET)
 13525     int dom, typ, proto = 0, sock, ret;
 13525     int dom, typ, proto = 0, sock, ret;
 13526     int on = 1;
 13526     int on = 1;
 13527 
 13527 
 13528     if (__INST(fd) != nil) {
 13528     if (__INST(fd) != nil) {
 13529         error = @symbol(internalError);
 13529 	error = @symbol(internalError);
 13530         goto err;
 13530 	goto err;
 13531     }
 13531     }
 13532     if (! __isSmallInteger(domainCode)) {
 13532     if (! __isSmallInteger(domainCode)) {
 13533         error = @symbol(badArgument1);
 13533 	error = @symbol(badArgument1);
 13534         goto err;
 13534 	goto err;
 13535     }
 13535     }
 13536     if (! __isSmallInteger(typeArg)) {
 13536     if (! __isSmallInteger(typeArg)) {
 13537         error = @symbol(badArgument2);
 13537 	error = @symbol(badArgument2);
 13538         goto err;
 13538 	goto err;
 13539     }
 13539     }
 13540     if (protocolNumber != nil) {
 13540     if (protocolNumber != nil) {
 13541         if (!__isSmallInteger(protocolNumber)) {
 13541 	if (!__isSmallInteger(protocolNumber)) {
 13542             error = @symbol(badArgument3);
 13542 	    error = @symbol(badArgument3);
 13543             goto err;
 13543 	    goto err;
 13544         }
 13544 	}
 13545         proto = __smallIntegerVal(protocolNumber);
 13545 	proto = __smallIntegerVal(protocolNumber);
 13546     }
 13546     }
 13547     dom = __smallIntegerVal(domainCode);
 13547     dom = __smallIntegerVal(domainCode);
 13548 
 13548 
 13549     /*
 13549     /*
 13550      * get socket-type and protocol-type
 13550      * get socket-type and protocol-type
 13552     typ = __intVal(typeArg);
 13552     typ = __intVal(typeArg);
 13553 
 13553 
 13554 againSocket:
 13554 againSocket:
 13555     sock = socket(dom, typ, proto);
 13555     sock = socket(dom, typ, proto);
 13556     if (sock < 0) {
 13556     if (sock < 0) {
 13557         if (errno == EINTR) {
 13557 	if (errno == EINTR) {
 13558             __HANDLE_INTERRUPTS__;
 13558 	    __HANDLE_INTERRUPTS__;
 13559             goto againSocket;
 13559 	    goto againSocket;
 13560         } else
 13560 	} else
 13561 # if defined(EPROTONOSUPPORT) /* for SGI */
 13561 # if defined(EPROTONOSUPPORT) /* for SGI */
 13562         if (errno == EPROTONOSUPPORT && proto != 0) {
 13562 	if (errno == EPROTONOSUPPORT && proto != 0) {
 13563             proto = 0;
 13563 	    proto = 0;
 13564             goto againSocket;
 13564 	    goto againSocket;
 13565         } else
 13565 	} else
 13566 # endif
 13566 # endif
 13567         {
 13567 	{
 13568             error = __mkSmallInteger(errno);
 13568 	    error = __mkSmallInteger(errno);
 13569             goto err;
 13569 	    goto err;
 13570         }
 13570 	}
 13571     }
 13571     }
 13572     __INST(fd) = __mkSmallInteger(sock);
 13572     __INST(fd) = __mkSmallInteger(sock);
 13573 
 13573 
 13574 err:;
 13574 err:;
 13575 # else /* NOSOCKET */
 13575 # else /* NOSOCKET */
 13576     error = @symbol(notImplemented);
 13576     error = @symbol(notImplemented);
 13577 # endif /* NOSOCKET */
 13577 # endif /* NOSOCKET */
 13578 %}.
 13578 %}.
 13579     error notNil ifTrue:[
 13579     error notNil ifTrue:[
 13580         ^ self error:error.
 13580 	^ self error:error.
 13581     ].
 13581     ].
 13582     self register.
 13582     self register.
 13583 
 13583 
 13584     "
 13584     "
 13585      self new domain:#inet type:#stream protocol:nil
 13585      self new domain:#inet type:#stream protocol:nil
 13601     int sock;
 13601     int sock;
 13602     int intval, sz;
 13602     int intval, sz;
 13603     char *p;
 13603     char *p;
 13604 
 13604 
 13605     if (!__isSmallInteger(__INST(fd))) {
 13605     if (!__isSmallInteger(__INST(fd))) {
 13606         error = @symbol(badFd);
 13606 	error = @symbol(badFd);
 13607         goto err;
 13607 	goto err;
 13608     }
 13608     }
 13609     if (!__bothSmallInteger(level, name)) {
 13609     if (!__bothSmallInteger(level, name)) {
 13610         error = @symbol(badArgument);
 13610 	error = @symbol(badArgument);
 13611         goto err;
 13611 	goto err;
 13612     }
 13612     }
 13613     if (!__isByteArray(bytes)) {
 13613     if (!__isByteArray(bytes)) {
 13614         error = @symbol(internalError);
 13614 	error = @symbol(internalError);
 13615         goto err;
 13615 	goto err;
 13616     }
 13616     }
 13617     p = __byteArrayVal(bytes);
 13617     p = __byteArrayVal(bytes);
 13618     sz = __byteArraySize(bytes);
 13618     sz = __byteArraySize(bytes);
 13619 
 13619 
 13620     sock = __smallIntegerVal(__INST(fd));
 13620     sock = __smallIntegerVal(__INST(fd));
 13621     if (getsockopt(sock, __smallIntegerVal(level), __smallIntegerVal(name), p, &sz) < 0) {
 13621     if (getsockopt(sock, __smallIntegerVal(level), __smallIntegerVal(name), p, &sz) < 0) {
 13622         error = __mkSmallInteger(errno);
 13622 	error = __mkSmallInteger(errno);
 13623     }
 13623     }
 13624     size = __mkSmallInteger(sz);
 13624     size = __mkSmallInteger(sz);
 13625 
 13625 
 13626 err:;
 13626 err:;
 13627 #endif
 13627 #endif
 13628 %}.
 13628 %}.
 13629     error notNil ifTrue:[
 13629     error notNil ifTrue:[
 13630         ^ self error:error
 13630 	^ self error:error
 13631     ].
 13631     ].
 13632     ^ bytes copyTo:size
 13632     ^ bytes copyTo:size
 13633 !
 13633 !
 13634 
 13634 
 13635 listenFor:aNumber
 13635 listenFor:aNumber
 13642 %{
 13642 %{
 13643 #if 0 && !defined(NO_SOCKET)
 13643 #if 0 && !defined(NO_SOCKET)
 13644     int sock, ret;
 13644     int sock, ret;
 13645 
 13645 
 13646     if (!__isSmallInteger(__INST(fd))) {
 13646     if (!__isSmallInteger(__INST(fd))) {
 13647         error = @symbol(badFd);
 13647 	error = @symbol(badFd);
 13648         goto err;
 13648 	goto err;
 13649     }
 13649     }
 13650     if (!__isSmallInteger(aNumber)) {
 13650     if (!__isSmallInteger(aNumber)) {
 13651         error = @symbol(badArgument1);
 13651 	error = @symbol(badArgument1);
 13652         goto err;
 13652 	goto err;
 13653     }
 13653     }
 13654 
 13654 
 13655     sock = __smallIntegerVal(__INST(fd));
 13655     sock = __smallIntegerVal(__INST(fd));
 13656 
 13656 
 13657 again:
 13657 again:
 13658     ret = listen(sock, __smallIntegerVal(aNumber));
 13658     ret = listen(sock, __smallIntegerVal(aNumber));
 13659     if (ret < 0) {
 13659     if (ret < 0) {
 13660         if (errno == EINTR) {
 13660 	if (errno == EINTR) {
 13661             __HANDLE_INTERRUPTS__;
 13661 	    __HANDLE_INTERRUPTS__;
 13662             goto again;
 13662 	    goto again;
 13663         } else {
 13663 	} else {
 13664             error = __mkSmallInteger(errno);
 13664 	    error = __mkSmallInteger(errno);
 13665         }
 13665 	}
 13666     }
 13666     }
 13667 
 13667 
 13668 err:;
 13668 err:;
 13669 #endif
 13669 #endif
 13670 %}.
 13670 %}.
 13671     error notNil ifTrue:[
 13671     error notNil ifTrue:[
 13672         ^ self error:error.
 13672 	^ self error:error.
 13673     ].
 13673     ].
 13674     ^ nil
 13674     ^ nil
 13675 !
 13675 !
 13676 
 13676 
 13677 setOptionsLevel:level name:name value:value
 13677 setOptionsLevel:level name:name value:value
 13685     int sock;
 13685     int sock;
 13686     int __level, __name, intval, sz;
 13686     int __level, __name, intval, sz;
 13687     char *p;
 13687     char *p;
 13688 
 13688 
 13689     if (!__isSmallInteger(__INST(fd))) {
 13689     if (!__isSmallInteger(__INST(fd))) {
 13690         error = @symbol(badFd);
 13690 	error = @symbol(badFd);
 13691         goto err;
 13691 	goto err;
 13692     }
 13692     }
 13693     if (__isSmallInteger(level)) {
 13693     if (__isSmallInteger(level)) {
 13694         __level = __smallIntegerVal(level);
 13694 	__level = __smallIntegerVal(level);
 13695     } else if (level == @symbol(SOL_SOCKET)) {
 13695     } else if (level == @symbol(SOL_SOCKET)) {
 13696         __level = SOL_SOCKET;
 13696 	__level = SOL_SOCKET;
 13697     } else {
 13697     } else {
 13698         error = @symbol(badArgument1);
 13698 	error = @symbol(badArgument1);
 13699         goto err;
 13699 	goto err;
 13700     }
 13700     }
 13701 
 13701 
 13702     if (__isSmallInteger(name)) {
 13702     if (__isSmallInteger(name)) {
 13703         __name = __smallIntegerVal(name);
 13703 	__name = __smallIntegerVal(name);
 13704     } else if (name == @symbol(SO_REUSEADDR)) {
 13704     } else if (name == @symbol(SO_REUSEADDR)) {
 13705         __name = SO_REUSEADDR;
 13705 	__name = SO_REUSEADDR;
 13706     } else {
 13706     } else {
 13707         error = @symbol(badArgument2);
 13707 	error = @symbol(badArgument2);
 13708         goto err;
 13708 	goto err;
 13709     }
 13709     }
 13710 
 13710 
 13711     if (__isSmallInteger(value)) {
 13711     if (__isSmallInteger(value)) {
 13712         intval = __intVal(value);
 13712 	intval = __intVal(value);
 13713         p = (char *) &intval;
 13713 	p = (char *) &intval;
 13714         sz = sizeof(intval);
 13714 	sz = sizeof(intval);
 13715     } else if (__isByteArrayLike(value)) {
 13715     } else if (__isByteArrayLike(value)) {
 13716         p = __byteArrayVal(value);
 13716 	p = __byteArrayVal(value);
 13717         sz = __byteArraySize(value);
 13717 	sz = __byteArraySize(value);
 13718     } else {
 13718     } else {
 13719         error = @symbol(badArgument3);
 13719 	error = @symbol(badArgument3);
 13720         goto err;
 13720 	goto err;
 13721     }
 13721     }
 13722 
 13722 
 13723     sock = __smallIntegerVal(__INST(fd));
 13723     sock = __smallIntegerVal(__INST(fd));
 13724     if (setsockopt(sock, __level, __name, p, sz) < 0) {
 13724     if (setsockopt(sock, __level, __name, p, sz) < 0) {
 13725         error = __mkSmallInteger(errno);
 13725 	error = __mkSmallInteger(errno);
 13726     }
 13726     }
 13727 err:;
 13727 err:;
 13728 #endif
 13728 #endif
 13729 %}.
 13729 %}.
 13730     error notNil ifTrue:[
 13730     error notNil ifTrue:[
 13731         ^ self error:error
 13731 	^ self error:error
 13732     ].
 13732     ].
 13733     ^ nil.
 13733     ^ nil.
 13734 !
 13734 !
 13735 
 13735 
 13736 shutdown:anInteger
 13736 shutdown:anInteger
 13737     "inform the socket that no more I/O will happen.
 13737     "inform the socket that no more I/O will happen.
 13738      anInteger == 0   no reads will be performed
 13738      anInteger == 0   no reads will be performed
 13739      anInteger == 1   no writes will be performed
 13739      anInteger == 1   no writes will be performed
 13740      anInteger == 2   neither reads nor writes will be performed.
 13740      anInteger == 2   neither reads nor writes will be performed.
 13741                       Pending data is discarded. This is faster tha
 13741 		      Pending data is discarded. This is faster tha
 13742                       close, which may wait until pending (written)
 13742 		      close, which may wait until pending (written)
 13743                       data has been read by the other side"
 13743 		      data has been read by the other side"
 13744 
 13744 
 13745     |error|
 13745     |error|
 13746 
 13746 
 13747 %{
 13747 %{
 13748 #if 0 && !defined(NO_SOCKET)
 13748 #if 0 && !defined(NO_SOCKET)
 13749     int ret;
 13749     int ret;
 13750 
 13750 
 13751     if (!__isSmallInteger(__INST(fd))) {
 13751     if (!__isSmallInteger(__INST(fd))) {
 13752         error = @symbol(badFd);
 13752 	error = @symbol(badFd);
 13753         goto err;
 13753 	goto err;
 13754     }
 13754     }
 13755     if (!__isSmallInteger(anInteger)) {
 13755     if (!__isSmallInteger(anInteger)) {
 13756         error = @symbol(badArgument1);
 13756 	error = @symbol(badArgument1);
 13757         goto err;
 13757 	goto err;
 13758     }
 13758     }
 13759 
 13759 
 13760 again:
 13760 again:
 13761     ret = shutdown(__smallIntegerVal(__INST(fd)), __smallIntegerVal(anInteger));
 13761     ret = shutdown(__smallIntegerVal(__INST(fd)), __smallIntegerVal(anInteger));
 13762     if (ret < 0) {
 13762     if (ret < 0) {
 13763         if (errno == EINTR) {
 13763 	if (errno == EINTR) {
 13764             __HANDLE_INTERRUPTS__;
 13764 	    __HANDLE_INTERRUPTS__;
 13765             goto again;
 13765 	    goto again;
 13766         } else {
 13766 	} else {
 13767             error = __mkSmallInteger(errno);
 13767 	    error = __mkSmallInteger(errno);
 13768         }
 13768 	}
 13769     }
 13769     }
 13770 
 13770 
 13771 err:;
 13771 err:;
 13772 #endif /*NO_SOCKET*/
 13772 #endif /*NO_SOCKET*/
 13773 %}.
 13773 %}.
 13774     error notNil ifTrue:[
 13774     error notNil ifTrue:[
 13775         ^ self error:error
 13775 	^ self error:error
 13776     ].
 13776     ].
 13777     ^ nil.
 13777     ^ nil.
 13778 ! !
 13778 ! !
 13779 
 13779 
 13780 !UnixOperatingSystem::SocketHandle methodsFor:'queries'!
 13780 !UnixOperatingSystem::SocketHandle methodsFor:'queries'!
 13790     int sock;
 13790     int sock;
 13791     int sockaddr_size;
 13791     int sockaddr_size;
 13792     int ret;
 13792     int ret;
 13793 
 13793 
 13794     if (!__isSmallInteger(__INST(fd))) {
 13794     if (!__isSmallInteger(__INST(fd))) {
 13795         error = @symbol(badFd);
 13795 	error = @symbol(badFd);
 13796         goto err;
 13796 	goto err;
 13797     }
 13797     }
 13798     if (!__isNonNilObject(socketAddress) ||
 13798     if (!__isNonNilObject(socketAddress) ||
 13799         (__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13799 	(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13800         error = @symbol(badArgument1);
 13800 	error = @symbol(badArgument1);
 13801         goto err;
 13801 	goto err;
 13802     }
 13802     }
 13803     sockaddr_size = __byteArraySize(socketAddress);
 13803     sockaddr_size = __byteArraySize(socketAddress);
 13804 
 13804 
 13805     sock = __smallIntegerVal(__INST(fd));
 13805     sock = __smallIntegerVal(__INST(fd));
 13806     ret = getsockname(sock, (struct sockaddr *)__byteArrayVal(socketAddress), &sockaddr_size);
 13806     ret = getsockname(sock, (struct sockaddr *)__byteArrayVal(socketAddress), &sockaddr_size);
 13807     if (ret < 0) {
 13807     if (ret < 0) {
 13808         error = __mkSmallInteger(errno);
 13808 	error = __mkSmallInteger(errno);
 13809     }
 13809     }
 13810 err:;
 13810 err:;
 13811 #endif /* NO_SOCKET */
 13811 #endif /* NO_SOCKET */
 13812 %}.
 13812 %}.
 13813     error notNil ifTrue:[
 13813     error notNil ifTrue:[
 13814         ^ self error:error
 13814 	^ self error:error
 13815     ].
 13815     ].
 13816     ^ nil.
 13816     ^ nil.
 13817 !
 13817 !
 13818 
 13818 
 13819 getPeerInto:socketAddress
 13819 getPeerInto:socketAddress
 13827     int __sock;
 13827     int __sock;
 13828     int __sockaddr_size;
 13828     int __sockaddr_size;
 13829     int __ret;
 13829     int __ret;
 13830 
 13830 
 13831     if (!__isSmallInteger(__INST(fd))) {
 13831     if (!__isSmallInteger(__INST(fd))) {
 13832         error = @symbol(badFd);
 13832 	error = @symbol(badFd);
 13833         goto err;
 13833 	goto err;
 13834     }
 13834     }
 13835     if (!__isNonNilObject(socketAddress) ||
 13835     if (!__isNonNilObject(socketAddress) ||
 13836         (__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13836 	(__intVal(__ClassInstPtr(__qClass(socketAddress))->c_flags) & ARRAYMASK) != BYTEARRAY) {
 13837         error = @symbol(badArgument1);
 13837 	error = @symbol(badArgument1);
 13838         goto err;
 13838 	goto err;
 13839     }
 13839     }
 13840     __sockaddr_size = __byteArraySize(socketAddress);
 13840     __sockaddr_size = __byteArraySize(socketAddress);
 13841 
 13841 
 13842     __sock = __smallIntegerVal(__INST(fd));
 13842     __sock = __smallIntegerVal(__INST(fd));
 13843     __ret = getpeername(__sock, (struct sockaddr *)__byteArrayVal(socketAddress),
 13843     __ret = getpeername(__sock, (struct sockaddr *)__byteArrayVal(socketAddress),
 13844                                 &__sockaddr_size);
 13844 				&__sockaddr_size);
 13845     if (__ret < 0) {
 13845     if (__ret < 0) {
 13846         error = __mkSmallInteger(errno);
 13846 	error = __mkSmallInteger(errno);
 13847     }
 13847     }
 13848 err:;
 13848 err:;
 13849 #endif /* NO_SOCKET */
 13849 #endif /* NO_SOCKET */
 13850 %}.
 13850 %}.
 13851     error notNil ifTrue:[
 13851     error notNil ifTrue:[
 13852         ^ self error:error
 13852 	^ self error:error
 13853     ].
 13853     ].
 13854     ^ nil
 13854     ^ nil
 13855 ! !
 13855 ! !
 13856 
 13856 
 13857 !UnixOperatingSystem class methodsFor:'documentation'!
 13857 !UnixOperatingSystem class methodsFor:'documentation'!
 13858 
 13858 
 13859 version
 13859 version
 13860     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.422 2015-03-02 23:12:12 stefan Exp $'
 13860     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.423 2015-03-09 17:46:04 cg Exp $'
 13861 !
 13861 !
 13862 
 13862 
 13863 version_CVS
 13863 version_CVS
 13864     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.422 2015-03-02 23:12:12 stefan Exp $'
 13864     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.423 2015-03-09 17:46:04 cg Exp $'
 13865 ! !
 13865 ! !
 13866 
 13866 
 13867 
 13867 
 13868 UnixOperatingSystem initialize!
 13868 UnixOperatingSystem initialize!
 13869 UnixOperatingSystem::FileDescriptorHandle initialize!
 13869 UnixOperatingSystem::FileDescriptorHandle initialize!