1*12835Ssam /* kern_sig.c 5.18 83/05/30 */ 27421Sroot 39755Ssam #include "../machine/reg.h" 49755Ssam #include "../machine/pte.h" 59755Ssam #include "../machine/psl.h" 69755Ssam 77421Sroot #include "../h/param.h" 87421Sroot #include "../h/systm.h" 97421Sroot #include "../h/dir.h" 107421Sroot #include "../h/user.h" 117421Sroot #include "../h/inode.h" 127421Sroot #include "../h/proc.h" 137421Sroot #include "../h/timeb.h" 147421Sroot #include "../h/times.h" 157421Sroot #include "../h/conf.h" 167421Sroot #include "../h/buf.h" 177421Sroot #include "../h/mount.h" 187421Sroot #include "../h/text.h" 197421Sroot #include "../h/seg.h" 207421Sroot #include "../h/vm.h" 217421Sroot #include "../h/acct.h" 227818Sroot #include "../h/uio.h" 238117Sroot #include "../h/kernel.h" 249160Ssam #include "../h/nami.h" 257421Sroot 267499Sroot /* KILL CODE SHOULDNT KNOW ABOUT PROCESS INTERNALS !?! */ 277499Sroot 287499Sroot sigvec() 297421Sroot { 307421Sroot 317421Sroot } 327421Sroot 337499Sroot sigblock() 347421Sroot { 357499Sroot 367499Sroot } 377499Sroot 387499Sroot sigsetmask() 397499Sroot { 407499Sroot 417499Sroot } 427499Sroot 437499Sroot sigpause() 447499Sroot { 457499Sroot 467499Sroot } 477499Sroot 487499Sroot sigstack() 497499Sroot { 507499Sroot 517499Sroot } 527499Sroot 538764Sroot #ifdef notdef 548032Sroot kill() 558032Sroot { 568032Sroot 578032Sroot } 588764Sroot #endif 598032Sroot 608032Sroot killpg() 618032Sroot { 629989Ssam register struct a { 639989Ssam int pgrp; 649989Ssam int signo; 659989Ssam } *uap = (struct a *)u.u_ap; 668032Sroot 6712750Ssam u.u_error = kill1(1, uap->signo, uap->pgrp); 688032Sroot } 698032Sroot 7012750Ssam kill1(ispgrp, signo, who) 719989Ssam int ispgrp, signo, who; 729989Ssam { 739989Ssam register struct proc *p; 749989Ssam int f, priv = 0; 759989Ssam 76*12835Ssam if (signo < 0 || signo > NSIG) 779989Ssam return (EINVAL); 789989Ssam if (who > 0 && !ispgrp) { 799989Ssam p = pfind(who); 809989Ssam if (p == 0 || u.u_uid && u.u_uid != p->p_uid) 819989Ssam return (ESRCH); 82*12835Ssam if (signo) 83*12835Ssam psignal(p, signo); 849989Ssam return (0); 857421Sroot } 869989Ssam if (who == -1 && u.u_uid == 0) 879989Ssam priv++, who = 0, ispgrp = 1; /* like sending to pgrp */ 889989Ssam else if (who == 0) { 897421Sroot /* 907421Sroot * Zero process id means send to my process group. 917421Sroot */ 929989Ssam ispgrp = 1; 939989Ssam who = u.u_procp->p_pgrp; 949989Ssam if (who == 0) 959989Ssam return (EINVAL); 967421Sroot } 979989Ssam for (f = 0, p = proc; p < procNPROC; p++) { 987421Sroot if (p->p_stat == NULL) 997421Sroot continue; 1009989Ssam if (!ispgrp) { 1019989Ssam if (p->p_pid != who) 1027421Sroot continue; 1039989Ssam } else if (p->p_pgrp != who && priv == 0 || p->p_ppid == 0 || 1049989Ssam (p->p_flag&SSYS) || (priv && p == u.u_procp)) 1057421Sroot continue; 1067421Sroot if (u.u_uid != 0 && u.u_uid != p->p_uid && 1079989Ssam (signo != SIGCONT || !inferior(p))) 1087421Sroot continue; 1097421Sroot f++; 110*12835Ssam if (signo) 111*12835Ssam psignal(p, signo); 1127421Sroot } 11312750Ssam return (f == 0 ? ESRCH : 0); 1147421Sroot } 1157421Sroot 1167421Sroot /* 1177421Sroot * Send the specified signal to 1187421Sroot * all processes with 'pgrp' as 1197421Sroot * process group. 1207421Sroot * Called by tty.c for quits and 1217421Sroot * interrupts. 1227421Sroot */ 1237421Sroot gsignal(pgrp, sig) 1247421Sroot register int pgrp; 1257421Sroot { 1267421Sroot register struct proc *p; 1277421Sroot 1287421Sroot if (pgrp == 0) 1297421Sroot return; 1307421Sroot for(p = proc; p < procNPROC; p++) 1317421Sroot if (p->p_pgrp == pgrp) 1327421Sroot psignal(p, sig); 1337421Sroot } 1347421Sroot 1357421Sroot /* 1367421Sroot * Send the specified signal to 1377421Sroot * the specified process. 1387421Sroot */ 1397421Sroot psignal(p, sig) 1407421Sroot register struct proc *p; 1417421Sroot register int sig; 1427421Sroot { 1437421Sroot register int s; 1447421Sroot register int (*action)(); 1457421Sroot long sigmask; 1467421Sroot 1477421Sroot if ((unsigned)sig >= NSIG) 1487421Sroot return; 1497421Sroot sigmask = (1L << (sig-1)); 1507421Sroot 1517421Sroot /* 1527421Sroot * If proc is traced, always give parent a chance. 1537421Sroot * Otherwise get the signal action from the bits in the proc table. 1547421Sroot */ 1557421Sroot if (p->p_flag & STRC) 1567421Sroot action = SIG_DFL; 1577421Sroot else { 1587421Sroot s = (p->p_siga1&sigmask) != 0; 1597421Sroot s <<= 1; 1607421Sroot s |= (p->p_siga0&sigmask) != 0; 1617421Sroot action = (int(*)())s; 1627421Sroot /* 1637421Sroot * If the signal is ignored, we forget about it immediately. 1647421Sroot */ 1657421Sroot if (action == SIG_IGN) 1667421Sroot return; 1677421Sroot } 1687421Sroot #define mask(sig) (1<<(sig-1)) 1697421Sroot #define stops (mask(SIGSTOP)|mask(SIGTSTP)|mask(SIGTTIN)|mask(SIGTTOU)) 1707421Sroot if (sig) { 1717421Sroot p->p_sig |= sigmask; 1727421Sroot switch (sig) { 1737421Sroot 1747421Sroot case SIGTERM: 1757421Sroot if ((p->p_flag&STRC) != 0 || action != SIG_DFL) 1767421Sroot break; 1777421Sroot /* fall into ... */ 1787421Sroot 1797421Sroot case SIGKILL: 1807421Sroot if (p->p_nice > NZERO) 1817421Sroot p->p_nice = NZERO; 1827421Sroot break; 1837421Sroot 1847421Sroot case SIGCONT: 1857421Sroot p->p_sig &= ~stops; 1867421Sroot break; 1877421Sroot 1887421Sroot case SIGSTOP: 1897421Sroot case SIGTSTP: 1907421Sroot case SIGTTIN: 1917421Sroot case SIGTTOU: 1927421Sroot p->p_sig &= ~mask(SIGCONT); 1937421Sroot break; 1947421Sroot } 1957421Sroot } 1967421Sroot #undef mask 1977421Sroot #undef stops 1987421Sroot /* 1997421Sroot * Defer further processing for signals which are held. 2007421Sroot */ 2017421Sroot if (action == SIG_HOLD) 2027421Sroot return; 2037421Sroot s = spl6(); 2047421Sroot switch (p->p_stat) { 2057421Sroot 2067421Sroot case SSLEEP: 2077421Sroot /* 2087421Sroot * If process is sleeping at negative priority 2097421Sroot * we can't interrupt the sleep... the signal will 2107421Sroot * be noticed when the process returns through 2117421Sroot * trap() or syscall(). 2127421Sroot */ 2137421Sroot if (p->p_pri <= PZERO) 2147421Sroot goto out; 2157421Sroot /* 2167421Sroot * Process is sleeping and traced... make it runnable 2177421Sroot * so it can discover the signal in issig() and stop 2187421Sroot * for the parent. 2197421Sroot */ 2207421Sroot if (p->p_flag&STRC) 2217421Sroot goto run; 2227421Sroot switch (sig) { 2237421Sroot 2247421Sroot case SIGSTOP: 2257421Sroot case SIGTSTP: 2267421Sroot case SIGTTIN: 2277421Sroot case SIGTTOU: 2287421Sroot /* 2297421Sroot * These are the signals which by default 2307421Sroot * stop a process. 2317421Sroot */ 2327421Sroot if (action != SIG_DFL) 2337421Sroot goto run; 2347421Sroot /* 2357421Sroot * Don't clog system with children of init 2367421Sroot * stopped from the keyboard. 2377421Sroot */ 2387421Sroot if (sig != SIGSTOP && p->p_pptr == &proc[1]) { 2397421Sroot psignal(p, SIGKILL); 2407421Sroot p->p_sig &= ~sigmask; 2417421Sroot splx(s); 2427421Sroot return; 2437421Sroot } 2447421Sroot /* 2457421Sroot * If a child in vfork(), stopping could 2467421Sroot * cause deadlock. 2477421Sroot */ 2487421Sroot if (p->p_flag&SVFORK) 2497421Sroot goto out; 2507421Sroot p->p_sig &= ~sigmask; 2517421Sroot p->p_cursig = sig; 2527421Sroot stop(p); 2537421Sroot goto out; 2547421Sroot 2557421Sroot case SIGIO: 2567421Sroot case SIGURG: 2577421Sroot case SIGCHLD: 2587421Sroot /* 2597421Sroot * These signals are special in that they 2607421Sroot * don't get propogated... if the process 2617421Sroot * isn't interested, forget it. 2627421Sroot */ 2637421Sroot if (action != SIG_DFL) 2647421Sroot goto run; 2657421Sroot p->p_sig &= ~sigmask; /* take it away */ 2667421Sroot goto out; 2677421Sroot 2687421Sroot default: 2697421Sroot /* 2707421Sroot * All other signals cause the process to run 2717421Sroot */ 2727421Sroot goto run; 2737421Sroot } 2747421Sroot /*NOTREACHED*/ 2757421Sroot 2767421Sroot case SSTOP: 2777421Sroot /* 2787421Sroot * If traced process is already stopped, 2797421Sroot * then no further action is necessary. 2807421Sroot */ 2817421Sroot if (p->p_flag&STRC) 2827421Sroot goto out; 2837421Sroot switch (sig) { 2847421Sroot 2857421Sroot case SIGKILL: 2867421Sroot /* 2877421Sroot * Kill signal always sets processes running. 2887421Sroot */ 2897421Sroot goto run; 2907421Sroot 2917421Sroot case SIGCONT: 2927421Sroot /* 2937421Sroot * If the process catches SIGCONT, let it handle 2947421Sroot * the signal itself. If it isn't waiting on 2957421Sroot * an event, then it goes back to run state. 2967421Sroot * Otherwise, process goes back to sleep state. 2977421Sroot */ 2987421Sroot if (action != SIG_DFL || p->p_wchan == 0) 2997421Sroot goto run; 3007421Sroot p->p_stat = SSLEEP; 3017421Sroot goto out; 3027421Sroot 3037421Sroot case SIGSTOP: 3047421Sroot case SIGTSTP: 3057421Sroot case SIGTTIN: 3067421Sroot case SIGTTOU: 3077421Sroot /* 3087421Sroot * Already stopped, don't need to stop again. 3097421Sroot * (If we did the shell could get confused.) 3107421Sroot */ 3117421Sroot p->p_sig &= ~sigmask; /* take it away */ 3127421Sroot goto out; 3137421Sroot 3147421Sroot default: 3157421Sroot /* 3167421Sroot * If process is sleeping interruptibly, then 3177421Sroot * unstick it so that when it is continued 3187421Sroot * it can look at the signal. 3197421Sroot * But don't setrun the process as its not to 3207421Sroot * be unstopped by the signal alone. 3217421Sroot */ 3227421Sroot if (p->p_wchan && p->p_pri > PZERO) 3237421Sroot unsleep(p); 3247421Sroot goto out; 3257421Sroot } 3267421Sroot /*NOTREACHED*/ 3277421Sroot 3287421Sroot default: 3297421Sroot /* 3307421Sroot * SRUN, SIDL, SZOMB do nothing with the signal, 3317421Sroot * other than kicking ourselves if we are running. 3327421Sroot * It will either never be noticed, or noticed very soon. 3337421Sroot */ 3347421Sroot if (p == u.u_procp && !noproc) 3358444Sroot #include "../vax/mtpr.h" 3367421Sroot aston(); 3377421Sroot goto out; 3387421Sroot } 3397421Sroot /*NOTREACHED*/ 3407421Sroot run: 3417421Sroot /* 3427421Sroot * Raise priority to at least PUSER. 3437421Sroot */ 3447421Sroot if (p->p_pri > PUSER) 3457421Sroot if ((p != u.u_procp || noproc) && p->p_stat == SRUN && 3467421Sroot (p->p_flag & SLOAD)) { 3477421Sroot remrq(p); 3487421Sroot p->p_pri = PUSER; 3497421Sroot setrq(p); 3507421Sroot } else 3517421Sroot p->p_pri = PUSER; 3527421Sroot setrun(p); 3537421Sroot out: 3547421Sroot splx(s); 3557421Sroot } 3567421Sroot 3577421Sroot /* 3587421Sroot * Returns true if the current 3597421Sroot * process has a signal to process. 3607421Sroot * The signal to process is put in p_cursig. 3617421Sroot * This is asked at least once each time a process enters the 3627421Sroot * system (though this can usually be done without actually 3637421Sroot * calling issig by checking the pending signal masks.) 3647421Sroot * A signal does not do anything 3657421Sroot * directly to a process; it sets 3667421Sroot * a flag that asks the process to 3677421Sroot * do something to itself. 3687421Sroot */ 3697421Sroot issig() 3707421Sroot { 3717421Sroot register struct proc *p; 3727421Sroot register int sig; 3737421Sroot long sigbits; 3747421Sroot long sigmask; 3757421Sroot 3767421Sroot p = u.u_procp; 3777421Sroot for (;;) { 3787421Sroot sigbits = p->p_sig; 3797421Sroot if ((p->p_flag&STRC) == 0) 3807421Sroot sigbits &= ~p->p_ignsig; 3817421Sroot if (p->p_flag&SVFORK) 3827421Sroot #define bit(a) (1<<(a-1)) 3837421Sroot sigbits &= ~(bit(SIGSTOP)|bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 3847421Sroot if (sigbits == 0) 3857421Sroot break; 3867421Sroot sig = ffs((int)sigbits); 3877421Sroot sigmask = 1L << (sig-1); 3887421Sroot p->p_sig &= ~sigmask; /* take the signal! */ 3897421Sroot p->p_cursig = sig; 3907421Sroot if (p->p_flag&STRC && (p->p_flag&SVFORK)==0) { 3917421Sroot /* 3927421Sroot * If traced, always stop, and stay 3937421Sroot * stopped until released by the parent. 3947421Sroot */ 3957421Sroot do { 3967421Sroot stop(p); 3977421Sroot swtch(); 3987421Sroot } while (!procxmt() && p->p_flag&STRC); 3997421Sroot 4007421Sroot /* 4017421Sroot * If the traced bit got turned off, 4027421Sroot * then put the signal taken above back into p_sig 4037421Sroot * and go back up to the top to rescan signals. 4047421Sroot * This ensures that siga0 and u_signal are consistent. 4057421Sroot */ 4067421Sroot if ((p->p_flag&STRC) == 0) { 4077421Sroot p->p_sig |= sigmask; 4087421Sroot continue; 4097421Sroot } 4107421Sroot 4117421Sroot /* 4127421Sroot * If parent wants us to take the signal, 4137421Sroot * then it will leave it in p->p_cursig; 4147421Sroot * otherwise we just look for signals again. 4157421Sroot */ 4167421Sroot sig = p->p_cursig; 4177421Sroot if (sig == 0) 4187421Sroot continue; 4197421Sroot } 4207421Sroot switch (u.u_signal[sig]) { 4217421Sroot 4227421Sroot case SIG_DFL: 4237421Sroot /* 4247421Sroot * Don't take default actions on system processes. 4257421Sroot */ 4267421Sroot if (p->p_ppid == 0) 4277421Sroot break; 4287421Sroot switch (sig) { 4297421Sroot 4307421Sroot case SIGTSTP: 4317421Sroot case SIGTTIN: 4327421Sroot case SIGTTOU: 4337421Sroot /* 4347421Sroot * Children of init aren't allowed to stop 4357421Sroot * on signals from the keyboard. 4367421Sroot */ 4377421Sroot if (p->p_pptr == &proc[1]) { 4387421Sroot psignal(p, SIGKILL); 4397421Sroot continue; 4407421Sroot } 4417421Sroot /* fall into ... */ 4427421Sroot 4437421Sroot case SIGSTOP: 4447421Sroot if (p->p_flag&STRC) 4457421Sroot continue; 4467421Sroot stop(p); 4477421Sroot swtch(); 4487421Sroot continue; 4497421Sroot 4507421Sroot case SIGCONT: 4517421Sroot case SIGCHLD: 4527421Sroot /* 4537421Sroot * These signals are normally not 4547421Sroot * sent if the action is the default. 4557421Sroot */ 4567421Sroot continue; /* == ignore */ 4577421Sroot 4587421Sroot default: 4597421Sroot goto send; 4607421Sroot } 4617421Sroot /*NOTREACHED*/ 4627421Sroot 4637421Sroot case SIG_HOLD: 4647421Sroot case SIG_IGN: 4657421Sroot /* 4667421Sroot * Masking above should prevent us 4677421Sroot * ever trying to take action on a held 4687421Sroot * or ignored signal, unless process is traced. 4697421Sroot */ 4707421Sroot if ((p->p_flag&STRC) == 0) 4717421Sroot printf("issig\n"); 4727421Sroot continue; 4737421Sroot 4747421Sroot default: 4757421Sroot /* 4767421Sroot * This signal has an action, let 4777421Sroot * psig process it. 4787421Sroot */ 4797421Sroot goto send; 4807421Sroot } 4817421Sroot /*NOTREACHED*/ 4827421Sroot } 4837421Sroot /* 4847421Sroot * Didn't find a signal to send. 4857421Sroot */ 4867421Sroot p->p_cursig = 0; 4877421Sroot return (0); 4887421Sroot 4897421Sroot send: 4907421Sroot /* 4917421Sroot * Let psig process the signal. 4927421Sroot */ 4937421Sroot return (sig); 4947421Sroot } 4957421Sroot 4967421Sroot /* 4977421Sroot * Put the argument process into the stopped 4987421Sroot * state and notify the parent via wakeup and/or signal. 4997421Sroot */ 5007421Sroot stop(p) 5017421Sroot register struct proc *p; 5027421Sroot { 5037421Sroot 5047421Sroot p->p_stat = SSTOP; 5057421Sroot p->p_flag &= ~SWTED; 5067421Sroot wakeup((caddr_t)p->p_pptr); 5077421Sroot /* 5087421Sroot * Avoid sending signal to parent if process is traced 5097421Sroot */ 5107421Sroot if (p->p_flag&STRC) 5117421Sroot return; 5127421Sroot psignal(p->p_pptr, SIGCHLD); 5137421Sroot } 5147421Sroot 5157421Sroot /* 5167421Sroot * Perform the action specified by 5177421Sroot * the current signal. 5187421Sroot * The usual sequence is: 5197421Sroot * if (issig()) 5207421Sroot * psig(); 5217421Sroot * The signal bit has already been cleared by issig, 5227421Sroot * and the current signal number stored in p->p_cursig. 5237421Sroot */ 5247421Sroot psig() 5257421Sroot { 5267421Sroot register struct proc *rp = u.u_procp; 5277421Sroot register int n = rp->p_cursig; 5287421Sroot long sigmask = 1L << (n-1); 5297421Sroot register int (*action)(); 5307421Sroot 5317421Sroot if (rp->p_cursig == 0) 5327421Sroot panic("psig"); 5337421Sroot action = u.u_signal[n]; 5347421Sroot if (action != SIG_DFL) { 5357421Sroot if (action == SIG_IGN || action == SIG_HOLD) 5367421Sroot panic("psig action"); 5377421Sroot u.u_error = 0; 5387421Sroot if (n != SIGILL && n != SIGTRAP) 5397421Sroot u.u_signal[n] = 0; 5407421Sroot /* 5417421Sroot * If this catch value indicates automatic holding of 5427421Sroot * subsequent signals, set the hold value. 5437421Sroot */ 5447421Sroot if (SIGISDEFER(action)) { 5457421Sroot (void) spl6(); 54612750Ssam /* SIG_HOLD known to be 3 */ 54712750Ssam rp->p_siga0 |= sigmask; 54812750Ssam rp->p_siga1 |= sigmask; 5497421Sroot u.u_signal[n] = SIG_HOLD; 5507421Sroot (void) spl0(); 5517421Sroot action = SIGUNDEFER(action); 5527421Sroot } 5538032Sroot u.u_ru.ru_nsignals++; 5547421Sroot sendsig(action, n); 5557421Sroot rp->p_cursig = 0; 5567421Sroot return; 5577421Sroot } 5587421Sroot u.u_acflag |= AXSIG; 5597421Sroot switch (n) { 5607421Sroot 5617421Sroot case SIGILL: 5627421Sroot case SIGIOT: 5637421Sroot case SIGBUS: 5647421Sroot case SIGQUIT: 5657421Sroot case SIGTRAP: 5667421Sroot case SIGEMT: 5677421Sroot case SIGFPE: 5687421Sroot case SIGSEGV: 5697421Sroot case SIGSYS: 5707421Sroot u.u_arg[0] = n; 5717421Sroot if (core()) 5727421Sroot n += 0200; 5737421Sroot } 5747421Sroot exit(n); 5757421Sroot } 5767421Sroot 5777421Sroot /* 5787421Sroot * Create a core image on the file "core" 5797421Sroot * If you are looking for protection glitches, 5807421Sroot * there are probably a wealth of them here 5817421Sroot * when this occurs to a suid command. 5827421Sroot * 5837421Sroot * It writes UPAGES block of the 5847421Sroot * user.h area followed by the entire 5857421Sroot * data+stack segments. 5867421Sroot */ 5877421Sroot core() 5887421Sroot { 5897421Sroot register struct inode *ip; 5907421Sroot extern schar(); 5917421Sroot 59212639Ssam if (u.u_uid != u.u_ruid || u.u_gid != u.u_rgid) 5937818Sroot return (0); 5948032Sroot if (ctob(UPAGES+u.u_dsize+u.u_ssize) >= 5958032Sroot u.u_rlimit[RLIMIT_CORE].rlim_cur) 5967421Sroot return (0); 5977421Sroot u.u_error = 0; 5987421Sroot u.u_dirp = "core"; 5999160Ssam ip = namei(schar, CREATE, 1); 6007421Sroot if (ip == NULL) { 6017421Sroot if (u.u_error) 6027421Sroot return (0); 60312639Ssam ip = maknode(0644); 6047421Sroot if (ip==NULL) 6057421Sroot return (0); 6067421Sroot } 6077818Sroot if (access(ip, IWRITE) || 6087818Sroot (ip->i_mode&IFMT) != IFREG || 6097818Sroot ip->i_nlink != 1) { 6107421Sroot u.u_error = EFAULT; 6117818Sroot goto out; 6127818Sroot } 6139160Ssam itrunc(ip, (u_long)0); 6147818Sroot u.u_acflag |= ACORE; 6158967Sroot /* if (u.u_error == 0) */ 6168967Sroot u.u_error = rdwri(UIO_WRITE, ip, 6178967Sroot (caddr_t)&u, 6188967Sroot ctob(UPAGES), 6198967Sroot 0, 1, (int *)0); 6208101Sroot if (u.u_error == 0) 6218644Sroot u.u_error = rdwri(UIO_WRITE, ip, 6228967Sroot (caddr_t)ctob(dptov(u.u_procp, 0)), 6238967Sroot ctob(u.u_dsize), 6248644Sroot ctob(UPAGES), 0, (int *)0); 6258101Sroot if (u.u_error == 0) 6268644Sroot u.u_error = rdwri(UIO_WRITE, ip, 6278967Sroot (caddr_t)ctob(sptov(u.u_procp, u.u_ssize - 1)), 6288967Sroot ctob(u.u_ssize), 6298644Sroot ctob(UPAGES)+ctob(u.u_dsize), 0, (int *)0); 6307818Sroot out: 6317421Sroot iput(ip); 6327818Sroot return (u.u_error == 0); 6337421Sroot } 634