Mercurial > hg > xemacs-beta
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 */ |