comparison src/nt.c @ 223:2c611d1463a6 r20-4b10

Import from CVS: tag r20-4b10
author cvs
date Mon, 13 Aug 2007 10:10:54 +0200
parents 78f53ef88e17
children 41f2f0e326e9
comparison
equal deleted inserted replaced
222:aae4c8b01452 223:2c611d1463a6
31 #include <io.h> 31 #include <io.h>
32 #include <errno.h> 32 #include <errno.h>
33 #include <fcntl.h> 33 #include <fcntl.h>
34 #include <ctype.h> 34 #include <ctype.h>
35 #include <signal.h> 35 #include <signal.h>
36 #include <sys/time.h>
37 36
38 /* must include CRT headers *before* config.h */ 37 /* must include CRT headers *before* config.h */
39 #include "config.h" 38 #include "config.h"
39 #include "systime.h"
40 #include "syssignal.h"
41
40 #undef access 42 #undef access
41 #undef chdir 43 #undef chdir
42 #undef chmod 44 #undef chmod
43 #undef creat 45 #undef creat
44 #undef ctime 46 #undef ctime
64 #undef getwd 66 #undef getwd
65 67
66 #include <pwd.h> 68 #include <pwd.h>
67 69
68 #include <windows.h> 70 #include <windows.h>
71 #include <mmsystem.h>
69 72
70 #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */ 73 #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
71 #include <sys/socket.h> 74 #include <sys/socket.h>
72 #undef socket 75 #undef socket
73 #undef bind 76 #undef bind
553 556
554 557
555 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */ 558 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
556 559
557 int 560 int
558 sigsetmask (int signal_mask)
559 {
560 return 0;
561 }
562
563 int
564 sigblock (int sig)
565 {
566 return 0;
567 }
568
569 int
570 setpgrp (int pid, int gid) 561 setpgrp (int pid, int gid)
571 { 562 {
572 return 0; 563 return 0;
573 } 564 }
574 565
575 int
576 alarm (int seconds)
577 {
578 return 0;
579 }
580 566
581 int 567 int
582 unrequest_sigio (void) 568 unrequest_sigio (void)
583 { 569 {
584 return 0; 570 return 0;
2802 { 2788 {
2803 return Vstdio_str; 2789 return Vstdio_str;
2804 } 2790 }
2805 #endif 2791 #endif
2806 2792
2793 /*--------------------------------------------------------------------*/
2794 /* Signal support */
2795 /*--------------------------------------------------------------------*/
2796
2797 /* We need MS-defined signal and raise here */
2798 #undef signal
2799 #undef raise
2800
2801 #define sigmask(nsig) (1U << nsig)
2802
2803 /* We can support as many signals as fit into word */
2804 #define SIG_MAX 32
2805
2806 /* Signal handlers. Initial value = 0 = SIG_DFL */
2807 static void (__cdecl *signal_handlers[SIG_MAX])(int) = {0};
2808
2809 /* Signal block mask: bit set to 1 means blocked */
2810 unsigned signal_block_mask = 0;
2811
2812 /* Signal pending mask: bit set to 1 means sig is pending */
2813 unsigned signal_pending_mask = 0;
2814
2815 msw_sighandler msw_sigset (int nsig, msw_sighandler handler)
2816 {
2817 /* We delegate some signals to the system function */
2818 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT)
2819 {
2820 signal (nsig, handler);
2821 return;
2822 }
2823
2824 if (nsig < 0 || nsig > SIG_MAX)
2825 {
2826 errno = EINVAL;
2827 return;
2828 }
2829
2830 /* Store handler ptr */
2831 signal_handlers[nsig] = handler;
2832 }
2833
2834 int msw_sighold (int nsig)
2835 {
2836 if (nsig < 0 || nsig > SIG_MAX)
2837 return errno = EINVAL;
2838
2839 signal_block_mask |= sigmask(nsig);
2840 return 0;
2841 }
2842
2843 int msw_sigrelse (int nsig)
2844 {
2845 if (nsig < 0 || nsig > SIG_MAX)
2846 return errno = EINVAL;
2847
2848 signal_block_mask &= ~sigmask(nsig);
2849
2850 if (signal_pending_mask & sigmask(nsig))
2851 msw_raise (nsig);
2852
2853 return 0;
2854 }
2855
2856 int msw_sigpause (int nsig)
2857 {
2858 /* This is currently not called, because the only
2859 call to sigpause inside XEmacs is with SIGCHLD
2860 parameter. Just in case, we put an assert here,
2861 so anyone who will add a call to sigpause will
2862 be surprised (or surprise someone else...) */
2863 assert (0);
2864 return 0;
2865 }
2866
2867 int msw_raise (int nsig)
2868 {
2869 /* We delegate some raises to the system routine */
2870 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT)
2871 return raise (nsig);
2872
2873 if (nsig < 0 || nsig > SIG_MAX)
2874 return errno = EINVAL;
2875
2876 /* If the signal is blocked, remember to issue later */
2877 if (signal_block_mask & sigmask(nsig))
2878 {
2879 signal_pending_mask |= sigmask(nsig);
2880 return 0;
2881 }
2882
2883 if (signal_handlers[nsig] == SIG_IGN)
2884 return 0;
2885
2886 if (signal_handlers[nsig] != SIG_DFL)
2887 {
2888 (*signal_handlers[nsig])(nsig);
2889 return 0;
2890 }
2891
2892 /* Default signal actions */
2893 if (nsig == SIGALRM || nsig == SIGPROF)
2894 exit (3);
2895
2896 /* Other signals are ignored by default */
2897 }
2898
2899 /*--------------------------------------------------------------------*/
2900 /* Async timers */
2901 /*--------------------------------------------------------------------*/
2902
2903 /* We emulate two timers, one for SIGALRM, another for SIGPROF.
2904
2905 itimerproc() function has an implementation limitation: it does
2906 not allow to set *both* interval and period. If an attempt is
2907 made to set both, and then they are unequal, the function
2908 asserts.
2909
2910 Minimum timer resolution on Win32 systems varies, and is greater
2911 than or equal than 1 ms. The resolution is always wrapped not to
2912 attempt to get below the system defined limit.
2913 */
2914
2915 /* Timer precision, denominator of one fraction: for 100 ms
2916 interval, request 10 ms precision
2917 */
2918 const int timer_prec = 10;
2919
2920 /* Last itimevals, as set by calls to setitimer */
2921 static struct itimerval it_alarm;
2922 static struct itimerval it_prof;
2923
2924 /* Timer IDs as returned by MM */
2925 MMRESULT tid_alarm = 0;
2926 MMRESULT tid_prof = 0;
2927
2928 static void CALLBACK timer_proc (UINT uID, UINT uMsg, DWORD dwUser,
2929 DWORD dw1, DWORD dw2)
2930 {
2931 /* Just raise a signal indicated by dwUser parameter */
2932 msw_raise (dwUser);
2933 }
2934
2935 /* Divide time in ms specified by IT by DENOM. Return 1 ms
2936 if division results in zero */
2937 static UINT period (const struct itimerval* it, UINT denom)
2938 {
2939 static TIMECAPS time_caps;
2940
2941 UINT res;
2942 const struct timeval* tv =
2943 (it->it_value.tv_sec == 0 && it->it_value.tv_usec == 0)
2944 ? &it->it_interval : &it->it_value;
2945
2946 /* Zero means stop timer */
2947 if (tv->tv_sec == 0 && tv->tv_usec == 0)
2948 return 0;
2949
2950 /* Conver to ms and divide by denom */
2951 res = (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000) / denom;
2952
2953 /* Converge to minimum timer resolution */
2954 if (time_caps.wPeriodMin == 0)
2955 timeGetDevCaps (&time_caps, sizeof(time_caps));
2956
2957 if (res < time_caps.wPeriodMin)
2958 res = time_caps.wPeriodMin;
2959
2960 return res;
2961 }
2962
2963 static int setitimer_helper (const struct itimerval* itnew,
2964 struct itimerval* itold, struct itimerval* itcurrent,
2965 MMRESULT* tid, DWORD sigkind)
2966 {
2967 UINT delay, resolution, event_type;
2968
2969 /* First stop the old timer */
2970 if (*tid)
2971 {
2972 timeKillEvent (*tid);
2973 timeEndPeriod (period (itcurrent, timer_prec));
2974 *tid = 0;
2975 }
2976
2977 /* Return old itimerval if requested */
2978 if (itold)
2979 *itold = *itcurrent;
2980
2981 *itcurrent = *itnew;
2982
2983 /* Determine if to start new timer */
2984 delay = period (itnew, 1);
2985 if (delay)
2986 {
2987 resolution = period (itnew, timer_prec);
2988 event_type = (itnew->it_value.tv_sec == 0 && itnew->it_value.tv_usec == 0)
2989 ? TIME_ONESHOT : TIME_PERIODIC;
2990 timeBeginPeriod (resolution);
2991 *tid = timeSetEvent (delay, resolution, timer_proc, sigkind, event_type);
2992 }
2993
2994 return !delay || *tid;
2995 }
2996
2997 int setitimer (int kind, const struct itimerval* itnew,
2998 struct itimerval* itold)
2999 {
3000 /* In this version, both interval and value are allowed
3001 only if they are equal. */
3002 assert ((itnew->it_value.tv_sec == 0 && itnew->it_value.tv_usec == 0)
3003 || (itnew->it_interval.tv_sec == 0 && itnew->it_interval.tv_usec == 0)
3004 || (itnew->it_value.tv_sec == itnew->it_interval.tv_sec &&
3005 itnew->it_value.tv_usec == itnew->it_interval.tv_usec));
3006
3007 if (kind == ITIMER_REAL)
3008 return setitimer_helper (itnew, itold, &it_alarm, &tid_alarm, SIGALRM);
3009 else if (kind == ITIMER_PROF)
3010 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF);
3011 else
3012 return errno = EINVAL;
3013 }
3014
2807 /* end of nt.c */ 3015 /* end of nt.c */