Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
«<br />
«<br />
«<br />
288 volume VI os16<br />
104.9.28 kernel/proc/proc_sys_wait.c<br />
Si veda la sezione 103.8.27.<br />
1930001 |#include <br />
1930002 |#include <br />
1930003 |//----------------------------------------------------------------------<br />
1930004 |pid_t<br />
1930005 |proc_sys_wait (pid_t pid, int *status)<br />
1930006 |{<br />
1930007 | pid_t parent = pid;<br />
1930008 | pid_t child;<br />
1930009 | int child_available = 0;<br />
1930010 | //<br />
1930011 | // Find a dead child process.<br />
1930012 | //<br />
1930013 | for (child = 1; child < PROCESS_MAX; child++)<br />
1930014 | {<br />
1930015 | if (proc_table[child].ppid == parent)<br />
1930016 | {<br />
1930017 | child_available = 1; // Child found!<br />
1930018 | if (proc_table[child].status == PROC_ZOMBIE)<br />
1930019 | {<br />
1930020 | break; // It is dead!<br />
1930021 | }<br />
1930022 | }<br />
1930023 | }<br />
1930024 | //<br />
1930025 | // If the index ‘child’ is a valid process number,<br />
1930026 | // a dead child was found.<br />
1930027 | //<br />
1930028 | if (child < PROCESS_MAX)<br />
1930029 | {<br />
1930030 | *status = proc_table[child].ret;<br />
1930031 | proc_available (child);<br />
1930032 | return (child);<br />
1930033 | }<br />
1930034 | else<br />
1930035 | {<br />
1930036 | if (child_available)<br />
1930037 | {<br />
1930038 | //<br />
1930039 | // There are child, but all alive.<br />
1930040 | //<br />
1930041 | // Go to sleep.<br />
1930042 | //<br />
1930043 | proc_table[parent].status = PROC_SLEEPING;<br />
1930044 | proc_table[parent].wakeup_events |= WAKEUP_EVENT_SIGNAL;<br />
1930045 | proc_table[parent].wakeup_signal = SIGCHLD;<br />
1930046 | return ((pid_t) 0);<br />
1930047 | }<br />
1930048 | else<br />
1930049 | {<br />
1930050 | //<br />
1930051 | // There are no child at all.<br />
1930052 | //<br />
1930053 | errset (ECHILD);<br />
1930054 | return ((pid_t) -1);<br />
1930055 | }<br />
1930056 | }<br />
1930057 |}<br />
104.9.29 kernel/proc/proc_table.c<br />
Si veda la sezione 103.8.7.<br />
1940001 |#include <br />
1940002 |//----------------------------------------------------------------------<br />
1940003 |proc_t proc_table[PROCESS_MAX];<br />
104.9.30 kernel/proc/sysroutine.c<br />
Si veda la sezione 103.8.28.<br />
1950001 |#include <br />
1950002 |#include <br />
1950003 |#include <br />
1950004 |//----------------------------------------------------------------------<br />
1950005 |static void sysroutine_error_back (int *number, int *line,<br />
1950006 | char *file_name);<br />
1950007 |//----------------------------------------------------------------------<br />
1950008 |void<br />
1950009 |sysroutine (uint16_t *sp, segment_t *segment_d, uint16_t syscallnr,<br />
1950010 | uint16_t msg_off, uint16_t msg_size)<br />
1950011 |{<br />
1950012 | pid_t pid = proc_find (*segment_d);<br />
1950013 | addr_t msg_addr = address (*segment_d, msg_off);<br />
1950014 | //<br />
1950015 | // Inbox.<br />
1950016 | //<br />
1950017 | union {<br />
1950018 | sysmsg_chdir_t chdir;<br />
1950019 | sysmsg_chmod_t chmod;<br />
1950020 | sysmsg_chown_t chown;<br />
1950021 | sysmsg_clock_t clock;<br />
1950022 | sysmsg_close_t close;<br />
1950023 | sysmsg_dup_t dup;<br />
1950024 | sysmsg_dup2_t dup2;<br />
1950025 | sysmsg_exec_t exec;<br />
1950026 | sysmsg_exit_t exit;<br />
1950027 | sysmsg_fchmod_t fchmod;<br />
1950028 | sysmsg_fchown_t fchown;<br />
1950029 | sysmsg_fcntl_t fcntl;<br />
1950030 | sysmsg_fork_t fork;<br />
1950031 | sysmsg_fstat_t fstat;<br />
1950032 | sysmsg_kill_t kill;<br />
1950033 | sysmsg_link_t link;<br />
1950034 | sysmsg_lseek_t lseek;<br />
1950035 | sysmsg_mkdir_t mkdir;<br />
1950036 | sysmsg_mknod_t mknod;<br />
1950037 | sysmsg_mount_t mount;<br />
1950038 | sysmsg_open_t open;<br />
1950039 | sysmsg_read_t read;<br />
1950040 | sysmsg_seteuid_t seteuid;<br />
1950041 | sysmsg_setuid_t setuid;<br />
Script e sorgenti del kernel 289<br />
1950042 | sysmsg_signal_t signal;<br />
1950043 | sysmsg_sleep_t sleep;<br />
1950044 | sysmsg_stat_t stat;<br />
1950045 | sysmsg_stime_t stime;<br />
1950046 | sysmsg_time_t time;<br />
1950047 | sysmsg_uarea_t uarea;<br />
1950048 | sysmsg_umask_t umask;<br />
1950049 | sysmsg_umount_t umount;<br />
1950050 | sysmsg_unlink_t unlink;<br />
1950051 | sysmsg_wait_t wait;<br />
1950052 | sysmsg_write_t write;<br />
1950053 | sysmsg_zpchar_t zpchar;<br />
1950054 | sysmsg_zpstring_t zpstring;<br />
1950055 | } msg;<br />
1950056 | //<br />
1950057 | // Verify if the system call was emitted from kernel code.<br />
1950058 | // The kernel can emit only some particular system call:<br />
1950059 | // SYS_NULL, to let other processes run;<br />
1950060 | // SYS_FORK, to let fork itself;<br />
1950061 | // SYS_EXEC, to replace a forked copy of itself.<br />
1950062 | //<br />
1950063 | if (pid == 0)<br />
1950064 | {<br />
1950065 | //<br />
1950066 | // This is the kernel code!<br />
1950067 | //<br />
1950068 | if ( syscallnr != SYS_0<br />
1950069 | && syscallnr != SYS_FORK<br />
1950070 | && syscallnr != SYS_EXEC)<br />
1950071 | {<br />
1950072 | k_printf ("kernel panic: the system call %i ", syscallnr);<br />
1950073 | k_printf ("was received while running in kernel space!\n");<br />
1950074 | }<br />
1950075 | }<br />
1950076 | //<br />
1950077 | // Entering a system call, the kernel variable ‘errno’ must be<br />
1950078 | // reset, otherwise, a previous kernel code error might be returned<br />
1950079 | // to the applications.<br />
1950080 | //<br />
1950081 | errno = 0;<br />
1950082 | errln = 0;<br />
1950083 | errfn[0] = 0;<br />
1950084 | //<br />
1950085 | // Get message.<br />
1950086 | //<br />
1950087 | dev_io (pid, DEV_MEM, DEV_READ, msg_addr, &msg, msg_size, NULL);<br />
1950088 | //<br />
1950089 | // Do the request from the received system call.<br />
1950090 | //<br />
1950091 | switch (syscallnr)<br />
1950092 | {<br />
1950093 | case SYS_0:<br />
1950094 | break;<br />
1950095 | case SYS_CHDIR:<br />
1950096 | msg.chdir.ret = path_chdir (pid, msg.chdir.path);<br />
1950097 | sysroutine_error_back (&msg.chdir.errno, &msg.chdir.errln,<br />
1950098 | msg.chdir.errfn);<br />
1950099 | break;<br />
1950100 | case SYS_CHMOD:<br />
1950101 | msg.chmod.ret = path_chmod (pid, msg.chmod.path,<br />
1950102 | msg.chmod.mode);<br />
1950103 | sysroutine_error_back (&msg.chmod.errno, &msg.chmod.errln,<br />
1950104 | msg.chmod.errfn);<br />
1950105 | break;<br />
1950106 | case SYS_CHOWN:<br />
1950107 | msg.chown.ret = path_chown (pid, msg.chown.path,<br />
1950108 | msg.chown.uid,<br />
1950109 | msg.chown.gid);<br />
1950110 | sysroutine_error_back (&msg.chown.errno, &msg.chown.errln,<br />
1950111 | msg.chown.errfn);<br />
1950112 | break;<br />
1950113 | case SYS_CLOCK:<br />
1950114 | msg.clock.ret = k_clock ();<br />
1950115 | break;<br />
1950116 | case SYS_CLOSE:<br />
1950117 | msg.close.ret = fd_close (pid, msg.close.fdn);<br />
1950118 | sysroutine_error_back (&msg.close.errno, &msg.close.errln,<br />
1950119 | msg.close.errfn);<br />
1950120 | break;<br />
1950121 | case SYS_DUP:<br />
1950122 | msg.dup.ret = fd_dup (pid, msg.dup.fdn_old, 0);<br />
1950123 | sysroutine_error_back (&msg.dup.errno, &msg.dup.errln,<br />
1950124 | msg.dup.errfn);<br />
1950125 | break;<br />
1950126 | case SYS_DUP2:<br />
1950127 | msg.dup2.ret = fd_dup2 (pid, msg.dup2.fdn_old,<br />
1950128 | msg.dup2.fdn_new);<br />
1950129 | sysroutine_error_back (&msg.dup2.errno, &msg.dup2.errln,<br />
1950130 | msg.dup2.errfn);<br />
1950131 | break;<br />
1950132 | case SYS_EXEC:<br />
1950133 | msg.exec.ret = proc_sys_exec (sp, segment_d, pid,<br />
1950134 | msg.exec.path,<br />
1950135 | msg.exec.argc,<br />
1950136 | msg.exec.arg_data,<br />
1950137 | msg.exec.envc,<br />
1950138 | msg.exec.env_data);<br />
1950139 | msg.exec.uid = proc_table[pid].uid;<br />
1950140 | msg.exec.euid = proc_table[pid].euid;<br />
1950141 | sysroutine_error_back (&msg.exec.errno, &msg.exec.errln,<br />
1950142 | msg.exec.errfn);<br />
1950143 | break;<br />
1950144 | case SYS_EXIT:<br />
1950145 | if (pid == 0)<br />
1950146 | {<br />
1950147 | k_printf ("kernel alert: "<br />
1950148 | "the kernel cannot exit!\n");<br />
1950149 | }<br />
1950150 | else<br />
1950151 | {<br />
1950152 | proc_sys_exit (pid, msg.exit.status);<br />
1950153 | }<br />
1950154 | break;<br />
1950155 | case SYS_FCHMOD:<br />
1950156 | msg.fchmod.ret = fd_chmod (pid, msg.fchmod.fdn,<br />
1950157 | msg.fchmod.mode);