• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++ sigsuspend函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中sigsuspend函数的典型用法代码示例。如果您正苦于以下问题:C++ sigsuspend函数的具体用法?C++ sigsuspend怎么用?C++ sigsuspend使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了sigsuspend函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: main

int main(int argc,char *argv[])
{
    char cmd[CMD_SIZE];
    pid_t childPid;
    sigset_t blockMask,emptyMask;
    struct sigaction sa;

    setbuf(stdout,NULL);    /* Disable buffering of stdout */

    memset(cmd,0,CMD_SIZE);
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sa.sa_handler = sigHandler;
    if (sigaction(SIGCHLD,&sa,NULL) == -1)
    {
        errExit("sigaction");
    }

    /* Block SIGCHLD to prevent its delivery if a child terminates
       before the parent commences the sigsupsend() */
    sigemptyset(&blockMask);
    sigaddset(&blockMask,SIGCHLD);
    if (sigprocmask(SIG_SETMASK,&blockMask,NULL) == -1)
    {
        errExit("sigprocmask");
    }
    
    printf("Parent PID=%ld\n",(long)getpid());

    switch(childPid = fork())
    {
    case -1:
        errExit("fork");
    case 0:   /* Child: immediately exits to become zombie */
        printf("Child (PID=%ld) exiting\n",(long)getpid());
        _exit(EXIT_SUCCESS);
    default:  /* Parent */

        sigemptyset(&emptyMask);
        if (sigsuspend(&emptyMask) == -1 && errno != EINTR)
        {
            errExit("sigsuspend");
        }
        
        snprintf(cmd,CMD_SIZE,"ps -c | grep %s",basename(argv[0]));
        cmd[CMD_SIZE - 1] = '\0';   /* Ensure string is null-terminated */
        system(cmd);               /* View zombie child */
        
        /* Now send the "sure kill" signal to the zombie */

        if (kill(childPid,SIGKILL) == -1)
        {
            errMsg("kill");
        }

        sleep(10);   /* Give child a chance to react to signal */
        printf("After sending SIGKILL to zombie (PID=%ld):\n",(long)childPid);
        system(cmd);   /* View zombie child again */
        
        exit(EXIT_SUCCESS);
    }
}
开发者ID:fanxiangchao,项目名称:tlpi,代码行数:62,代码来源:make_zombie_signal.c


示例2: coro_create

void
coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssize)
{
  coro_context nctx;
# if CORO_SJLJ
  stack_t ostk, nstk;
  struct sigaction osa, nsa;
  sigset_t nsig, osig;
# endif

  if (!coro)
    return;

  coro_init_func = coro;
  coro_init_arg  = arg;

  new_coro    = ctx;
  create_coro = &nctx;

# if CORO_SJLJ
  /* we use SIGUSR2. first block it, then fiddle with it. */

  sigemptyset (&nsig);
  sigaddset (&nsig, SIGUSR2);
  sigprocmask (SIG_BLOCK, &nsig, &osig);

  nsa.sa_handler = trampoline;
  sigemptyset (&nsa.sa_mask);
  nsa.sa_flags = SA_ONSTACK;

  if (sigaction (SIGUSR2, &nsa, &osa))
    {
      perror ("sigaction");
      abort ();
    }

  /* set the new stack */
  nstk.ss_sp    = STACK_ADJUST_PTR (sptr, ssize); /* yes, some platforms (IRIX) get this wrong. */
  nstk.ss_size  = STACK_ADJUST_SIZE (sptr, ssize);
  nstk.ss_flags = 0;

  if (sigaltstack (&nstk, &ostk) < 0)
    {
      perror ("sigaltstack");
      abort ();
    }

  trampoline_done = 0;
  kill (getpid (), SIGUSR2);
  sigfillset (&nsig); sigdelset (&nsig, SIGUSR2);

  while (!trampoline_done)
    sigsuspend (&nsig);

  sigaltstack (0, &nstk);
  nstk.ss_flags = SS_DISABLE;
  if (sigaltstack (&nstk, 0) < 0)
    perror ("sigaltstack");

  sigaltstack (0, &nstk);
  if (~nstk.ss_flags & SS_DISABLE)
    abort ();

  if (~ostk.ss_flags & SS_DISABLE)
    sigaltstack (&ostk, 0);

  sigaction (SIGUSR2, &osa, 0);
  sigprocmask (SIG_SETMASK, &osig, 0);

# elif CORO_LOSER

  coro_setjmp (ctx->env);
  #if __CYGWIN__ && __i386
    ctx->env[8]                        = (long)    coro_init;
    ctx->env[7]                        = (long)    ((char *)sptr + ssize)         - sizeof (long);
  #elif __CYGWIN__ && __x86_64
    ctx->env[7]                        = (long)    coro_init;
    ctx->env[6]                        = (long)    ((char *)sptr + ssize)         - sizeof (long);
  #elif defined(__MINGW32__)
    ctx->env[5]                        = (long)    coro_init;
    ctx->env[4]                        = (long)    ((char *)sptr + ssize)         - sizeof (long);
  #elif defined(_M_IX86)
    ((_JUMP_BUFFER *)&ctx->env)->Eip   = (long)    coro_init;
    ((_JUMP_BUFFER *)&ctx->env)->Esp   = (long)    STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
  #elif defined(_M_AMD64)
    ((_JUMP_BUFFER *)&ctx->env)->Rip   = (__int64) coro_init;
    ((_JUMP_BUFFER *)&ctx->env)->Rsp   = (__int64) STACK_ADJUST_PTR (sptr, ssize) - sizeof (__int64);
  #elif defined(_M_IA64)
    ((_JUMP_BUFFER *)&ctx->env)->StIIP = (__int64) coro_init;
    ((_JUMP_BUFFER *)&ctx->env)->IntSp = (__int64) STACK_ADJUST_PTR (sptr, ssize) - sizeof (__int64);
  #else
    #error "microsoft libc or architecture not supported"
  #endif

# elif CORO_LINUX

  coro_setjmp (ctx->env);
  #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined (JB_PC) && defined (JB_SP)
    ctx->env[0].__jmpbuf[JB_PC]        = (long)    coro_init;
    ctx->env[0].__jmpbuf[JB_SP]        = (long)    STACK_ADJUST_PTR (sptr, ssize) - sizeof (long);
//.........这里部分代码省略.........
开发者ID:Airisu,项目名称:pokemon-online,代码行数:101,代码来源:coro.c


示例3: main


//.........这里部分代码省略.........

    timeout.tv_sec = duration / 1000;
    timeout.tv_nsec = (duration % 1000) * 1000000;
    

    //set the data for each thread and create the threads
    for (i = 0; i < num_threads; i++) {
        data[i].id = i;
        data[i].num_operations = 0;
        data[i].total_time=0;
        data[i].num_insert=0;
        data[i].num_remove=0;
        data[i].num_search=0;
        data[i].num_add = max_key/(2 * num_threads); 
        if (i< ((max_key/2)%num_threads)) data[i].num_add++;
        data[i].seed = rand();
        data[i].barrier = &barrier;
        data[i].init_lock = &init_lock;
        if (pthread_create(&threads[i], &attr, test, (void *)(&data[i])) != 0) {
            fprintf(stderr, "Error creating thread\n");
            exit(1);
        }
    }
    pthread_attr_destroy(&attr);

    /* Catch some signals */
    if (signal(SIGHUP, catcher) == SIG_ERR ||
            signal(SIGINT, catcher) == SIG_ERR ||
            signal(SIGTERM, catcher) == SIG_ERR) {
        perror("signal");
        exit(1);
    }

    // seeds = seed_rand();
    // skey_t key;
    // for (i=0;i<max_key/2;++i) {
    //     key = my_random(&seeds[0],&seeds[1],&seeds[2]) & max_key;
    //     //we make sure the insert was effective (as opposed to just updating an existing entry)
    //     if (bst_add(key, root, 0)!=TRUE) {
    //         i--;
    //     }
    // }

    // bst_print(root);


    /* Start threads */
    barrier_cross(&barrier);
    gettimeofday(&start, NULL);
    if (duration > 0) {
        //sleep for the duration of the experiment
        nanosleep(&timeout, NULL);
    } else {
        sigemptyset(&block_set);
        sigsuspend(&block_set);
    }

    //signal the threads to stop
    *running = 0;
    gettimeofday(&end, NULL);

    /* Wait for thread completion */
    for (i = 0; i < num_threads; i++) {
        if (pthread_join(threads[i], NULL) != 0) {
            fprintf(stderr, "Error waiting for thread completion\n");
            exit(1);
        }
    }
    DDPRINT("threads finshed\n",NULL);
    //compute the exact duration of the experiment
    duration = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000);
    
    //bst_print(root);

    unsigned long operations = 0;
    ticks total_ticks = 0;
    long reported_total = 1; //the tree contains two initial dummy nodes, INF1 and INF2
    //report some experiment statistics
    for (i = 0; i < num_threads; i++) {
        printf("Thread %d\n", i);
        printf("  #operations   : %lu\n", data[i].num_operations);
        printf("  #inserts   : %lu\n", data[i].num_insert);
        printf("  #removes   : %lu\n", data[i].num_remove);
        operations += data[i].num_operations;
        total_ticks += data[i].total_time;
        reported_total = reported_total + data[i].num_add + data[i].num_insert - data[i].num_remove;
    }

    printf("Duration      : %d (ms)\n", duration);
    printf("#txs     : %lu (%f / s)\n", operations, operations * 1000.0 / duration);
    //printf("Operation latency %lu\n", total_ticks / operations);
    //make sure the tree is correct
    printf("Expected size: %ld Actual size: %lu\n",reported_total,bst_size(root));

    free(threads);
    free(data);

    return 0;

}
开发者ID:LPD-EPFL,项目名称:ASCYLIB,代码行数:101,代码来源:bst_howley_test_scalability.c


示例4: startServer

static int
startServer(char *server[])
{
    sigset_t mask, old;
    const char * const *cpp;

    sigemptyset(&mask);
    sigaddset(&mask, SIGUSR1);
    sigprocmask(SIG_BLOCK, &mask, &old);

    serverpid = fork();

    switch(serverpid) {
    case 0:
        /* Unblock */
        sigprocmask(SIG_SETMASK, &old, NULL);

        /*
         * don't hang on read/write to control tty
         */
        signal(SIGTTIN, SIG_IGN);
        signal(SIGTTOU, SIG_IGN);
        /*
         * ignore SIGUSR1 in child.  The server
         * will notice this and send SIGUSR1 back
         * at xinit when ready to accept connections
         */
        signal(SIGUSR1, SIG_IGN);
        /*
         * prevent server from getting sighup from vhangup()
         * if client is xterm -L
         */
        setpgid(0,getpid());
        Execute(server);

        Error("unable to run server \"%s\"", server[0]);

        fprintf(stderr, "Use the -- option, or make sure that %s is in your path and\n", bindir);
        fprintf(stderr, "that \"%s\" is a program or a link to the right type of server\n", server[0]);
        fprintf(stderr, "for your display.  Possible server names include:\n\n");
        for (cpp = server_names; *cpp; cpp++)
            fprintf(stderr, "    %s\n", *cpp);
        fprintf(stderr, "\n");

        exit(EXIT_FAILURE);

        break;
    case -1:
        break;
    default:
        /*
         * don't nice server
         */
        setpriority(PRIO_PROCESS, serverpid, -1);

        errno = 0;
        if(! processTimeout(0, "")) {
            serverpid = -1;
            break;
        }
        /*
         * kludge to avoid race with TCP, giving server time to
         * set his socket options before we try to open it,
         * either use the 15 second timeout, or await SIGUSR1.
         *
         * If your machine is substantially slower than 15 seconds,
         * you can easily adjust this value.
         */
        alarm(15);

        sigsuspend(&old);
        alarm(0);
        sigprocmask(SIG_SETMASK, &old, NULL);

        if (waitforserver() == 0) {
            Error("unable to connect to X server");
            shutdown();
            serverpid = -1;
        }
        break;
    }

    return(serverpid);
}
开发者ID:Jubei-Mitsuyoshi,项目名称:aaa-stage-1,代码行数:84,代码来源:xinit.c


示例5: j_waitj

/*
 * wait for job to complete or change state
 *
 * If jobs are compiled in then this routine expects sigchld to be blocked.
 */
static int
j_waitj(Job *j,
    int flags,			/* see JW_* */
    const char *where)
{
	int	rv;

	/*
	 * No auto-notify on the job we are waiting on.
	 */
	j->flags |= JF_WAITING;
	if (flags & JW_ASYNCNOTIFY)
		j->flags |= JF_W_ASYNCNOTIFY;

	if (!Flag(FMONITOR))
		flags |= JW_STOPPEDWAIT;

	while ((volatile int) j->state == PRUNNING ||
	    ((flags & JW_STOPPEDWAIT) && (volatile int) j->state == PSTOPPED)) {
		sigsuspend(&sm_default);
		if (fatal_trap) {
			int oldf = j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY);
			j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
			runtraps(TF_FATAL);
			j->flags |= oldf; /* not reached... */
		}
		if ((flags & JW_INTERRUPT) && (rv = trap_pending())) {
			j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);
			return -rv;
		}
	}
	j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY);

	if (j->flags & JF_FG) {
		int	status;

		j->flags &= ~JF_FG;
#ifdef JOBS
		if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) {
			/*
			 * Save the tty's current pgrp so it can be restored
			 * when the job is foregrounded.  This is to
			 * deal with things like the GNU su which does
			 * a fork/exec instead of an exec (the fork means
			 * the execed shell gets a different pid from its
			 * pgrp, so naturally it sets its pgrp and gets hosed
			 * when it gets foregrounded by the parent shell, which
			 * has restored the tty's pgrp to that of the su
			 * process).
			 */
			if (j->state == PSTOPPED &&
			    (j->saved_ttypgrp = tcgetpgrp(tty_fd)) >= 0)
				j->flags |= JF_SAVEDTTYPGRP;
			if (tcsetpgrp(tty_fd, our_pgrp) < 0) {
				warningf(true,
				    "j_waitj: tcsetpgrp(%d, %d) failed: %s",
				    tty_fd, (int) our_pgrp,
					strerror(errno));
			}
			if (j->state == PSTOPPED) {
				j->flags |= JF_SAVEDTTY;
				tcgetattr(tty_fd, &j->ttystate);
			}
		}
#endif /* JOBS */
		if (tty_fd >= 0) {
			/* Only restore tty settings if job was originally
			 * started in the foreground.  Problems can be
			 * caused by things like `more foobar &' which will
			 * typically get and save the shell's vi/emacs tty
			 * settings before setting up the tty for itself;
			 * when more exits, it restores the `original'
			 * settings, and things go down hill from there...
			 */
			if (j->state == PEXITED && j->status == 0 &&
			    (j->flags & JF_USETTYMODE)) {
				tcgetattr(tty_fd, &tty_state);
			} else {
				tcsetattr(tty_fd, TCSADRAIN, &tty_state);
				/* Don't use tty mode if job is stopped and
				 * later restarted and exits.  Consider
				 * the sequence:
				 *	vi foo (stopped)
				 *	...
				 *	stty something
				 *	...
				 *	fg (vi; ZZ)
				 * mode should be that of the stty, not what
				 * was before the vi started.
				 */
				if (j->state == PSTOPPED)
					j->flags &= ~JF_USETTYMODE;
			}
		}
#ifdef JOBS
//.........这里部分代码省略.........
开发者ID:bobertlo,项目名称:openbsd-pdksh,代码行数:101,代码来源:jobs.c


示例6: main


//.........这里部分代码省略.........
	memset(&signals, 0, sizeof(signals));
	sigemptyset(&signals.sa_mask);

	if (killsig != SIGKILL && killsig != SIGSTOP)
		signums[0] = killsig;

	for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i ++)
		sigaddset(&signals.sa_mask, signums[i]);

	signals.sa_handler = sig_handler;
	signals.sa_flags = SA_RESTART;

	for (i = 0; i < sizeof(signums) / sizeof(signums[0]); i ++)
		if (signums[i] != -1 && signums[i] != 0 &&
		    sigaction(signums[i], &signals, NULL) == -1)
			err(EX_OSERR, "sigaction()");

	signal(SIGTTIN, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);

	pid = fork();
	if (pid == -1)
		err(EX_OSERR, "fork()");
	else if (pid == 0) {
		/* child process */
		signal(SIGTTIN, SIG_DFL);
		signal(SIGTTOU, SIG_DFL);

		error = execvp(argv[0], argv);
		if (error == -1)
			err(EX_UNAVAILABLE, "exec()");
	}

	if (sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL) == -1)
		err(EX_OSERR, "sigprocmask()");

	/* parent continues here */
	set_interval(first_kill);

	for (;;) {
		sigemptyset(&signals.sa_mask);
		sigsuspend(&signals.sa_mask);

		if (sig_chld) {
			sig_chld = 0;
			while (((cpid = wait(&status)) < 0) && errno == EINTR)
				continue;

			if (cpid == pid) {
				pstat = status;
				break;
			}
		} else if (sig_alrm) {
			sig_alrm = 0;

			timedout = true;
			if (!foreground)
				killpg(pgid, killsig);
			else
				kill(pid, killsig);

			if (do_second_kill) {
				set_interval(second_kill);
				second_kill = 0;
				sig_ign = killsig;
				killsig = SIGKILL;
			} else
				break;

		} else if (sig_term) {
			if (!foreground)
				killpg(pgid, killsig);
			else
				kill(pid, sig_term);

			if (do_second_kill) {
				set_interval(second_kill);
				second_kill = 0;
				sig_ign = killsig;
				killsig = SIGKILL;
			} else
				break;
		}
	}

	while (cpid != pid  && wait(&pstat) == -1) {
		if (errno != EINTR)
			err(EX_OSERR, "waitpid()");
	}

	if (WEXITSTATUS(pstat))
		pstat = WEXITSTATUS(pstat);
	else if(WIFSIGNALED(pstat))
		pstat = 128 + WTERMSIG(pstat);

	if (timedout && !preserve)
		pstat = EXIT_TIMEOUT;

	return (pstat);
}
开发者ID:Alkzndr,项目名称:freebsd,代码行数:101,代码来源:timeout.c


示例7: ngx_master_process_cycle


//.........这里部分代码省略.........
                               NGX_PROCESS_RESPAWN);
    /*启动缓存索引重建进程,该进程在整个Nginx服务器运行过程中只存在很短的时间,主要用来遍历磁盘上的缓存数据,在内存中建立数据索引,提高Nginx服务器检索缓存的效率*/
    ngx_start_cache_manager_processes(cycle, 0);

    ngx_new_binary = 0;
    delay = 0;
    sigio = 0;
    live = 1;

    for ( ;; ) {
        if (delay) {
            /*等待工作进程退出的时间*/
            if (ngx_sigalrm) {
                sigio = 0;
                delay *= 2;
                ngx_sigalrm = 0;
            }

            ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                           "termination cycle: %M", delay);

            /*初始化一个定时器*/
            itv.it_interval.tv_sec = 0;
            itv.it_interval.tv_usec = 0;
            itv.it_value.tv_sec = delay / 1000;
            itv.it_value.tv_usec = (delay % 1000 ) * 1000;

            if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
                ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                              "setitimer() failed");
            }
        }

        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend");

        /*挂起进程,等待接收到信号,在不向主进程发送信号的情况下,该进程将一直挂起在这里等待*/
        sigsuspend(&set);

        /*更新缓冲时间*/
        ngx_time_update();

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                       "wake up, sigio %i", sigio);

        /*如果有工作进程异常退出,则调用ngx_reap_children()重启该工作进程*/
        if (ngx_reap) {
            ngx_reap = 0;
            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");

            /*重启工作进程*/
            live = ngx_reap_children(cycle);
        }

        /*如果主进程接收到的是NGX_CMD_TERMINATE信号、SIGTERM信号、SIGINT信号(ngx_terminate=1)或者收到的是NGX_CMD_QUIT信号、SIGQUIT信号(ngx_quit=1),并且工作进程退出,则主进程调用ngx_master_process_exit()函数退出*/
        if (!live && (ngx_terminate || ngx_quit)) {
            ngx_master_process_exit(cycle);
        }

        /*处理SIGINT信号*/
        if (ngx_terminate) {
            if (delay == 0) {
                delay = 50;
            }

            if (sigio) {
                sigio--;
开发者ID:Feather-Wang,项目名称:lib_of_wangqingsong_C,代码行数:67,代码来源:ngx_process_cycle.c


示例8: producer

void producer( pid_t ch_pid, int argc, char * argv[] )
{
    /*******************************************
     * Define producer (parent) process
     *******************************************/
    printf("\tPRODUCER: pid = %d\n", getpid());

    struct sigaction action;
    action.sa_handler = SIG_IGN;
    sigaction(SIGUSR1, &action, NULL);

    /* Read input file */
    char    buffer[BUFSIZE];
    ssize_t count;
    int     fdin;

    /* validate arguments from program call */
    if ( argc !=2 )
    {
        printf( "Usage: %s  <input_filename>\n", argv[0] );
        exit(1);
    }

    /* validate input file */
    if ( (fdin = open(argv[1], O_RDONLY)) == -1 )
    {
        perror("Error opening the input file");
        exit(2);
    }

    /* enter while loop to process data from input file */
    sigset_t mask;
    sigemptyset ( &mask );
    while ( (count=read(fdin, buffer, BUFSIZE)) > 0 )
    {
        /* Copy data from local buffer into shared memory */
        memcpy( shmem_ptr->buf, buffer, count );
#ifdef DEBUG
            printf("PRODUCER: wrote %zu bytes to shared mem\n", count);
#endif

        /* Send signal to consumer */
#ifdef DEBUG
            printf("PRODUCER: signal Consumer that shared memory ready to read\n");
#endif
        send_rt_signal( ch_pid, SIGUSR1, (int)count );

        /* Suspend until signal received from consumer */
#ifdef DEBUG
        printf("PRODUCER: suspend until signal received from Consumer...\n");
#endif
        sigsuspend( &mask );  /* No signals are masked while waiting */
    }

    if ( count == -1 ) {
       perror ("Error reading input file");
       exit(4);
    }

    close(fdin);

    /* Send signal to consumer */
#ifdef DEBUG
    printf("PRODUCER: signal Consumer that Producer has reached EOF\n");
#endif
    send_rt_signal( ch_pid, SIGUSR1, -1 );

    /* Suspend until signal received from consumer */
#ifdef DEBUG
    printf("PRODUCER: suspend until signal received from Consumer...\n");
#endif
    sigsuspend( &mask );  /* No signals are masked while waiting */
}
开发者ID:Eric0870,项目名称:csci_5103,代码行数:73,代码来源:prodcon.c


示例9: main


//.........这里部分代码省略.........
    sigprocmask(SIG_BLOCK, &blockedsigs, NULL);

    sigfillset(&unblockedsigs);
    sigdelset(&unblockedsigs, SIGTERM);
    sigdelset(&unblockedsigs, SIGINT);
    sigdelset(&unblockedsigs, SIGHUP);
    sigdelset(&unblockedsigs, SIGIO);
    sigdelset(&unblockedsigs, SIGCHLD);
    if (boot) {
	sigdelset(&unblockedsigs, SIGALRM);
    }
    sigprocmask(SIG_UNBLOCK, &unblockedsigs, NULL);

    /* Initialize the retry timeout using the RETRYTIMEOUT setting. */
    temp = svGetValue(ifcfg, "RETRYTIMEOUT");
    if (temp) {
	timeout = atoi(temp);
	free(temp);
    } else {
	timeout = 30;
    }

    /* Start trying to bring the interface up. */
    fork_exec(FALSE, IFUP_PPP, "daemon", device, boot);

    while (TRUE) {
	/* Wait for a signal. */
	if (!theSigterm &&
	    !theSigint &&
	    !theSighup &&
	    !theSigio &&
	    !theSigchld &&
	    !theSigalrm) {
	    sigsuspend(&unblockedsigs);
	}

	/* If we got SIGTERM or SIGINT, give up and hang up. */
	if (theSigterm || theSigint) {
	    theSigterm = theSigint = 0;

	    /* If we've already tried to exit this way, use SIGKILL instead
	     * of SIGTERM, because pppd's just being stubborn. */
	    if (dying) {
		sendsig = SIGKILL;
	    } else {
		sendsig = SIGTERM;
	    }
	    dying = TRUE;

	    /* Get the pid of our child pppd. */
	    pppLogicalToPhysical(&pppdPid, device, NULL);

	    /* We don't know what our child pid is.  This is very confusing. */
	    if (!pppdPid) {
		failureExit(35);
	    }

	    /* Die, pppd, die. */
	    kill(pppdPid, sendsig);
	    if (sendsig == SIGKILL) {
		kill(-pppdPid, SIGTERM); /* Give it a chance to die nicely, then
					    kill its whole process group. */
		usleep(2500000);
		kill(-pppdPid, sendsig);
		hangup(ifcfg);
		failureExit(32);
开发者ID:OpenMandrivaSoftware,项目名称:initscripts,代码行数:67,代码来源:ppp-watch.c


示例10: APR_DECLARE

APR_DECLARE(apr_status_t) apr_signal_thread(int(*signal_handler)(int signum))
{
    sigset_t sig_mask;
#if APR_HAVE_SIGWAIT
    int (*sig_func)(int signum) = (int (*)(int))signal_handler;
#endif

    /* This thread will be the one responsible for handling signals */
    sigfillset(&sig_mask);

    /* On certain platforms, sigwait() returns EINVAL if any of various
     * unblockable signals are included in the mask.  This was first 
     * observed on AIX and Tru64.
     */
#ifdef SIGKILL
    sigdelset(&sig_mask, SIGKILL);
#endif
#ifdef SIGSTOP
    sigdelset(&sig_mask, SIGSTOP);
#endif
#ifdef SIGCONT
    sigdelset(&sig_mask, SIGCONT);
#endif
#ifdef SIGWAITING
    sigdelset(&sig_mask, SIGWAITING);
#endif

    /* no synchronous signals should be in the mask passed to sigwait() */
    remove_sync_sigs(&sig_mask);

    /* On AIX (4.3.3, at least), sigwait() won't wake up if the high-
     * order bit of the second word of flags is turned on.  sigdelset()
     * returns an error when trying to turn this off, so we'll turn it
     * off manually.
     *
     * Note that the private fields differ between 32-bit and 64-bit
     * and even between _ALL_SOURCE and !_ALL_SOURCE.  Except that on
     * AIX 4.3 32-bit builds and 64-bit builds use the same definition.
     *
     * Applicable AIX fixes such that this is no longer needed:
     *
     * APAR IY23096 for AIX 51B, fix included in AIX 51C, and
     * APAR IY24162 for 43X.
     */
#if defined(_AIX)
#if defined(__64BIT__) && defined(_AIXVERSION_510)
#ifdef _ALL_SOURCE
        sig_mask.ss_set[3] &= 0x7FFFFFFF;
#else /* not _ALL_SOURCE */
        sig_mask.__ss_set[3] &= 0x7FFFFFFF;
#endif
#else /* not 64-bit build, or 64-bit build on 4.3 */
#ifdef _ALL_SOURCE
        sig_mask.hisigs &= 0x7FFFFFFF;
#else /* not _ALL_SOURCE */
        sig_mask.__hisigs &= 0x7FFFFFFF;
#endif
#endif
#endif /* _AIX */

    while (1) {
#if APR_HAVE_SIGWAIT
        int signal_received;

        if (apr_sigwait(&sig_mask, &signal_received) != 0)
        {
            /* handle sigwait() error here */
        }
        
        if (sig_func(signal_received) == 1) {
            return APR_SUCCESS;
        }
#elif HAVE_SIGSUSPEND
	sigsuspend(&sig_mask);
#else
#error No apr_sigwait() and no sigsuspend()
#endif
    }
}
开发者ID:AAthresh,项目名称:quantlib,代码行数:79,代码来源:signals.c


示例11: suspend_thread

static void
suspend_thread (SgenThreadInfo *info, void *context)
{
	int stop_count;
#ifndef USE_MONO_CTX
	gpointer regs [ARCH_NUM_REGS];
#endif
	MonoContext ctx;
	gpointer stack_start;

	info->client_info.stopped_domain = mono_domain_get ();
	info->client_info.signal = 0;
	stop_count = sgen_global_stop_count;
	/* duplicate signal */
	if (0 && info->client_info.stop_count == stop_count)
		return;

#ifdef USE_MONO_CTX
	if (context) {
		mono_sigctx_to_monoctx (context, &ctx);
		info->client_info.stopped_ip = MONO_CONTEXT_GET_IP (&ctx);
		stack_start = (((guint8 *) MONO_CONTEXT_GET_SP (&ctx)) - REDZONE_SIZE);
	} else {
		info->client_info.stopped_ip = NULL;
		stack_start = NULL;
	}
#else
	info->client_info.stopped_ip = context ? (gpointer) ARCH_SIGCTX_IP (context) : NULL;
	stack_start = context ? (char*) ARCH_SIGCTX_SP (context) - REDZONE_SIZE : NULL;
#endif

	/* If stack_start is not within the limits, then don't set it
	   in info and we will be restarted. */
	if (stack_start >= info->client_info.stack_start_limit && stack_start <= info->client_info.stack_end) {
		info->client_info.stack_start = stack_start;

#ifdef USE_MONO_CTX
		if (context) {
			memcpy (&info->client_info.ctx, &ctx, sizeof (MonoContext));
		} else {
			memset (&info->client_info.ctx, 0, sizeof (MonoContext));
		}
#else
		if (context) {
			ARCH_COPY_SIGCTX_REGS (regs, context);
			memcpy (&info->client_info.regs, regs, sizeof (info->client_info.regs));
		} else {
			memset (&info->client_info.regs, 0, sizeof (info->client_info.regs));
		}
#endif
	} else {
		g_assert (!info->client_info.stack_start);
	}

	/* Notify the JIT */
	if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
		mono_gc_get_gc_callbacks ()->thread_suspend_func (info->client_info.runtime_data, context, NULL);

	SGEN_LOG (4, "Posting suspend_ack_semaphore for suspend from %p %p", info, (gpointer) (gsize) mono_native_thread_id_get ());

	/*
	Block the restart signal. 
	We need to block the restart signal while posting to the suspend_ack semaphore or we race to sigsuspend,
	which might miss the signal and get stuck.
	*/
	pthread_sigmask (SIG_BLOCK, &suspend_ack_signal_mask, NULL);

	/* notify the waiting thread */
	SGEN_SEMAPHORE_POST (suspend_ack_semaphore_ptr);
	info->client_info.stop_count = stop_count;

	/* wait until we receive the restart signal */
	do {
		info->client_info.signal = 0;
		sigsuspend (&suspend_signal_mask);
	} while (info->client_info.signal != restart_signal_num);

	/* Unblock the restart signal. */
	pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL);

	SGEN_LOG (4, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer) (gsize) mono_native_thread_id_get ());
	/* notify the waiting thread */
	SGEN_SEMAPHORE_POST (suspend_ack_semaphore_ptr);
}
开发者ID:campolake,项目名称:mono_research,代码行数:84,代码来源:sgen-os-posix.c


示例12: main

int
main(int argc, char **argv)
{
	char buf[1024], *cp, c;
	int error, desc, rv;
	long scval;
	sigset_t ss;
	struct sigaction sa;
	void *region;
	size_t i, psize;

#ifndef _POSIX_SHARED_MEMORY_OBJECTS
	printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n");
#else
	printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n", 
	       (long)_POSIX_SHARED_MEMORY_OBJECTS - 0);
	if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1)
		printf("***Indicates this feature may be unsupported!\n");
#endif
	errno = 0;
	scval = sysconf(_SC_SHARED_MEMORY_OBJECTS);
	if (scval == -1 && errno != 0) {
		err(1, "sysconf(_SC_SHARED_MEMORY_OBJECTS)");
	} else {
		printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n",
		       scval);
		if (scval == -1)
			printf("***Indicates this feature is unsupported!\n");
	}

	errno = 0;
	scval = sysconf(_SC_PAGESIZE);
	if (scval == -1 && errno != 0) {
		err(1, "sysconf(_SC_PAGESIZE)");
	} else if (scval <= 0 || (size_t)psize != psize) {
		warnx("bogus return from sysconf(_SC_PAGESIZE): %ld",
		      scval);
		psize = 4096;
	} else {
		printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval);
		psize = scval;
	}

	argc--, argv++;

	if (*argv) {
		strncat(buf, *argv, (sizeof buf) - 1);
		desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
	} else {
		do {
			/*
			 * Can't use mkstemp for obvious reasons...
			 */
			strcpy(buf, "/tmp/shmtest.XXXXXXXXXXXX");
			mktemp(buf);
			desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
		} while (desc < 0 && errno == EEXIST);
	}

	if (desc < 0)
		err(1, "shm_open");

	if (shm_unlink(buf) < 0)
		err(1, "shm_unlink");

	if (ftruncate(desc, (off_t)psize) < 0)
		err(1, "ftruncate");

	region = mmap((void *)0, psize, PROT_READ | PROT_WRITE, MAP_SHARED,
		      desc, (off_t)0);
	if (region == MAP_FAILED)
		err(1, "mmap");
	memset(region, '\377', psize);

	sa.sa_flags = 0;
	sa.sa_handler = ignoreit;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGUSR1, &sa, (struct sigaction *)0) < 0)
		err(1, "sigaction");

	sigemptyset(&ss);
	sigaddset(&ss, SIGUSR1);
	if (sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) < 0)
		err(1, "sigprocmask");

	rv = fork();
	if (rv < 0) {
		err(1, "fork");
	} else if (rv == 0) {
		sigemptyset(&ss);
		sigsuspend(&ss);

		for (cp = region; cp < (char *)region + psize; cp++) {
			if (*cp != '\151')
				_exit(1);
		}
		if (lseek(desc, 0, SEEK_SET) == -1)
			_exit(1);
		for (i = 0; i < psize; i++) {
			error = read(desc, &c, 1);
//.........这里部分代码省略.........
开发者ID:coyizumi,项目名称:cs111,代码行数:101,代码来源:shm_test.c


示例13: eval

/* 
 * eval - Evaluate the command line that the user has just typed in
 * 
 * If the user has requested a built-in command (quit, jobs, bg or fg)
 * then execute it immediately. Otherwise, fork a child process and
 * run the job in the context of the child. If the job is running in
 * the foreground, wait for it to terminate and then return.  Note:
 * each child process must have a unique process group ID so that our
 * background children don't receive SIGINT (SIGTSTP) from the kernel
 * when we type ctrl-c (ctrl-z) at the keyboard.  
 */
void 
eval(char *cmdline) 
{
    int bg;              /* should the job run in bg or fg? */
    struct cmdline_tokens tok;

    int temp;
    pid_t pid;

    // variables to be used for blocking and unblocking signals
    sigset_t sigs;
    sigset_t sigmask;
    sigset_t wmask;
    sigemptyset(&sigmask);

    int jobID;
    struct job_t *new_job;

    /* Parse command line */
    bg = parseline(cmdline, &tok); 

    if (bg == -1) /* parsing error */
        return;

    if (tok.argv[0] == NULL) /* ignore empty lines */
        return;

    // If user enters builtin command quit
    // normally exits
    else if(tok.builtins == BUILTIN_QUIT)
      exit(0);
    
    // If user enters builtin command jobs
    // Lists all the current running and stopped jobs
    else if(tok.builtins == BUILTIN_JOBS)
    {
      if(tok.outfile == NULL)
	listjobs(job_list,1);
      else
      {
	temp = open(tok.outfile,O_WRONLY);
	listjobs(job_list,temp);
      }
    }

    // If user did not enter any built in commands
    else if(tok.builtins == BUILTIN_NONE)
    {

      //initialize signals and block
      sigemptyset(&sigs);
      sigaddset(&sigs, SIGINT);
      sigaddset(&sigs, SIGTSTP);
      sigaddset(&sigs, SIGCHLD);
      sigprocmask(SIG_BLOCK, &sigs, NULL);

      // I/O redirection
      if((pid = fork()) == 0)
      {
	if(tok.infile != NULL)
	  dup2(open(tok.infile, O_RDONLY), 0);
	if(tok.outfile != NULL)
	  dup2(open(tok.outfile, O_WRONLY), 0);
	
	setpgid(0, 0);
	sigprocmask(SIG_UNBLOCK, &sigs, NULL);
	
	if(execve(tok.argv[0], tok.argv, environ) < 0) //execute user command
	{
	  printf("%s: Command not found. \n", tok.argv[0]);
	  exit(0);
	}
      }

      if(!addjob(job_list, pid, bg ? BG : FG, cmdline))
        return;

      if(!bg)
	while(fgpid(job_list)) // wait for foreground job to finish
	  sigsuspend(&sigmask);
      else
	printf("[%d] (%d) %s\n",pid2jid(pid),pid,cmdline);

      sigprocmask(SIG_UNBLOCK,&sigs,NULL);
    }

    // If user enters builtin command FG (Foreground)
    if(tok.builtins == BUILTIN_FG)
    {
//.........这里部分代码省略.........
开发者ID:nabilmurshed,项目名称:Unix-Shell,代码行数:101,代码来源:tsh.c


示例14: eval

/* 
 * eval - Evaluate the command line that the user has just typed in
 * 
 * If the user has requested a built-in command (quit, jobs, bg or fg)
 * then execute it immediately. Otherwise, fork a child process and
 * run the job in the context of the child. If the job is running in
 * the foreground, wait for it to terminate and then return.  Note:
 * each child process must have a unique process group ID so that our
 * background children don't receive SIGINT (SIGTSTP) from the kernel
 * when we type ctrl-c (ctrl-z) at the keyboard.  
 */
void 
eval(char *cmdline) 
{
    int bg;              /* should the job run in bg or fg? */
    struct cmdline_tokens tok;

    int fd_in = STDIN_FILENO;
    int fd_out = STDOUT_FILENO;
    //int status;
    sigset_t mask, prev_mask;
    struct job_t *job;
    pid_t pid;


    /* Parse command line */
    bg = parseline(cmdline, &tok); 

    if (bg == -1) /* parsing error */
        return;
    if (tok.argv[0] == NULL) /* ignore empty lines */
        return;

    //Handle IO redirection
    if(tok.infile != NULL ) {
        if( (fd_in = open(tok.infile,O_RDONLY, 0)) < 0 )
            app_error("cannot open input file");
    }

    if(tok.outfile != NULL ) {
        if( (fd_out = open(tok.outfile,O_WRONLY|O_CREAT, 0644)) < 0 )
            app_error("cannot open output file");
    }

    switch(tok.builtins) {
    case BUILTIN_QUIT:
        exit(0);
        break;
    case BUILTIN_JOBS:
        listjobs(job_list,fd_out);
        break;
    case BUILTIN_BG:
        if(tok.argc < 2)
            app_error("lack of argument: PID or %%jobid");
        if(tok.argv[1][0] == '%')
            job = getjobjid(job_list,atoi(tok.argv[1]+1));
        else
            job = getjobpid(job_list,atoi(tok.argv[1]));

        if( !job )
            app_error("no such process or job");

        //Set job state to BG and send SIGCONT to its process group
        job->state = BG;
        printf("[%d] (%d) %s\n", job->jid, job->pid, job->cmdline);
        kill(-job->pid,SIGCONT);
        break;
    case BUILTIN_FG:
        if(tok.argc < 2)
            app_error("lack of argument: PID or %%jobid");
        if(tok.argv[1][0] == '%')
            job = getjobjid(job_list,atoi(tok.argv[1]+1));
        else
            job = getjobpid(job_list,atoi(tok.argv[1]));

        if( !job )
            app_error("no such processs or job");

        //Set job state to FG, send SIGCONT to its process, bring it to the front
        job->state = FG;
        kill(-job->pid, SIGCONT);
        
        //wait the fg process by a sigsuspend
        sigemptyset(&mask);
        if(!bg)
            while( fgpid(job_list) > 0 )
                sigsuspend(&mask);

        break;
    case BUILTIN_NONE:
        //Block SIGINT, SIGTSTP, SIGCHLD to avoid race 
        sigemptyset(&mask);
        sigaddset(&mask, SIGINT);
        sigaddset(&mask, SIGCHLD);
        sigaddset(&mask, SIGTSTP);
        sigprocmask(SIG_BLOCK, &mask, &prev_mask);

        //Child
        if((pid = fork()) == 0) {
            //Make SIGINT only send to tsh
//.........这里部分代码省略.........
开发者ID:jessesleeping,项目名称:15213labs,代码行数:101,代码来源:tsh.c


示例15: consumer

void consumer( void )
{
    /*******************************************
     * Define consumer (child) process
     *******************************************/
    printf("\tCONSUMER: pid = %d\n", getpid());
    consumer_done = 0;

    struct sigaction action;
    action.sa_handler = SIG_IGN;
    sigaction(SIGUSR2, &action, NULL);

    /*  Reuse key set in main to get the segment id of the
        segment that the parent process created. The size parameter is set
        to zero, and the flag to IPC_ALLOC, indicating that the segment is
        not being created here, it already exists
    */
    shmem_id = shmget (key, 0, 0);
    if (shmem_id == -1)
    {
        perror("child shmget failed");
        exit(1);
    }
#ifdef DEBUG
        printf("Consumer: Got shmem id = %d\n", shmem_id);
#endif

    /* Now attach this segment into the child address space */
        shmem_ptr = shmat (shmem_id, (void *) NULL, flag);
    if (shmem_ptr == (void *) -1)
    {
        perror("child shmat failed");
        exit(2);
    }
#ifdef DEBUG
        printf("Consumer: Got ptr = %p\n", shmem_ptr);
#endif


    /* open output file */
    mode_t  perms;
    perms = 0740;
    if ( (fdout = open ("output", (O_WRONLY | O_CREAT), perms)) == -1 )
    {
        perror("Error in creating output file");
        exit(3);
    }


    /* Suspend until signal received from producer */
    sigset_t mask;
    sigemptyset ( &mask );

    while ( consumer_done == 0 )
    {
#ifdef DEBUG
        printf("CONSUMER: suspend until signal received from Producer...\n");
#endif
        sigsuspend( &mask );  /* No signals are masked while waiting */
    }


    /* close the file */
    close(fdout);

    /* compute metrics from data transfer */
    struct timespec ts_now;
    float           d_xfr_t;

    clock_gettime( CLOCK_MONOTONIC, &ts_now );
    d_xfr_t = diff_time( &(shmem_ptr->ts), &ts_now );
    printf("\tData transfer completed in %f ms\n", d_xfr_t);

    /* done with the program, so detach the shared segment */
    shmdt( (void *)shmem_ptr);

    /* send signal to producer to indicate transfer complete */
#ifdef DEBUG
    printf("CONSUMER: signal Producer that data transfer is complete\n");
#endif
    send_rt_signal( getppid(), SIGUSR2, 0 );
}
开发者ID:Eric0870,项目名称:csci_5103,代码行数:82,代码来源:prodcon.c


示例16: intpr


//.........这里部分代码省略.........
		       W(d.comp_packets),
		       KBPS(W(d.inc_bytes)),
		       W(d.inc_packets),
		       ccs.d.ratio / 256.0);
		printf(" | %8.3f %6u %8.3f %6u %6.2f",
		       KBPS(W(c.comp_bytes)),
		       W(c.comp_packets),
		       KBPS(W(c.inc_bytes)),
		       W(c.inc_packets),
		       ccs.c.ratio / 256.0);
	    } else {
		printf("%8u %6u %8u %6u %6.2f",
		       W(d.comp_bytes),
		       W(d.comp_packets),
		       W(d.inc_bytes),
		       W(d.inc_packets),
		       ccs.d.ratio / 256.0);
		printf(" | %8u %6u %8u %6u %6.2f",
		       W(c.comp_bytes),
		       W(c.comp_packets),
		       W(c.inc_bytes),
		       W(c.inc_packets),
		       ccs.c.ratio / 256.0);
	    }
	
	} else {
	    if (ratef)
		printf("%8.3f", KBPS(V(p.ppp_ibytes)));
	    else
		printf("%8u", V(p.ppp_ibytes));
	    printf(" %6u %6u",
		   V(p.ppp_ipackets),
		   V(vj.vjs_compressedin));
	    if (!rflag)
		printf(" %6u %6u",
		       V(vj.vjs_uncompressedin),
		       V(vj.vjs_errorin));
	    if (vflag)
		printf(" %6u %6u",
		       V(vj.vjs_tossed),
		       V(p.ppp_ipackets) - V(vj.vjs_compressedin)
		       - V(vj.vjs_uncompressedin) - V(vj.vjs_errorin));
	    if (rflag) {
		printf(" %6.2f ", CRATE(d));
		if (ratef)
		    printf("%6.2f", KBPS(W(d.unc_bytes)));
		else
		    printf("%6u", W(d.unc_bytes));
	    }
	    if (ratef)
		printf("  | %8.3f", KBPS(V(p.ppp_obytes)));
	    else
		printf("  | %8u", V(p.ppp_obytes));
	    printf(" %6u %6u",
		   V(p.ppp_opackets),
		   V(vj.vjs_compressed));
	    if (!rflag)
		printf(" %6u %6u",
		       V(vj.vjs_packets) - V(vj.vjs_compressed),
		       V(p.ppp_opackets) - V(vj.vjs_packets));
	    if (vflag)
		printf(" %6u %6u",
		       V(vj.vjs_searches),
		       V(vj.vjs_misses));
	    if (rflag) {
		printf(" %6.2f ", CRATE(c));
		if (ratef)
		    printf("%6.2f", KBPS(W(c.unc_bytes)));
		else
		    printf("%6u", W(c.unc_bytes));
	    }

	}

	putchar('\n');
	fflush(stdout);
	line++;

	count--;
	if (!infinite && !count)
	    break;

	sigemptyset(&mask);
	sigaddset(&mask, SIGALRM);
	sigprocmask(SIG_BLOCK, &mask, &oldmask);
	if (!signalled) {
	    sigemptyset(&mask);
	    sigsuspend(&mask);
	}
	sigprocmask(SIG_SETMASK, &oldmask, NULL);
	signalled = 0;
	alarm(interval);

	if (!aflag) {
	    old = cur;
	    ocs = ccs;
	    ratef = dflag;
	}
    }
}
开发者ID:mihaicarabas,项目名称:dragonfly,代码行数:101,代码来源:pppstats.c


示例17: main

<

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ sigtimedwait函数代码示例发布时间:2022-05-30
下一篇:
C++ sigsetmask函数代码示例发布时间:2022-05-30
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap