int lwip_sock_read(void *conn, unsigned char *buff, unsigned long len) { struct netbuf *new_buf=0; unsigned char *data; int data_len=0; int ret,newret; SYSCALL_DEBUG(" SOCK read :%x len:%d \n",buff,len); mutexLock(g_netBH_lock); ret=netconn_recv(conn, &new_buf); mutexUnLock(g_netBH_lock); if (ret!=ERR_OK){ SYSCALL_DEBUG(" Fail to recv data: %x newret:%x(%d) \n",ret,-ret,-ret); return 0; } netbuf_data(new_buf,&data,&data_len); SYSCALL_DEBUG(" SUCESS to recv data:%d ret:%d\n",data_len,ret); if (data_len > 0){ ut_memcpy(buff,data,ut_min(data_len,len)); ret = ut_min(data_len,len); }else{ ret = 0; } mutexLock(g_netBH_lock); netbuf_delete(new_buf); mutexUnLock(g_netBH_lock); return ret; }
/* syscall: yield - give up the processor to another thread, if it exists. A thread that has run out of work for the time being can use this syscall to immediately release the cpu rather than spin waiting until its timeslice runs out. This call will return when the scheduler picks the thread to run again, which could be immediately if there's no other threads waiting. NOTE: this syscall should really be called thread_yield :-/ => no parameters required <= all registers preserved */ void syscall_do_yield(int_registers_block *regs) { SYSCALL_DEBUG("[sys:%i] SYSCALL_YIELD called by process %i (%p) (thread %i)\n", CPU_ID, cpu_table[CPU_ID].current->proc->pid, cpu_table[CPU_ID].current->proc, cpu_table[CPU_ID].current->tid); sched_priority_calc(cpu_table[CPU_ID].current, priority_punish); sched_move_to_end(CPU_ID, cpu_table[CPU_ID].current); /* the syscall dispatch will call sched_pick() for us */ }
int lwip_sock_read_from(void *conn, unsigned char *buff, unsigned long len,struct sockaddr *sockaddr, int addr_len) { struct netbuf *new_buf=0; unsigned char *data; int data_len=0; int ret=0; SYSCALL_DEBUG(" SOCK recvfrom :%x len:%d \n",buff,len); mutexLock(g_netBH_lock); ret=netconn_recv(conn, &new_buf); mutexUnLock(g_netBH_lock); if (ret == ERR_TIMEOUT){ if (g_current_task->killed == 1){ return 0; } } if (ret!=ERR_OK){ SYSCALL_DEBUG(" Fail to recvfrom data: %x newret:%x(%d) \n",ret,-ret,-ret); return 0; } SYSCALL_DEBUG(" SUCESS to recv data:%d \n",ret); netbuf_data(new_buf,&data,&data_len); if (data_len > 0){ if (sockaddr != 0){ sockaddr->addr = new_buf->addr.addr; sockaddr->sin_port = new_buf->port; } ut_memcpy(buff,data,ut_min(data_len,len)); ret = ut_min(data_len,len); }else{ ret =0; } mutexLock(g_netBH_lock); netbuf_delete(new_buf); mutexUnLock(g_netBH_lock); return ret; }
/* syscall: exit - terminate execution of the current process */ void syscall_do_exit(int_registers_block *regs) { SYSCALL_DEBUG("[sys:%i] SYSCALL_EXIT called by process %i (%p) (thread %i)\n", CPU_ID, cpu_table[CPU_ID].current->proc->pid, cpu_table[CPU_ID].current->proc, cpu_table[CPU_ID].current->tid); /* request to be killed by the system executive */ msg_send_signal(proc_role_lookup(DIOSIX_ROLE_SYSTEM_EXECUTIVE), NULL, SIGXPROCEXIT, cpu_table[CPU_ID].current->proc->pid); /* remove from the run queue and mark as dying */ sched_remove(cpu_table[CPU_ID].current, dead); }
void *lwip_sock_open(int type) { void *ret; mutexLock(g_netBH_lock); if (type == SOCK_DGRAM) { ret = netconn_new(NETCONN_UDP); } else if (type == SOCK_STREAM ) { ret = netconn_new(NETCONN_TCP); } else { SYSCALL_DEBUG("Error socket Unknown type : %d \n",type); ret = 0; } mutexUnLock(g_netBH_lock); return ret; }
/* syscall thread_exit - end termination of the currently running thread. if it's the only thread in the process, the whole process will exit */ void syscall_do_thread_exit(int_registers_block *regs) { SYSCALL_DEBUG("[sys:%i] SYSCALL_THREAD_EXIT called by process %i (%p) (thread %i threads %i)\n", CPU_ID, cpu_table[CPU_ID].current->proc->pid, cpu_table[CPU_ID].current->proc, cpu_table[CPU_ID].current->tid, cpu_table[CPU_ID].current->proc->thread_count); /* check to see if this process has only one thread */ if(cpu_table[CPU_ID].current->proc->thread_count < 2) { syscall_do_exit(regs); return; } /* request to be killed by the system executive */ msg_send_signal(proc_role_lookup(DIOSIX_ROLE_SYSTEM_EXECUTIVE), NULL, SIGXTHREADEXIT, cpu_table[CPU_ID].current->proc->pid); /* remove from the run queue and mark as dying */ sched_remove(cpu_table[CPU_ID].current, dead); }
/* syscall:usrdebug - use the kernel to aid debugging of a userland process. => r0 = DIOSIX_DEBUG_WRITE: write string to the kernel's debug channel (root-owned processes only) r1 = pointer to null-terminated string <= r0 = 0 for succes or an error code */ void syscall_do_debug(int_registers_block *regs) { thread *current = cpu_table[CPU_ID].current; SYSCALL_DEBUG("[sys:%i] SYSCALL_USRDEBUG(%i) called by process %i (thread %i)\n", CPU_ID, regs->r0, current->proc->pid, current->tid); /* fill out the block, a bad pointer will page fault in the caller's virtual space */ switch(regs->r0) { case DIOSIX_DEBUG_WRITE: { char *str = (char *)regs->r1; /* sanity check pointer for badness */ if(!str) SYSCALL_RETURN(e_bad_address); /* check permissions */ if(current->proc->uid.effective != DIOSIX_SUPERUSER_ID) SYSCALL_RETURN(e_no_rights); dprintf("[debug:%i] *** pid %i tid %i role %i: ", CPU_ID, current->proc->pid, current->tid, current->proc->role); /* output one byte at a time, checking not to collide with kernel space */ while((unsigned int)str < KERNEL_SPACE_BASE && *str) dprintf("%c", *str++); SYSCALL_RETURN(success); } } /* fall through to returning an error code */ SYSCALL_RETURN(e_bad_params); }