int read_shared_memory(void) { int *at; if (! is_shared_memory_initialised ) return 0; at = (int *)(sharedMemory.address); if (*at & signal_mask(SIGINT)) return 1; if (*at & signal_mask(SIGTERM)) return 2; return 0; }
static void *thread_run(void *parameter) { rt_thread_t tid; thread_t *thread; thread = THREAD_T(parameter); int res; /* set signal mask, mask the timer! */ signal_mask(); thread->status = SUSPEND_LOCK; TRACE("pid <%08x> stop on sem...\n", (unsigned int)(thread->pthread)); sem_wait(&thread->sem); tid = rt_thread_self(); TRACE("pid <%08x> tid <%s> starts...\n", (unsigned int)(thread->pthread), tid->name); thread->rtthread = tid; thread->task(thread->para); TRACE("pid <%08x> tid <%s> exit...\n", (unsigned int)(thread->pthread), tid->name); thread->exit(); /*TODO: * 最后一行的pthread_exit永远没有机会执行,这是因为在threead->exit函数中 * 会发生线程切换,并永久将此pthread线程挂起,所以更完美的解决方案是在这 * 里发送信号给主线程,主线程中再次唤醒此线程令其自动退出。 */ //sem_destroy(&thread->sem); pthread_exit(NULL); }
int main(int argc, char *argv[]) { int sig=-1; int pid=-1; char *in; sigNameStruct *sigNamePtr = sigNames; if (argc < 3 || argv[1][0] != '-') { USAGE: fprintf(stderr,"Sample usage: winkill -INT 232423, to interrupt the process 232423 "); {int i = 0; fprintf(stderr,"\nargv[1][0]=%c,%d",argv[1][0],argv[1][0]); fprintf(stderr,"\nCalled with: argc=%d <",argc); while (i < argc) fprintf(stderr, " %s",argv[i++]); fprintf(stderr,">\n"); } exit(1); } in = &(argv[1][1]); if (sscanf(&(argv[1][1]),"%d",&sig)==0) { while(sigNamePtr->name) { if (strcmp(sigNamePtr->name,in)==0) { sig = sigNamePtr->signumber; break; } sigNamePtr++; } } if (sig<0) { fprintf(stderr,"[had sig=%d]\n", sig); goto USAGE; } if (sscanf(argv[2],"%d",&pid)!=1 ) { fprintf(stderr,"sscanf(argv[2],\"%d\",&pid) failed for %s,%d", argv[2],atoi(argv[2])); goto USAGE; } sprintf(sharedMemory.name,"gcl-%d",pid); { int value; int *at; value = signal_mask(sig); sharedMemory.handle = OpenFileMapping(FILE_MAP_WRITE, /* Read/write permission. */ FALSE, /* Do not inherit the name */ sharedMemory.name); /* of the mapping object. */ if (sharedMemory.handle == NULL) { ErrorHandler("winkill: Could not open file-mapping object."); } sharedMemory.address = MapViewOfFile(sharedMemory.handle, /* Handle to mapping object. */ FILE_MAP_WRITE, /* Read/write permission. */ 0, /* Max. object size. */ 0, /* Size of hFile. */ 0); /* Map entire file. */ if (sharedMemory.address == NULL) { ErrorHandler("winkill: Could not map view of file."); } at = (int *)(sharedMemory.address); *at |= value; close_shared_memory(); exit(0); } }
int Tcl_WinKillCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {int sig=-1; int pid=-1; int i = 0; int value = 0; char *dosig = NULL; char *in; char *pidPtr = NULL; sharedMemory *shmPtr; sigNameStruct *sigNamePtr = sigNames; if (argc < 3 || argv[1][0] != '-') { { USAGE: Tcl_AppendResult(interp,"winkill -pid pid -signal SIG",0); return TCL_ERROR; } } for (i = 1 ; i < argc ; i+=2) { if (argv[i][0]!='-') { goto USAGE;} if (argv[i][1]=='s' && strcmp(&argv[i][1],"signal")==0) { in = &(argv[i+1][1]); if (sscanf(in,"%d",&sig)==0) { while(sigNamePtr->name) { if (strcmp(sigNamePtr->name,in)==0) { sig = sigNamePtr->signumber; break; } sigNamePtr++; } } if (sig<0) { Tcl_AppendResult(interp,"Bad Signal",0); goto USAGE; } value |= signal_mask(sig); } else if (argv[i][1]=='p' && strcmp(&argv[i][1],"pid")==0) { pidPtr = argv[i+1]; if (1 != sscanf(argv[i+1],"%d",&pid)) { Tcl_AppendResult(interp,"Bad pid arg:",argv[2],".",0); goto USAGE; } } else goto USAGE; } if (pidPtr== NULL || (shmPtr = getSharedMemoryPtr(interp,pid))==NULL) { Tcl_AppendResult(interp,"Could not open shared memory for pid ", pidPtr,0); return TCL_ERROR; } { int *at; at = (int *)(shmPtr->address); *at |= value; } return TCL_OK; }
int init_term(void) { #ifndef TGETENT_ACCEPTS_NULL static char termbuf[2048]; /* the termcap buffer */ #endif if (!*term) return termok = TERM_BAD; /* unset zle if using zsh under emacs */ if (!strcmp(term, "emacs")) opts[USEZLE] = 0; #ifdef TGETENT_ACCEPTS_NULL /* If possible, we let tgetent allocate its own termcap buffer */ if (tgetent(NULL, term) != 1) { #else if (tgetent(termbuf, term) != 1) { #endif if (isset(INTERACTIVE)) zerr("can't find termcap info for %s", term, 0); errflag = 0; return termok = TERM_BAD; } else { char tbuf[1024], *pp; int t0; termok = TERM_OK; for (t0 = 0; t0 != TC_COUNT; t0++) { pp = tbuf; zsfree(tcstr[t0]); /* AIX tgetstr() ignores second argument */ if (!(pp = tgetstr(tccapnams[t0], &pp))) tcstr[t0] = NULL, tclen[t0] = 0; else { tclen[t0] = strlen(pp); tcstr[t0] = (char *) zalloc(tclen[t0] + 1); memcpy(tcstr[t0], pp, tclen[t0] + 1); } } /* check whether terminal has automargin (wraparound) capability */ hasam = tgetflag("am"); /* if there's no termcap entry for cursor up, use single line mode: * * this is flagged by termok which is examined in zle_refresh.c * */ if (!tccan(TCUP)) { tcstr[TCUP] = NULL; termok = TERM_NOUP; } /* if there's no termcap entry for cursor left, use \b. */ if (!tccan(TCLEFT)) { tcstr[TCLEFT] = ztrdup("\b"); tclen[TCLEFT] = 1; } /* if the termcap entry for down is \n, don't use it. */ if (tccan(TCDOWN) && tcstr[TCDOWN][0] == '\n') { tclen[TCDOWN] = 0; zsfree(tcstr[TCDOWN]); tcstr[TCDOWN] = NULL; } /* if there's no termcap entry for clear, use ^L. */ if (!tccan(TCCLEARSCREEN)) { tcstr[TCCLEARSCREEN] = ztrdup("\14"); tclen[TCCLEARSCREEN] = 1; } } return termok; } /* Initialize lots of global variables and hash tables */ /**/ void setupvals(void) { struct passwd *pswd; struct timezone dummy_tz; char *ptr; #ifdef HAVE_GETRLIMIT int i; #endif noeval = 0; curhist = 0; histsiz = DEFAULT_HISTSIZE; inithist(); clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *)); cmdstack = (unsigned char *) zalloc(256); cmdsp = 0; bangchar = '!'; hashchar = '#'; hatchar = '^'; termok = TERM_BAD; curjob = prevjob = coprocin = coprocout = -1; gettimeofday(&shtimer, &dummy_tz); /* init $SECONDS */ srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */ hostnam = (char *) zalloc(256); gethostname(hostnam, 256); /* Set default path */ path = (char **) zalloc(sizeof(*path) * 5); path[0] = ztrdup("/bin"); path[1] = ztrdup("/usr/bin"); path[2] = ztrdup("/usr/ucb"); path[3] = ztrdup("/usr/local/bin"); path[4] = NULL; cdpath = mkarray(NULL); manpath = mkarray(NULL); fignore = mkarray(NULL); fpath = mkarray(NULL); mailpath = mkarray(NULL); watch = mkarray(NULL); psvar = mkarray(NULL); #ifdef DYNAMIC module_path = mkarray(ztrdup(MODULE_DIR)); modules = newlinklist(); #endif /* Set default prompts */ if (opts[INTERACTIVE]) { prompt = ztrdup("%m%# "); prompt2 = ztrdup("%_> "); } else { prompt = ztrdup(""); prompt2 = ztrdup(""); } prompt3 = ztrdup("?# "); prompt4 = ztrdup("+ "); sprompt = ztrdup("zsh: correct '%R' to '%r' [nyae]? "); ifs = ztrdup(DEFAULT_IFS); wordchars = ztrdup(DEFAULT_WORDCHARS); postedit = ztrdup(""); underscore = ztrdup(""); zoptarg = ztrdup(""); zoptind = 1; schedcmds = NULL; ppid = (long) getppid(); mypid = (long) getpid(); term = ztrdup(""); #ifdef TIOCGWINSZ if (!(columns = shttyinfo.winsize.ws_col)) columns = 80; if (columns < 2) opts[USEZLE] = 0; if (!(lines = shttyinfo.winsize.ws_row)) lines = 24; if (lines < 2) opts[SINGLELINEZLE] = 1; #else columns = 80; lines = 24; #endif /* The following variable assignments cause zsh to behave more * * like Bourne and Korn shells when invoked as "sh" or "ksh". * * NULLCMD=":" and READNULLCMD=":" */ if (emulation == EMULATE_KSH || emulation == EMULATE_SH) { nullcmd = ztrdup(":"); readnullcmd = ztrdup(":"); } else { nullcmd = ztrdup("cat"); readnullcmd = ztrdup("more"); } /* We cache the uid so we know when to * * recheck the info for `USERNAME' */ cached_uid = getuid(); /* Get password entry and set info for `HOME' and `USERNAME' */ if ((pswd = getpwuid(cached_uid))) { home = metafy(pswd->pw_dir, -1, META_DUP); cached_username = ztrdup(pswd->pw_name); } else { home = ztrdup("/"); cached_username = ztrdup(""); } /* Try a cheap test to see if we can * * initialize `PWD' from `HOME' */ if (ispwd(home)) pwd = ztrdup(home); else if ((ptr = zgetenv("PWD")) && ispwd(ptr)) pwd = ztrdup(ptr); else pwd = metafy(zgetcwd(), -1, META_REALLOC); oldpwd = ztrdup(pwd); /* initialize `OLDPWD' = `PWD' */ #ifdef __EMX__ *cdrive = _getdrive(); strcat(cdrive+1,":"); #endif inittyptab(); /* initialize the ztypes table */ initlextabs(); /* initialize lexing tables */ createreswdtable(); /* create hash table for reserved words */ createaliastable(); /* create hash table for aliases */ createcmdnamtable(); /* create hash table for external commands */ createshfunctable(); /* create hash table for shell functions */ createbuiltintable(); /* create hash table for builtin commands */ createnameddirtable(); /* create hash table for named directories */ createparamtable(); /* create paramater hash table */ #ifdef ZLE_MODULE add_dep("compctl", "zle"); addbuiltin("bindkey", 0, NULL, 0, -1, "zle"); addbuiltin("vared", 0, NULL, 1, 7, "zle"); addbuiltin("compctl", 0, NULL, 0, -1, "compctl"); #endif #ifdef HAVE_GETRLIMIT for (i = 0; i != RLIM_NLIMITS; i++) { getrlimit(i, current_limits + i); limits[i] = current_limits[i]; } #endif breaks = loops = 0; lastmailcheck = time(NULL); locallist = NULL; locallevel = sourcelevel = 0; trapreturn = 0; noerrexit = 0; nohistsave = 1; dirstack = newlinklist(); bufstack = newlinklist(); hsubl = hsubr = NULL; lastpid = 0; bshin = SHIN ? fdopen(SHIN, "r") : stdin; if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) { #ifdef _IONBF setvbuf(stdin, NULL, _IONBF, 0); #else setlinebuf(stdin); #endif } times(&shtms); } /* Initialize signal handling */ /**/ void init_signals(void) { intr(); #ifndef QDEBUG signal_ignore(SIGQUIT); #endif install_handler(SIGHUP); install_handler(SIGCHLD); if (interact) { install_handler(SIGALRM); #ifdef SIGWINCH install_handler(SIGWINCH); #endif signal_ignore(SIGTERM); } if (jobbing) { long ttypgrp; #ifndef __EMX__ while ((ttypgrp = gettygrp()) != -1 && ttypgrp != mypgrp) kill(0, SIGTTIN); #endif if (ttypgrp == -1) { opts[MONITOR] = 0; } else { #ifndef __EMX__ signal_ignore(SIGTTOU); signal_ignore(SIGTSTP); signal_ignore(SIGTTIN); #endif signal_ignore(SIGPIPE); attachtty(mypgrp); } } if (islogin) { signal_setmask(signal_mask(0)); } else if (interact) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGINT); sigaddset(&set, SIGQUIT); signal_unblock(set); } }
void erase_sigal_mask() { signal_mask(1); }
TEST_F(ProcTestor, ShareMem) { exit_cnt = 0; yf_set_sig_handler(SIGCHLD, on_child_process_exit, _log); yf_set_sig_handler(SIGIO, SIG_IGN, _log); signal_mask(); yf_shm_t shm; shm.size = 4096; yf_str_set(&shm.name, "test_shm"); shm.log = _log; yf_int_t ret = yf_shm_alloc(&shm); ASSERT_EQ(ret, YF_OK); int cnt[4] = { 6900000, 7500000, 6600000, 6215968 }; bool flag[4] = { true, true, false, false }; ShmSt *shm_st = (ShmSt *)shm.addr; shm_st->cnt = 0; yf_lock_init(&shm_st->lock); TestCtx test_ctx; test_ctx.test_ma = shm_st; yf_log_t *proc_log = yf_log_open(YF_LOG_DEBUG, 8192, (void*)"dir/proc.log"); yf_pid_t active_pid = yf_spawn_process(test_channel_func, NULL, "test_channel_func", YF_PROC_CHILD, on_child_exit_cb, proc_log); yf_pid_t pid = yf_spawn_process(test_channel_func, NULL, "test_channel_func", YF_PROC_CHILD, on_child_exit_cb, proc_log); yf_pid_t signal_pid = yf_spawn_process(empty_child_proc, NULL, "empty_child_proc", YF_PROC_CHILD, on_child_exit_cb, proc_log); ASSERT_TRUE(signal_pid != YF_INVALID_PID); for (size_t i = 0; i < YF_ARRAY_SIZE(cnt); ++i) { test_ctx.try_times = cnt[i]; test_ctx.is_add = flag[i]; pid = yf_spawn_process(child_process, &test_ctx, "child_process", YF_PROC_CHILD, on_child_exit_cb, proc_log); ASSERT_TRUE(pid != YF_INVALID_PID); } sigset_t set; sigemptyset(&set); while (exit_cnt < YF_ARRAY_SIZE(cnt)) { sigsuspend(&set); if (g_child_flag) { yf_process_get_status(_log); g_child_flag = 0; yf_log_debug1(YF_LOG_DEBUG, _log, 0, "exit child process = %d", exit_cnt); } } printf("last cnt=%d, pid=%d\n", shm_st->cnt, getpid()); ASSERT_EQ(shm_st->cnt, (cnt[0] + cnt[1] - cnt[2] - cnt[3])); //send signal to empty child proc yf_os_signal_process(child_signals, "reload", signal_pid, _log); yf_os_signal_process(child_signals, "stop_accept", signal_pid, _log); yf_sleep(1);//must yf_os_signal_process(child_signals, "quit", signal_pid, _log); //send cmd by channel to child proc, and old child -> new child yf_channel_t channel = {0}; channel.command = YF_CMD_DATA; sprintf(channel.data, "gfdgfds564fdaefafd"); ret = yf_write_channel(yf_processes[0].channel[0], &channel, _log); ASSERT_EQ(ret, YF_OK); //send file fd to child proc yf_memzero(&channel, sizeof(channel)); channel.command = YF_CMD_SEND_FD; yf_fd_t fd_send = yf_open_file("dir/test_fd_send", YF_FILE_APPEND, YF_FILE_CREATE_OR_OPEN, YF_FILE_DEFAULT_ACCESS); channel.fd = fd_send; assert(fd_send >= 0); ret = yf_write_channel(yf_processes[1].channel[0], &channel, _log); ASSERT_EQ(ret, YF_OK); //yf_close test 1's fds //yf_close(yf_processes[1].channel[0]); //yf_close(yf_processes[1].channel[1]); //channel 的特性,当把一对socket中一端发送给另外的proc后,就会形成,多个发送者和一个接受 //者的连接;只有当所有这些proc关闭这端后,另外那段接受者才能收到recv=0的标志(即连接断开) usleep(100000); yf_memzero(&channel, sizeof(channel)); channel.command = YF_CMD_QUIT; ret = yf_write_channel(yf_processes[0].channel[0], &channel, _log); ASSERT_EQ(ret, YF_OK); exit_cnt = 0; while (exit_cnt < 3) { sigsuspend(&set); if (g_child_flag) { yf_process_get_status(_log); g_child_flag = 0; yf_log_debug1(YF_LOG_DEBUG, _log, 0, "exit child process = %d", exit_cnt); } } yf_close_file(fd_send); yf_lock_destory(&shm_st->lock); yf_log_close(proc_log); yf_shm_free(&shm); }