?? rtlinux_signal.c
字號:
/* * (C) Finite State Machine Labs Inc. 2000 business@fsmlabs.com * * Released under the terms of GPL 2. * Open RTLinux makes use of a patented process described in * US Patent 5,995,745. Use of this process is governed * by the Open RTLinux Patent License which can be obtained from * www.fsmlabs.com/PATENT or by sending email to * licensequestions@fsmlabs.com *//* * This is a hack to get NR_IRQS on the PowerPC since it depends on * the configured machine and processor type as well as having __KERNEL__ * defined. Other architectures (alpha, mips) may need this one day as well. * -- Cort */#define __KERNEL__#include <linux/autoconf.h>#include <asm/irq.h>#undef __KERNEL__#include <fcntl.h>#include <linux/unistd.h>#include <asm/errno.h>#include <rtlinux_signal.h>/*#include <sys/mman.h>*//* sys/mman.h has old and wrong values -- Cort */#include <asm/mman.h>#include <stdio.h>#include <pthread.h>int gethrtime_init = 0;#define SETUP_CALL(ptr,file) \ if (!ptr) \ { \ char s[256]; \ int fd; \ \ memset(s, 0, 256); \ if ((fd = open(file, O_RDONLY)) < 0) \ return (-1); \ if ((read(fd, &s, 256)) < 0) \ return (-1); \ ptr = (typeof(ptr)) strtoul(s, NULL, 10); \ close(fd); \ }/* gethrtime function pointer */hrtime_t(*gethrtime_p) (void);int (*rtf_put_p) (unsigned int fifo, void *buf, int count);int (*rtf_get_p) (unsigned int fifo, void *buf, int count);unsigned long __NR_rtf_create_p = 0;unsigned long __NR_rtf_destroy_p = 0;volatile unsigned long create_fifo_retval, create_fifo_num, create_fifo_size, create_fifo_done;volatile unsigned long destroy_fifo_retval, destroy_fifo_num, destroy_fifo_done;hrtime_t gethrtime(void){ return gethrtime_p();}int rtf_put(unsigned int fifo, void *buf, int count){ return rtf_put_p(fifo, buf, count);}int rtf_get(unsigned int fifo, void *buf, int count){ return rtf_get_p(fifo, buf, count);}/* system calls for FIFO manipulation -Nathan */_syscall1(int, rtf_destroy_p, unsigned int, fifo);_syscall2(int, rtf_create_p, unsigned int, fifo, int, size);int rtf_destroy(unsigned int fifo){ if (__NR_rtf_destroy_p == 0) SETUP_CALL(__NR_rtf_destroy_p, "/proc/rtlinux/rtf_destroy"); return (rtf_destroy_p(fifo));}int rtf_create(unsigned int fifo, int size){ if (__NR_rtf_create_p == 0) SETUP_CALL(__NR_rtf_create_p, "/proc/rtlinux/rtf_create"); return (rtf_create_p(fifo, size));}/* global signal set of per-process blocked signals -Nathan */rtlinux_sigset_t rtlinux_blocked = { 0, };int rtlinux_sigaction(int sig, struct rtlinux_sigaction *act, struct rtlinux_sigaction *oldact){ char s[256]; int fd; unsigned long err; SETUP_CALL(gethrtime_p, "/proc/rtlinux/gethrtime"); SETUP_CALL(rtf_put_p, "/proc/rtlinux/rtf_put"); SETUP_CALL(rtf_get_p, "/proc/rtlinux/rtf_get"); /* Lock all our pages so we don't have to worry about faults * when the code is running in kernel mode. */ if (mlockall(MCL_CURRENT | MCL_FUTURE)) { perror("mlockall"); return -1; } sprintf(s, "/proc/rtlinux/sigaction"); if ((fd = open(s, O_WRONLY)) <= -1) return -1; act->sa_signal = sig; if ((err = write(fd, act, sizeof(*act))) != sizeof(*act)) return -1; else return 0;}/* XXX: This function (and functions it depends upon) will allow you to set * non-existant signals as blocked or unblocked. Mainly, this is for forward * compatibility when we add more signals; please don't abuse it. -Nathan */int rtlinux_sigprocmask(int how, rtlinux_sigset_t * set, rtlinux_sigset_t * oldset){ int retval, i; int fd; /* first save the old set */ if (oldset != NULL) { for (i = 0; i < RTLINUX_SIGMAX; i++) { retval = rtlinux_sigismember(&rtlinux_blocked, i); if (retval == -1) return (-1); else if (retval == 1) if ((rtlinux_sigaddset(oldset, i)) == -1) return (-1); } } if (how == RTLINUX_SIG_BLOCK) { for (i = 0; i < RTLINUX_SIGMAX; i++) { retval = rtlinux_sigismember(set, i); if (retval == -1) return (-1); else if (retval == 1) if ( (rtlinux_sigaddset (&rtlinux_blocked, i)) == -1) return (-1); } } else if (how == RTLINUX_SIG_UNBLOCK) { for (i = 0; i < RTLINUX_SIGMAX; i++) { retval = rtlinux_sigismember(set, i); if (retval == -1) return (-1); else if (retval == 1) if ( (rtlinux_sigdelset (&rtlinux_blocked, i)) == -1) return (-1); } } else if (how == RTLINUX_SIG_SETMASK) { rtlinux_sigemptyset(&rtlinux_blocked); for (i = 0; i < RTLINUX_SIGMAX; i++) { retval = rtlinux_sigismember(set, i); if (retval == -1) return (-1); else if (retval == 1) if ( (rtlinux_sigaddset (&rtlinux_blocked, i)) == -1) return (-1); } } else { return (-1); } if ((fd = open("/proc/rtlinux/sigprocmask", O_WRONLY)) < 0) return (-1); if ( (retval = write(fd, &rtlinux_blocked, sizeof(rtlinux_sigset_t))) != sizeof(rtlinux_sigset_t)) { close(fd); fprintf(stderr, "wrote %d of %d bytes\n", retval, sizeof(rtlinux_sigset_t)); return (-1); } if ((close(fd)) != 0) return (-1); /* if all else suceeds */ return (0);}/* The size of rtlinux_sigset_t is currently 34 bytes -- 272 bits, so we have * to do some malicious bit twiddling of our own here. The first two functions * aren't so bad, just beware the rest. -Nathan */int rtlinux_sigemptyset(rtlinux_sigset_t * set){ if (set == NULL) return (-1); memset(set, 0x00, sizeof(rtlinux_sigset_t)); return (0);}int rtlinux_sigfillset(rtlinux_sigset_t * set){ if (set == NULL) return (-1); memset(set, 0xff, sizeof(rtlinux_sigset_t)); return (0);}int rtlinux_sigaddset(rtlinux_sigset_t * set, int sig){ int offset; unsigned long int value; if (set == NULL) return (-1); if (sig > RTLINUX_SIGMAX) { errno = EINVAL; } offset = (int) ((sig / (sizeof(unsigned long int) * 8))); value = 1 << (sig % (sizeof(unsigned long int) * 8)); set->__val[offset] |= value; return (0);}int rtlinux_sigdelset(rtlinux_sigset_t * set, int sig){ int offset; unsigned long int value; if (set == NULL) return (-1); if (sig > RTLINUX_SIGMAX) { errno = EINVAL; return (-1); } offset = (int) ((sig / (sizeof(unsigned long int) * 8))); value = 1 << (sig % (sizeof(unsigned long int) * 8)); set->__val[offset] &= ~(value); return (0);}int rtlinux_sigismember(const rtlinux_sigset_t * set, int sig){ int offset; unsigned long int value; if (set == NULL) return (-1); if (sig > RTLINUX_SIGMAX) { errno = EINVAL; return (-1); } offset = (int) ((sig / (sizeof(unsigned long int) * 8))); value = 1 << (sig % (sizeof(unsigned long int) * 8)); if (((unsigned long int) (set->__val[offset] & value)) > 0) return (1); return (0);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -