/* Before sending the signal to the pid this function verifies that * the pid is a member of the current process group; either using * apr_proc_wait(), where waitpid() guarantees to fail for non-child * processes; or by using getpgid() directly, if available. */ AP_DECLARE(apr_status_t) ap_mpm_safe_kill(pid_t pid, int sig) { #ifndef HAVE_GETPGID apr_proc_t proc; apr_status_t rv; apr_exit_why_e why; int status; /* Ensure pid sanity */ if (pid < 1) { return APR_EINVAL; } proc.pid = pid; rv = apr_proc_wait(&proc, &status, &why, APR_NOWAIT); if (rv == APR_CHILD_DONE) { /* The child already died - log the termination status if * necessary: */ ap_process_child_status(&proc, why, status); return APR_EINVAL; } else if (rv != APR_CHILD_NOTDONE) { /* The child is already dead and reaped, or was a bogus pid - * log this either way. */ ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, ap_server_conf, APLOGNO(00048) "cannot send signal %d to pid %ld (non-child or " "already dead)", sig, (long)pid); return APR_EINVAL; } #else pid_t pg; /* Ensure pid sanity. */ if (pid < 1) { return APR_EINVAL; } pg = getpgid(pid); if (pg == -1) { /* Process already dead... */ return errno; } if (pg != getpgrp()) { ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, APLOGNO(00049) "refusing to send signal %d to pid %ld outside " "process group", sig, (long)pid); return APR_EINVAL; } #endif return kill(pid, sig) ? errno : APR_SUCCESS; }
pid_t safe_getpgid(const char *file, const int lineno, pid_t pid) { pid_t pgid; pgid = getpgid(pid); if (pgid == -1) { tst_brk(TBROK | TERRNO, "%s:%d: getpgid(%i) failed", file, lineno, pid); } return pgid; }
int main(int argc, char *argv[]) { getpid(); getppid(); getpgid(0); getsid(0); getuid(); geteuid(); getgid(); getegid(); return 0; }
/* * In class com.android.internal.os.ZygoteInit: * private static native int getpgid(int pid) */ static jint com_android_internal_os_ZygoteInit_getpgid( JNIEnv* env, jobject clazz, jint pid) { pid_t ret; ret = getpgid(pid); if (ret < 0) { jniThrowIOException(env, errno); } return ret; }
bool CProcess::KillGroup(unsigned long timeout) const { #if defined(NCBI_OS_UNIX) TPid pgid = getpgid((TPid)m_Process); if (pgid == (TPid)(-1)) { // TRUE if PID does not match any process return errno == ESRCH; } return KillGroupById(pgid, timeout); #elif defined(NCBI_OS_MSWIN) // Convert the process handle to process ID if needed TPid pid = 0; if (m_Type == eHandle) { // Some OS like Windows 2000 and WindowsXP (w/o SP1) don't // have GetProcessId() function. Try to load it directy from // KERNEL32.DLL static bool s_TryGetProcessId = true; typedef DWORD (STDMETHODCALLTYPE FAR* LPFN_GETPROCESSID)(HANDLE process); static LPFN_GETPROCESSID s_GetProcessId = NULL; if ( s_TryGetProcessId && !s_GetProcessId ) { s_GetProcessId = (LPFN_GETPROCESSID)GetProcAddress( GetModuleHandleA("KERNEL32.DLL"), "GetProcessId"); s_TryGetProcessId = false; } if ( !s_GetProcessId ) { // GetProcessId() is not available on this platform return false; } pid = s_GetProcessId((TProcessHandle)m_Process); } else { // m_Type == ePid pid = (TPid)m_Process; } if (!pid) { return false; } // Use safe process termination if timeout > 0 unsigned long x_timeout = timeout; CStopWatch timer; if ( timeout ) { timer.Start(); } // Kill process tree bool result = s_KillGroup(pid, (timeout > 0) ? &timer : 0, x_timeout); return result; #endif }
/* * Unload all the loaded modules and then refresh the module cache with the * latest list of loaded modules and their address ranges. */ void dtrace_update(dtrace_hdl_t *dtp) { dt_module_t *dmp; DIR *dirp; for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL; dmp = dt_list_next(dmp)) dt_module_unload(dtp, dmp); if (!(dtp->dt_oflags & DTRACE_O_NOSYS)) { dt_module_update(dtp, "mach_kernel"); } /* * Look up all the macro identifiers and set di_id to the latest value. * This code collaborates with dt_lex.l on the use of di_id. We will * need to implement something fancier if we need to support non-ints. */ dt_idhash_lookup(dtp->dt_macros, "egid")->di_id = getegid(); dt_idhash_lookup(dtp->dt_macros, "euid")->di_id = geteuid(); dt_idhash_lookup(dtp->dt_macros, "gid")->di_id = getgid(); dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid(); dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0); dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid(); dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid(); dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0); dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid(); dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid(); /* * Cache the pointers to the modules representing the base executable * and the run-time linker in the dtrace client handle. Note that on * x86 krtld is folded into unix, so if we don't find it, use unix * instead. */ dtp->dt_exec = dt_module_lookup_by_name(dtp, "mach_kernel"); dtp->dt_rtld = dt_module_lookup_by_name(dtp, "dyld"); /* XXX to what purpose? */ /* * If this is the first time we are initializing the module list, * remove the module for genunix from the module list and then move it * to the front of the module list. We do this so that type and symbol * queries encounter genunix and thereby optimize for the common case * in dtrace_lookup_by_name() and dtrace_lookup_by_type(), below. */ if (dtp->dt_exec != NULL && dtp->dt_cdefs == NULL && dtp->dt_ddefs == NULL) { dt_list_delete(&dtp->dt_modlist, dtp->dt_exec); dt_list_prepend(&dtp->dt_modlist, dtp->dt_exec); } }
/** * @return TRUE (i.e. the daemons pid) if a daemon process is running, * otherwise FALSE */ int exist_daemon() { pid_t pid; errno= 0; if( (pid= Util_getPid(Run.pidfile)) ) if( (getpgid(pid)) > -1 || (errno == EPERM) ) return( (int)pid ); return(FALSE); }
/* find_cinit_pids() iteratively finds the pid's having same PGID as its parent. * Input parameter - Accepts pointer to pid_t : To copy the pid's matching. * Returns - the number of pids matched. */ int find_cinit_pids(pid_t * pids) { int next = 0, pid_max, i; pid_t parentpid, pgid, pgid2; pid_max = max_pid(); parentpid = getpid(); pgid = getpgid(parentpid); /* The loop breaks, when the loop counter reaches the parentpid value */ for (i = parentpid + 1; i != parentpid; i++) { if (i > pid_max) i = 2; pgid2 = getpgid(i); if (pgid2 == pgid) { pids[next] = i; next++; } } return next; }
void hello_signal(int number, siginfo_t *info, void *something) { struct datapacket send_data; send_data.num = number; send_data.signo = info->si_signo; send_data.code = info->si_code; send_data.mypid = getpid(); send_data.mygid = getpgrp(); send_data.sender_pid = info->si_pid; send_data.sender_gid = getpgid(info->si_pid); send_data.sender_uid = info->si_uid; write(pair[1], &send_data, sizeof(send_data)); }
int main (void) { pid_t pid; int fils; /* Création d'un nouveau groupe de processus */ setpgid (0, 0); signal (SIGUSR1, gestionnaire); for (fils = 0; fils < NB_FILS; fils ++) { if ((pid = fork()) < 0) { perror ("fork"); exit (1); } if (pid != 0) continue; gentillesse = fils * (20 / (NB_FILS - 1)); if (nice (gentillesse) < 0) { perror ("nice"); exit (1); } /* attente signal de démarrage */ pause (); /* comptage */ while (1) compteur ++; } /* processus père */ signal (SIGUSR1, SIG_IGN); sleep (1); kill (- getpgid (0), SIGUSR1); sleep (5); kill (- getpgid (0), SIGUSR1); while (wait (NULL) > 0) ; exit (0); }
extern int slurm_container_plugin_signal ( uint64_t id, int signal ) { pid_t pid = (pid_t) id; if (!id) /* no container ID */ return ESRCH; if (pid == getpid() || pid == getpgid(0)) { error("slurm_signal_container would kill caller!"); return ESRCH; } return (int)killpg(pid, signal); }
int main(int ac, char **av) { int lc; /* loop counter */ int i; const char *msg; /* message returned by parse_opts */ /* parse standard options */ if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){ tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); } setup(); /* set up the expected errnos */ TEST_EXP_ENOS(exp_enos); /* check looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; /* loop through the test cases */ for (i = 0; i < TST_TOTAL; i++) { TEST(getpgid(*TC[i].id)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "call succeeded unexpectedly"); continue; } TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == TC[i].error) { tst_resm(TPASS, "expected failure - " "errno = %d : %s", TEST_ERRNO, strerror(TEST_ERRNO)); } else { tst_resm(TFAIL, "unexpected error - %d : %s - " "expected %d", TEST_ERRNO, strerror(TEST_ERRNO), TC[i].error); } } } cleanup(); /*NOTREACHED*/ }
void exec_process(char *cmd, char **args, pid_t pgid, int fin, int fout, char fg) { int err; /* set the pgid */ if( setpgid(0, pgid) == -1 ) { perror("setpgid"); _exit(EXIT_FAILURE); } //printf("%s new pgid: %d\n", args[0],getpgid(0)); if( fg && tcsetpgrp(STDIN_FILENO, getpgid(0)) == -1 ) { perror("tcsetpgrp"); _exit(EXIT_FAILURE); } /* set stdin, stdout */ if(fin != STDIN_FILENO) { dup2(fin, STDIN_FILENO); close(fin); } if(fout != STDOUT_FILENO) { dup2(fout, STDOUT_FILENO); close(fout); } /* reset signal handlers to default */ signal(SIGTTOU, SIG_DFL); signal(SIGTTIN, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGTSTP, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGCHLD, SIG_DFL); err = execvp(cmd, args); if(err == -1) { err = errno; if(err == ENOENT || err == ENOTDIR) // no file or dir for cmd write(STDOUT_FILENO, UNCMD_MSG, STRING_SIZE(UNCMD_MSG)); else perror("execvp"); free_list(job_list); free_list(msg_q); _exit(EXIT_FAILURE); } }
int main (int argc, char * argv []) { int i; pid_t pid; pid_t pgid; if (argc == 1) { fprintf (stdout, "%u : %u\n", getpid (), getpgid (0)); return (0); } for (i = 1; i < argc; i ++) if (sscanf (argv [i], "%u", & pid) != 1) { fprintf (stderr, "PID invalide : %s\n", argv [i]); } else { pgid = getpgid (pid); if (pgid == -1) fprintf (stderr, "%u inexistant\n", pid); else fprintf (stderr, "%u : %u\n", pid, pgid); } return (0); }
static void _reset_input_mode (void) { /* SIGTTOU needs to be blocked per the POSIX spec: * http://pubs.opengroup.org/onlinepubs/009695399/functions/tcsetattr.html */ int sig_block[] = { SIGTTOU, SIGTTIN, 0 }; xsignal_block (sig_block); tcsetattr (STDIN_FILENO, TCSANOW, &saved_tty_attributes); /* If salloc was run as interactive, with job control, reset the * foreground process group of the terminal to the process group of * the parent pid before exiting */ if (is_interactive) tcsetpgrp(STDIN_FILENO, getpgid(getppid())); }
extern int proctrack_p_signal ( uint64_t id, int signal ) { pid_t pid = (pid_t) id; if (!id) { /* no container ID */ } else if (pid == getpid() || pid == getpgid(0)) { error("slurm_signal_container would kill caller!"); } else { return killpg(pid, signal); } slurm_seterrno(ESRCH); return SLURM_ERROR; }
int main (int argc, char * argv[]) { int i; long int pid; long int pgid; if (argc == 1) { fprintf(stdout, "%d : %d\n", getpid(), getpgid(0)); return 0; } for (i = 1; i < argc; i ++) { if (sscanf(argv[i], "%ld", & pid) != 1) { fprintf(stderr, "PID invalide : %s\n", argv[i]); } else { pgid = (long) getpgid((pid_t) pid); if (pgid == -1) fprintf(stderr, "%ld inexistant\n", pid); else fprintf(stderr, "%ld : %ld\n", pid, pgid); } } return 0; }
/********************************************************************************************************* ** 函数名称: setpriority ** 功能描述: set or set the nice value ** 输 入 : which PRIO_PROCESS / PRIO_PGRP / PRIO_USER ** who process ID / process group ID / effective user ID who == 0 specifies the current process, process group or user. ** value priority (PRIO_MIN ~ PRIO_MAX) PRIO_MIN -> highest priorioty PRIO_MAX -> lowest priorioty ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API int setpriority (int which, id_t who, int value) { #if LW_CFG_MODULELOADER_EN > 0 INT iRet = PX_ERROR; UINT8 ucPriority; if ((value < PRIO_MIN) || (value > PRIO_MAX)) { errno = EINVAL; return (PX_ERROR); } if (which == PRIO_PROCESS) { if (who == 0) { who = (id_t)getpid(); } } else if (which == PRIO_PGRP) { if (who == 0) { who = (id_t)getpgid(getpid()); } } else if (PRIO_USER) { if (who == 0) { who = (id_t)geteuid(); } } else { errno = EINVAL; return (PX_ERROR); } ucPriority = (UINT8)value; __KERNEL_ENTER(); _ThreadTraversal(__sprio_hook, (PVOID)&iRet, (PVOID)which, (PVOID)who, (PVOID)&ucPriority, LW_NULL, LW_NULL); __KERNEL_EXIT(); if (iRet == ERROR_NONE) { return (ERROR_NONE); } else { errno = ESRCH; return (PX_ERROR); } #else errno = ENOSYS; return (PX_ERROR); #endif /* LW_CFG_MODULELOADER_EN > 0 */ }
static void ft_continue_child(t_data *d, t_id *tmp) { ft_printf("[%d]\tcontinued\t%s\n", tmp->nb, tmp->cmd); if (tcsetpgrp(d->tty.fd, getpgid(tmp->pid)) < 0) ft_puterror("tcsetpgrp in builtin/ft_fg.c line 23: failed\n"); if (!tmp->run && killpg(tmp->pid, SIGCONT) < 0) ft_puterror("kill in builtin/ft_fg.c line 25: failed\n"); tmp->jobs = 0; tmp->run = 0; waitpid(-tmp->pid, &tmp->id, WUNTRACED); ft_print_process(d, tmp); if (tcsetpgrp(d->tty.fd, getpgrp()) < 0) ft_puterror("tcsetpgrp in builtin/ft_fg.c line 30: failed\n"); }
int main(int ac, char **av) { int nb; int id; int f_id; int gid; nb = atoi(av[1]) + 1; gid = 0; while (nb) { if ((id = fork()) == 0) { execlp("./xeyes_fedo64", "xeyes_fedo64", 0); } else { if (nb == atoi(av[1]) + 1) f_id = id; if (setpgid(id, gid) == -1) { write(2, "erreur setpgrid\n", strlen("erreur setpgrid\n")); perror("setpgid"); } if (f_id == id) { if (tcsetpgrp(0, getpgid(id)) == -1) write(2, "erreur tcspgrid\n", strlen("erreur tcspgrid\n")); if (tcsetpgrp(1, getpgid(id)) == -1) write(2, "erreur tcspgrid\n", strlen("erreur tcspgrid\n")); } sleep(3); } nb--; } return (0); }
static void __my_sig_child(int signo, siginfo_t *info, void *data) { int status; pid_t child_pid, child_pgid; child_pgid = getpgid(info->si_pid); SLOG(LOG_DEBUG, TAG_TTSC, "Signal handler: dead pid = %d, pgid = %d\n", info->si_pid, child_pgid); while (0 < (child_pid = waitpid(-1, &status, WNOHANG))) { if(child_pid == child_pgid) killpg(child_pgid, SIGKILL); } return; }
int main(int argc,char**argv) { pid_t pid; pid = fork(); if (pid < 0) { printf ("fork error"); } else if (pid ==0) //子进程 { printf("The child process PID is %d.\n",getpid()); printf("The Group ID is %d.\n",getpgrp()); printf("The Group ID is %d.\n",getpgid(0)); printf("The Group ID is %d.\n",getpgid(getpid())); exit(0); } sleep(3); printf("The Parent process PID is %d.\n",getpid()); printf("The Group ID is %d.\n",getpgrp()); return 0; }
static void do_sigchld(int sig) { pid_t pid, pgid; int status; xvect dying_jobs; size_t i, j; xv_init(&dying_jobs, sizeof(pid_t)); while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { if (WIFSTOPPED(status)) { post_job_suspend(getpgid(pid), 1); } else { pgid = getpgid(pid); xv_push(&dying_jobs, &pgid); } } for (i = 0; i < xv_size(&dying_jobs); ++i) { pgid = *(pid_t *)xv_get(&dying_jobs, i); if (waitpid(-pgid, &status, WNOHANG | WUNTRACED) == -1 && errno == ECHILD) { /* if the job of pgid is completely dead */ for (j = 0; j < xv_size(&bg_jobs); ++j) { if (((bg_job *)xv_get(&bg_jobs, j))->pgid == pgid) { break; } } if (j != xv_size(&bg_jobs)) { xv_splice(&bg_jobs, j, 1); } } } xv_destroy(&dying_jobs); }
int main() { pid_t pid; pid_t pgid = getpgid(0); setpgid(0,0); kill(-1*pgid, SIGKILL); while (1) { while ((pid = fork())!= -1) { if (pid == 0) { setpgid(0,0); } } } }
int spawncmd::terminate() { if (pid() <= 0) return 0 ; pid_t p = _pid ; _pid = 0 ; if (_wait) return waitpid(p, &_status, 0) ; if (int result = waitpid(p, &_status, WNOHANG)) return result ; std::cout << "Killing " << p << std::endl ; if (int result = kill(-getpgid(p), SIGTERM)) return result ; return waitpid(p, &_status, 0) ; }
void sig_tstp(int signno) { if(findJobNo(curpid)==-1) { fprintf(stderr, "\nNo foreground job running!\n"); longjmp(env,2); return; } else { int i=findJobNo(curpid); if(jobs[i]->bg_flag==0) //fg process { jobs[i]->bg_flag=1; tcsetpgrp (STDIN_FILENO, getpgid(curpid)); tcsetpgrp (STDOUT_FILENO, getpgid(curpid)); printf("\n"); longjmp(env,2); } } signal(SIGTSTP, sig_tstp); /* reestablish signal handler */ return; }
__pid_t __waitpid_not_cancel (__pid_t pid, int *stat_loc, int options) { int res; siginfo_t info; /* wait until the child dies */ options |= WEXITED | WTRAPPED; /* implement waitpid by calling waitid */ if (pid < -1) res = waitid_not_cancel (P_PGID, -pid, &info, options); else if (pid == -1) res = waitid_not_cancel (P_ALL, 0, &info, options); else if (pid == 0) res = waitid_not_cancel (P_PGID, getpgid(0), &info, options); else /* if(pid > 0) */ res = waitid_not_cancel (P_PID, pid, &info, options); if (res == -1) return -1; /* use info.si_code and info.si_status to set stat_loc */ if (stat_loc) { switch (info.si_code) { case CLD_EXITED: *stat_loc = (info.si_status & 0xff) << 8; break; case CLD_KILLED: *stat_loc = (info.si_status & 0x7f); break; case CLD_DUMPED: *stat_loc = (info.si_status & 0x7f) | WCOREFLG; break; case CLD_TRAPPED: case CLD_STOPPED: *stat_loc = ((info.si_status & 0xff) << 8) | WSTOPFLG; break; case CLD_CONTINUED: *stat_loc = WCONTFLG; break; } } return info.si_pid; }
/** * call result callback function * run in caller */ static int __call_app_result_callback(bundle *kb, int is_cancel, int launched_pid) { app_resultcb_info_t *info; int pgid; char *fwdpid_str; if (((info = __find_resultcb(launched_pid)) == NULL) || (launched_pid < 0)) { _E("reject by pid - wait pid = %d, recvd pid = %d\n", getpid(), launched_pid); /* second chance - support app launched by shell script*/ pgid = getpgid(launched_pid); if (pgid <= 1) return -1; if ((info = __find_resultcb(pgid)) == NULL) { _E("second chance : also reject pgid - %d\n", pgid); return -1; } } if (info->cb_func == NULL || kb == NULL) return -1; /* In case of aul_forward_app, update the callback data */ if(is_cancel == 1 && (fwdpid_str = (char *)bundle_get_val(kb, AUL_K_FWD_CALLEE_PID))) { app_resultcb_info_t newinfo; newinfo.launched_pid = atoi(fwdpid_str); newinfo.cb_func = info->cb_func; newinfo.priv_data = info->priv_data; __remove_resultcb(info); __add_resultcb(newinfo.launched_pid, newinfo.cb_func, newinfo.priv_data); _D("change callback - %s\n",AUL_K_FWD_CALLEE_PID); goto end; } info->cb_func(kb, is_cancel, info->priv_data); __remove_resultcb(info); end: return 0; }
/* * kill_process: sends the given signal to the specified process. It does * not delete the process from the process table or anything like that, it * only is for sending a signal to a sub process (most likely in an attempt * to kill it.) The actual reaping of the children will take place async * on the next parsing run. */ static void kill_process (int kill_index, int sig) { pid_t pgid; int old_from_server, l; if (!process_list || kill_index > process_list_size || !process_list[kill_index]) { say("There is no such process %d", kill_index); return; } old_from_server = from_server; from_server = process_list[kill_index]->server; l = message_from(NULL, LEVEL_OTHER); say("Sending signal %s (%d) to process %d: %s", sys_siglist[sig], sig, kill_index, process_list[kill_index]->name); pop_message_from(l); from_server = old_from_server; #ifdef HAVE_GETPGID pgid = getpgid(process_list[kill_index]->pid); #else # ifndef GETPGRP_VOID pgid = getpgrp(process_list[kill_index]->pid); # else pgid = process_list[kill_index]->pid; # endif #endif #ifndef HAVE_KILLPG # define killpg(pg, sig) kill(-(pg), (sig)) #endif /* The exec'd process shouldn't be in our process group */ if (pgid == getpid()) { yell("--- exec'd process is in my job control session! Something is hosed ---"); return; } killpg(pgid, sig); kill(process_list[kill_index]->pid, sig); }
void do_resize(int number, int rows, int cols, int ypixels, int xpixels) { int i; #ifdef USE_WINCHKILL int pg; #endif for (i=0; i < MAX_CLIENTS; i++) { if (clients[i].fd >= 0 && clients[i].number == number) { #ifdef TIOCSWINSZ struct winsize ws; ws.ws_row = rows; ws.ws_col = cols; ws.ws_ypixel = ypixels; ws.ws_xpixel = xpixels; ioctl(clients[i].fd, TIOCSWINSZ, &ws); #else #ifdef TIOCSSIZE struct ttysize ts; ts.ts_lines = rows; ts.ts_cols = cols; ts.ts_yyy = ypixels; ts.ts_xxx = xpixels; ioctl(clients[i].fd, TIOCSSIZE, &ts); #endif #endif #ifdef USE_WINCHKILL #ifdef SYSV pg = getpgid(clients[i].pid); if (pg > 0) kill(pg, SIGWINCH); #else pg = getpgrp(clients[i].pid); if (pg > 0) killpg(pg, SIGWINCH); #endif #endif /* USE_WINCHKILL */ } } return; }