UnixOperatingSystem.st
changeset 3780 7d735472f937
parent 3773 54dd6a5fd72a
child 3793 aff27e755ffd
equal deleted inserted replaced
3779:6409bc73ce3c 3780:7d735472f937
  4927 !
  4927 !
  4928 
  4928 
  4929 primIdOf:aPathName
  4929 primIdOf:aPathName
  4930     "the actual code to return the fileNumber (i.e. inode number) of a file."
  4930     "the actual code to return the fileNumber (i.e. inode number) of a file."
  4931 
  4931 
  4932 %{  /* UNLIMITEDSTACK(WIN32) */
  4932 %{
  4933     struct stat buf;
  4933     struct stat buf;
  4934     int ret;
  4934     int ret;
  4935     unsigned INT ino;
  4935     unsigned INT ino;
  4936     OBJ retVal;
  4936     OBJ retVal;
  4937 
  4937 
  5010     "could be implemented as:
  5010     "could be implemented as:
  5011 	(self infoOf:aPathName) accessed 
  5011 	(self infoOf:aPathName) accessed 
  5012     "
  5012     "
  5013     |osSeconds i|
  5013     |osSeconds i|
  5014 %{
  5014 %{
  5015 #if !defined(WIN32) && !defined(__VMS__)
       
  5016     struct stat buf;
  5015     struct stat buf;
  5017     time_t mtime;
  5016     time_t mtime;
  5018     int ret;
  5017     int ret;
  5019 
  5018 
  5020     if (__isString(aPathName)) {
  5019     if (__isString(aPathName)) {
  5030 	    @global(LastErrorNumber) = __MKSMALLINT(errno);
  5029 	    @global(LastErrorNumber) = __MKSMALLINT(errno);
  5031 	    RETURN (nil);
  5030 	    RETURN (nil);
  5032 	}
  5031 	}
  5033 	osSeconds = __MKUINT(buf.st_atime);
  5032 	osSeconds = __MKUINT(buf.st_atime);
  5034     }
  5033     }
  5035 #endif
       
  5036 %}.
  5034 %}.
  5037     osSeconds notNil ifTrue:[^ AbsoluteTime fromOSTime:(osSeconds * 1000)].
  5035     osSeconds notNil ifTrue:[^ AbsoluteTime fromOSTime:(osSeconds * 1000)].
  5038 
  5036 
  5039     i := self infoOf:aPathName.
  5037     i := self infoOf:aPathName.
  5040     i notNil ifTrue:[^ i accessed].
  5038     i notNil ifTrue:[^ i accessed].
  5295     dt.it_value.tv_sec = 0;
  5293     dt.it_value.tv_sec = 0;
  5296     dt.it_value.tv_usec = 0;
  5294     dt.it_value.tv_usec = 0;
  5297     setitimer(ITIMER_REAL, &dt, 0);
  5295     setitimer(ITIMER_REAL, &dt, 0);
  5298     RETURN (true);
  5296     RETURN (true);
  5299 #else
  5297 #else
  5300 # if defined(WIN32)
       
  5301     extern void __win32ClearTimer();
       
  5302 
       
  5303     __win32ClearTimer();
       
  5304     RETURN (true);
       
  5305 # endif /* WIN32 */
       
  5306 
       
  5307 # if defined(__VMS__) && defined(USE_AST_TIMER)
       
  5308     extern void __vmsClearTimer();
       
  5309 
       
  5310     __vmsClearTimer();
       
  5311     RETURN (true);
       
  5312 # endif /* __VMS__ */
       
  5313 
  5298 
  5314 # if defined(USE_SLOW_ALARM)
  5299 # if defined(USE_SLOW_ALARM)
  5315 #  if defined(SIGALRM)
  5300 #  if defined(SIGALRM)
  5316     alarm(0);
  5301     alarm(0);
  5317     RETURN (true);
  5302     RETURN (true);
  5562 	    case SIGINT:
  5547 	    case SIGINT:
  5563 #endif
  5548 #endif
  5564 #ifdef SIGQUIT
  5549 #ifdef SIGQUIT
  5565 	    case SIGQUIT:
  5550 	    case SIGQUIT:
  5566 #endif
  5551 #endif
  5567 #  ifdef WIN32
  5552 #if defined(SIGINT) || defined(SIGQUIT) || defined(SIGBREAK)
  5568 #ifdef PROCESSDEBUGWIN32
       
  5569 		printf("ConsoleSignal %d\n",sigNr);
       
  5570 #endif
       
  5571 		SetConsoleCtrlHandler((PHANDLER_ROUTINE)__signalUserInterruptWIN32,TRUE);
       
  5572 		RETURN (self);
       
  5573 #else
       
  5574 # if defined(SIGINT) || defined(SIGQUIT) || defined(SIGBREAK)
       
  5575 		handler = __signalUserInterrupt;
  5553 		handler = __signalUserInterrupt;
  5576 		break;
  5554 		break;
  5577 # endif
       
  5578 #endif
  5555 #endif
  5579 #ifdef SIGFPE
  5556 #ifdef SIGFPE
  5580 	    case SIGFPE:
  5557 	    case SIGFPE:
  5581 		handler = __signalFpExceptionInterrupt;
  5558 		handler = __signalFpExceptionInterrupt;
  5582 		break;
  5559 		break;
  5617 	    case CHILD_SIGNAL:
  5594 	    case CHILD_SIGNAL:
  5618 		handler = __signalChildInterrupt;
  5595 		handler = __signalChildInterrupt;
  5619 		break;
  5596 		break;
  5620 #endif
  5597 #endif
  5621 #ifdef SIGALRM
  5598 #ifdef SIGALRM
  5622 # ifndef WIN32
       
  5623 	    case SIGALRM:
  5599 	    case SIGALRM:
  5624 		handler = __signalTimerInterrupt;
  5600 		handler = __signalTimerInterrupt;
  5625 		break;
  5601 		break;
  5626 # endif
       
  5627 #endif
  5602 #endif
  5628 
  5603 
  5629 	    default:
  5604 	    default:
  5630 		handler = __signalInterrupt;
  5605 		handler = __signalInterrupt;
  5631 		break;
  5606 		break;
  5653 	    vec.sv_flags = SV_INTERRUPT;
  5628 	    vec.sv_flags = SV_INTERRUPT;
  5654 	    sigemptyset(&vec.sv_mask);
  5629 	    sigemptyset(&vec.sv_mask);
  5655 	    vec.sv_handler = handler;
  5630 	    vec.sv_handler = handler;
  5656 	    sigvec(sigNr, &vec, NULL);
  5631 	    sigvec(sigNr, &vec, NULL);
  5657 # else
  5632 # else
  5658 #  ifdef WIN32
       
  5659 #ifdef PROCESSDEBUGWIN32
       
  5660 	    printf("signal %d can't change handler\n",sigNr);
       
  5661 #endif
       
  5662 #  else
       
  5663 	    (void) signal(sigNr, handler);
  5633 	    (void) signal(sigNr, handler);
  5664 #  endif
       
  5665 # endif
  5634 # endif
  5666 #endif
  5635 #endif
  5667 	}
  5636 	}
  5668 
  5637 
  5669 	/*
  5638 	/*
  5732 	dt.it_value.tv_usec = (millis % 1000) * 1000;  
  5701 	dt.it_value.tv_usec = (millis % 1000) * 1000;  
  5733 	setitimer(ITIMER_REAL, &dt, 0);
  5702 	setitimer(ITIMER_REAL, &dt, 0);
  5734 	RETURN (true);
  5703 	RETURN (true);
  5735     }
  5704     }
  5736 #else /* no ITIMER_REAL */
  5705 #else /* no ITIMER_REAL */
  5737 # ifdef WIN32
       
  5738     {
       
  5739 	extern void __win32SetTimer();
       
  5740 
       
  5741 	__win32SetTimer(millis);
       
  5742 	RETURN (true);
       
  5743     }
       
  5744 # endif /* WIN32 */
       
  5745 
       
  5746 # if defined(__VMS__) && defined(USE_AST_TIMER)
       
  5747     {
       
  5748 	extern void __vmsSetTimer();
       
  5749 
       
  5750 	__vmsSetTimer(millis);
       
  5751 	RETURN (true);
       
  5752     }
       
  5753 # endif /* __VMS__ */
       
  5754 
  5706 
  5755 # ifdef USE_SLOW_ALARM
  5707 # ifdef USE_SLOW_ALARM
  5756     {
  5708     {
  5757 	/*
  5709 	/*
  5758 	 * last fallback - use alarm (which only gives 1 second resolution).
  5710 	 * last fallback - use alarm (which only gives 1 second resolution).
  5791 	      UnixOperatingSystem>>getStatusOfProcess:aProcessId."
  5743 	      UnixOperatingSystem>>getStatusOfProcess:aProcessId."
  5792 
  5744 
  5793     self sendSignal:(self sigKILL) to:(processGroupId negated).
  5745     self sendSignal:(self sigKILL) to:(processGroupId negated).
  5794 
  5746 
  5795     "Created: / 10.6.1998 / 11:59:29 / cg"
  5747     "Created: / 10.6.1998 / 11:59:29 / cg"
  5796 !
       
  5797 
       
  5798 primTerminateProcess:pid
       
  5799     "terminate a WIN32 process.
       
  5800     The TerminateProcess function is used to unconditionally cause
       
  5801     a process to exit. Use it only in extreme circumstances. The state of
       
  5802     global data maintained by dynamic-link libraries (DLLs)
       
  5803     may be compromised if TerminateProcess is used."
       
  5804 
       
  5805 %{  /* UNLIMITEDSTACK (WIN95 only)*/
       
  5806 #ifdef WIN32
       
  5807     if (__isExternalAddress(pid) )
       
  5808     {
       
  5809       if (_HANDLEVal(pid) != 0)
       
  5810       {
       
  5811 #ifdef PROCESSDEBUGWIN32
       
  5812 	 printf("Terminate ProcessHandle %x\n",_HANDLEVal(pid));
       
  5813 #endif
       
  5814 	 TerminateProcess(_HANDLEVal(pid),-1);
       
  5815 	 CloseHandle(_HANDLEVal(pid));
       
  5816 	 _HANDLEVal(pid) = 0;
       
  5817       }
       
  5818     }
       
  5819 
       
  5820 #endif
       
  5821 %}
       
  5822 !
  5748 !
  5823 
  5749 
  5824 sendSignal:signalNumber to:processId
  5750 sendSignal:signalNumber to:processId
  5825     "send a unix signal to some process (maybe myself).
  5751     "send a unix signal to some process (maybe myself).
  5826      Returns false if any error occurred, true otherwise.
  5752      Returns false if any error occurred, true otherwise.
  7782 #   define HAVE_TIME
  7708 #   define HAVE_TIME
  7783 #  endif /* old SYSV stuff */
  7709 #  endif /* old SYSV stuff */
  7784 # endif
  7710 # endif
  7785 
  7711 
  7786 # ifndef HAVE_TIME
  7712 # ifndef HAVE_TIME
  7787 #  ifdef WIN32
       
  7788     t = GetTickCount();
       
  7789     _seconds = t / 1000.
       
  7790     _millis = t % 1000;
       
  7791 #   define HAVE_TIME
       
  7792 #  endif
       
  7793 # endif
       
  7794 
       
  7795 # ifndef HAVE_TIME
       
  7796 #  ifdef MSDOS_LIKE
  7713 #  ifdef MSDOS_LIKE
  7797     struct _timeb timebuffer;
  7714     struct _timeb timebuffer;
  7798 
  7715 
  7799     _ftime(&timebuffer);
  7716     _ftime(&timebuffer);
  7800     _seconds = timebuffer.time;
  7717     _seconds = timebuffer.time;
  7877 
  7794 
  7878     ticks = times(&tb);
  7795     ticks = times(&tb);
  7879     t = (ticks * 1000) / HZ;
  7796     t = (ticks * 1000) / HZ;
  7880 #   define HAVE_TIME
  7797 #   define HAVE_TIME
  7881 #  endif /* old SYSV stuff */
  7798 #  endif /* old SYSV stuff */
  7882 # endif
       
  7883 
       
  7884 # ifndef HAVE_TIME
       
  7885 #  ifdef WIN32
       
  7886     t = GetTickCount();
       
  7887 #   define HAVE_TIME
       
  7888 #  endif
       
  7889 # endif
  7799 # endif
  7890 
  7800 
  7891 # ifndef HAVE_TIME
  7801 # ifndef HAVE_TIME
  7892 #  ifdef MSDOS_LIKE
  7802 #  ifdef MSDOS_LIKE
  7893     struct _timeb timebuffer;
  7803     struct _timeb timebuffer;
  8419      "return true, if childProcessWait: blocks, if no children are ready.
  8329      "return true, if childProcessWait: blocks, if no children are ready.
  8420       On those systems, we must be somewhat careful when looking out for
  8330       On those systems, we must be somewhat careful when looking out for
  8421       a subprocesses status (to avoid blocking)."
  8331       a subprocesses status (to avoid blocking)."
  8422 
  8332 
  8423 %{ /*NOCONTEXT*/
  8333 %{ /*NOCONTEXT*/
  8424 #if defined(HAS_WAITPID) || defined(HAS_WAIT3) || defined(WIN32) || defined(__VMS__)
  8334 #if defined(HAS_WAITPID) || defined(HAS_WAIT3)
  8425     RETURN(false);
  8335     RETURN(false);
  8426 #else
  8336 #else
  8427     RETURN(true);
  8337     RETURN(true);
  8428 #endif
  8338 #endif
  8429 %}
  8339 %}
  8558 %{
  8468 %{
  8559 #ifdef NOTDEF   /* does not work ... */
  8469 #ifdef NOTDEF   /* does not work ... */
  8560     /*
  8470     /*
  8561      * if available, try FIONREAD first, which is usually done faster.
  8471      * if available, try FIONREAD first, which is usually done faster.
  8562      */
  8472      */
  8563 # if defined(FIONREAD) && !defined(WIN32)
  8473 # if defined(FIONREAD)
  8564     {
  8474     {
  8565 	int n;
  8475 	int n;
  8566 
  8476 
  8567 	if (__isSmallInteger(fd)) {
  8477 	if (__isSmallInteger(fd)) {
  8568 	    if (ioctl(__intVal(fd), FIONREAD, &n) >= 0) {
  8478 	    if (ioctl(__intVal(fd), FIONREAD, &n) >= 0) {
  8584 %{
  8494 %{
  8585 #ifdef NOTDEF   /* does not work ... */
  8495 #ifdef NOTDEF   /* does not work ... */
  8586     /*
  8496     /*
  8587      * if available, try FIONREAD first, which is usually done faster.
  8497      * if available, try FIONREAD first, which is usually done faster.
  8588      */
  8498      */
  8589 # if defined(FIONREAD) && !defined(WIN32)
  8499 # if defined(FIONREAD)
  8590     {
  8500     {
  8591 	int n;
  8501 	int n;
  8592 
  8502 
  8593 	if (__isSmallInteger(fd)) {
  8503 	if (__isSmallInteger(fd)) {
  8594 	    if (n = ioctl(__intVal(fd), FIONREAD)) {
  8504 	    if (n = ioctl(__intVal(fd), FIONREAD)) {
  8734 	if (t == 0) {
  8644 	if (t == 0) {
  8735 	    /* 
  8645 	    /* 
  8736 	     * if there is no timeout time, we can stay here interruptable.
  8646 	     * if there is no timeout time, we can stay here interruptable.
  8737 	     */
  8647 	     */
  8738 	    do {
  8648 	    do {
  8739 # ifdef WIN32
       
  8740 		intf we;
       
  8741 
       
  8742 		if (numFds == 0) {
       
  8743 		    HANDLE dummyHandle = (HANDLE)0;
       
  8744 
       
  8745 #  if 0 /* does not work under WIN95 - sigh */
       
  8746 		    if (! GetQueueStatus(QS_ALLINPUT)) {
       
  8747 			MsgWaitForMultipleObjects(0, &dummyHandle, FALSE, t, QS_ALLINPUT);
       
  8748 		    }
       
  8749 #  else
       
  8750 		    if (we = __getWaitInputEvent()) {
       
  8751 			we(t);
       
  8752 		    }
       
  8753 #  endif
       
  8754 		    ret = 0;
       
  8755 		} else {
       
  8756 		    ret = select(0, &rset, &wset, &eset, &wt);
       
  8757 		}
       
  8758 # else /* a real OS */
       
  8759 		ret = select(maxF+1, &rset, &wset, &eset, &wt);
  8649 		ret = select(maxF+1, &rset, &wset, &eset, &wt);
  8760 # endif /* to WIN or not to WIN */
       
  8761 	    } while ((ret < 0) && (errno == EINTR));
  8650 	    } while ((ret < 0) && (errno == EINTR));
  8762 	} else {
  8651 	} else {
  8763 	    do {
  8652 	    do {
  8764 # ifdef WIN32
       
  8765 		intf we;
       
  8766 
       
  8767 		if (numFds == 0) {
       
  8768 		    HANDLE dummyHandle = (HANDLE)0;
       
  8769 #  if 0 /* does not work under WIN95 - sigh */
       
  8770 		    if (! GetQueueStatus(QS_ALLINPUT)) {
       
  8771 			MsgWaitForMultipleObjects(0, &dummyHandle, FALSE, t, QS_ALLINPUT);
       
  8772 		    }
       
  8773 #  else
       
  8774 		    if (we = __getWaitInputEvent()) {
       
  8775 			we(t);
       
  8776 		    }
       
  8777 #  endif
       
  8778 		    ret = 0;
       
  8779 		} else {
       
  8780 		    ret = select(0, &rset, &wset, &eset, &wt);
       
  8781 		}
       
  8782 # else /* a real OS */
       
  8783 		ret = select(maxF+1, &rset, &wset, &eset, &wt);
  8653 		ret = select(maxF+1, &rset, &wset, &eset, &wt);
  8784 # endif * to WIN or not to WIN */
       
  8785 		/* 
  8654 		/* 
  8786 		 * for now: dont loop; if we did, we had to adjust the vt-timeval;
  8655 		 * for now: dont loop; if we did, we had to adjust the vt-timeval;
  8787 		 * could otherwise stay in this loop forever ...
  8656 		 * could otherwise stay in this loop forever ...
  8788 		 * Premature return (before the time expired) must be handled by the caller.
  8657 		 * Premature return (before the time expired) must be handled by the caller.
  8789 		 * A good solution is to update the wt-timeval and redo the select.
  8658 		 * A good solution is to update the wt-timeval and redo the select.
  9150 ! !
  9019 ! !
  9151 
  9020 
  9152 !UnixOperatingSystem class methodsFor:'documentation'!
  9021 !UnixOperatingSystem class methodsFor:'documentation'!
  9153 
  9022 
  9154 version
  9023 version
  9155     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.37 1998-08-20 00:48:28 cg Exp $'
  9024     ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.38 1998-08-25 13:43:22 cg Exp $'
  9156 ! !
  9025 ! !
  9157 UnixOperatingSystem initialize!
  9026 UnixOperatingSystem initialize!