Example #1
0
/*-------------------------------------------
| Name:_system_exit
| Description:
| Parameters:
| Return Type:
| Comments:
| See:
---------------------------------------------*/
void _system_exit(int status) {
    kernel_pthread_t* pthread_ptr= kernel_pthread_self();
    pid_t pid = pthread_ptr->pid;
    exit_t exit_dt;

#if ATEXIT_MAX>0
    {
        atexit_func_t* p_atexit_func;
        while( *(p_atexit_func = process_lst[pid]->p_atexit_func++) ) {
            (*p_atexit_func)();
        }
    }
#endif

    //mutex stdio release
    if(pthread_ptr->stat&PTHREAD_STATUS_SIGHANDLER) {
        //to do lonjmp() will must use this method to release semaphore;
        //release semaphore stdio_sem (instead of use atexit()???;)
#if !defined(__KERNEL_LOAD_LIB)
        kernel_pthread_mutex_destroy(&stdin->mutex);
        kernel_pthread_mutex_destroy(&stdout->mutex);
        kernel_pthread_mutex_destroy(&stderr->mutex);
#endif
    }


    exit_dt.pid=pid;
    exit_dt.status = status;

    __mk_syscall(_SYSCALL_EXIT,exit_dt);
    //no return: thread is destroyed
}
/**
 * \brief Start listening to the specified port. Standard BSD listen() with internal name.
 * \param[in] desc socket descriptor to start listening on.
 * \param[in] maxcon is be the maximum TCP connections to accept on that socket. Unsued parameter with current implementation.
 * \details To accept connections, a socket is first created with socket(), 
            a willingness to accept incoming connections is specified with listen(), 
            and then the connections are accepted with accept(). The listen() call applies only to sockets of type \ref SOCK_STREAM (TCP).
 * \note Default maximum number of connections unknown?
 * \return On connection success, zero is returned. On error, -1 is returned.
 * \callgraph
 */
int _sys_sock_listen(int fd,int maxcon){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   hsock_t hsock  = 0;
   desc_t desc;
   //
   //
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(fd<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   if(((socket_t*)hsock)->protocol!=IPPROTO_TCP){
      __set_kernel_pthread_errno (EPROTONOSUPPORT);
      return -1;
   }
   //lock
   __lock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   __lock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //
   ((socket_t*)hsock)->state = STATE_SOCKET_LISTEN;
   #if UIP_CONF_IPV6
   uip_listen( (u16_t)( ((socket_t*)hsock)->addr_in.sin6_port) );
   #else
   uip_listen( (u16_t)( ((socket_t*)hsock)->addr_in.sin_port) );
   #endif
   //unlock
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //
   __set_kernel_pthread_errno (0);
   //
   return 0;
#else
   return -1;
#endif
} //end of _sys_sock_listen()
/*
 * Return current thread's timeout info
 */
struct sys_timeouts *sys_arch_timeouts(void)
{
   struct lwip_thread *t;
   kernel_pthread_t* pthread;

   pthread = kernel_pthread_self();

   //p_task = OS_GetpCurrentTask();

   for(t = threads; t; t = t->next)
      if (&t->t == pthread)
         return &(t->to);

   to.next=(struct sys_timeout *)0;
   return &to;
}
/*-------------------------------------------
| Name:_slip_send_packet
| Description:
| Parameters:
| Return Type:
| Comments:sends a packet of length "len", starting at
| location "p".
| See:
---------------------------------------------*/
int _dev_slip_write_c(desc_t desc, const unsigned char c, int last){
   int cb=-1;

#ifdef USE_SLIP_WRITE_BUFFER
   if(!(ofile_lst[desc].oflag&O_NONBLOCK)) {

      desc_t slip_desc=ofile_lst[desc].desc_prv;
      slip_write_t* p_slip_write = &(((slip_io_t*)ofile_lst[slip_desc].p)->write);
      if(!p_slip_write)
         return -1;

      p_slip_write->buf[p_slip_write->cb++]=c;

      if(last) {
         cb = p_slip_write->cb;
         p_slip_write->cb = 0;
         if((cb = ofile_lst[desc].pfsop->fdev.fdev_write(desc,p_slip_write->buf,cb))<0) {
            return -1;
         }
      }
   }
   return 1;

#else
   kernel_pthread_t* pthread_ptr;

   if(!(pthread_ptr = kernel_pthread_self()))
      return -1;
   if(!(ofile_lst[desc].oflag&O_NONBLOCK)) {
      if((cb = ofile_lst[desc].pfsop->fdev.fdev_write(desc,(void*)&c,1))<0) {
         return -1;
      }

      //see write() in devio.c. write wait an event from last character
      //fix a deadlock pb in this case.
      if(last)
         return cb;

      do {
         __wait_io_int(pthread_ptr);
      } while(ofile_lst[desc].pfsop->fdev.fdev_isset_write
              && ofile_lst[desc].pfsop->fdev.fdev_isset_write(desc));
   }
   return cb;
#endif
}
/**
 * \brief Closes a socket. Standard BSD shutdown() with internal name.
 * \param[in]  desc socket descriptor to close.
 * \param[in]  how Shutdown method : \ref SHUT_RD, \ref SHUT_WR or \ref SHUT_RDWR. 
 * \note Similar to "close()" BSD function when using \ref SHUT_RDWR method (no need to call close()).
 * \note Only \ref SHUT_RDWR is supported with current implementation.
 * \return shutdown() returns 0 on success and -1 on failure.
 * \callgraph
 */
int _sys_sock_shutdown(int fd, int how){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   kernel_pthread_t* pthread_ptr;
   //
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(how != SHUT_RDWR){
      __set_kernel_pthread_errno (EOPNOTSUPP);
      return -1; //only SHUT_RDWR is supported with current implementation
   }
   //
   return(_sys_sock_close(fd));
#else
   return -1;
#endif
} //end of _sys_sock_shutdown()
/*--------------------------------------------
| Name:        kernel_sigqueue_wait
| Description:
| Parameters:  none
| Return Type: none
| Comments:
| See:
----------------------------------------------*/
int kernel_sigqueue_wait(struct kernel_sigevent_st* kernel_sigevent){
   struct kernel_sigqueue_st* p= &kernel_pthread_self()->kernel_sigqueue;
   if(!p)
      return -1;
   //wait event
   if(kernel_sem_wait(&p->kernel_sem->object.kernel_object_sem.kernel_sem)<0)
      return -1;

   //extract sigevent in queue
   if(kernel_sigevent->si_code==SI_SYSTEM) { //filter event on SI_SYSTEM
      if(kernel_sigqueue_sysextract(p,kernel_sigevent)<0)
         return -1;
   }else{
      if(kernel_sigqueue_extract(p,kernel_sigevent)<0)
         return -1;
   }

   return 0;
}
/*-------------------------------------------
| Name:_slip_send_packet
| Description:
| Parameters:
| Return Type:
| Comments:sends a packet of length "len", starting at
| location "p".
| See:
---------------------------------------------*/
int _dev_slip_read_c(desc_t desc, unsigned char* c,int first){
   int cb=-1;
   kernel_pthread_t* pthread_ptr;

   if(!(pthread_ptr = kernel_pthread_self()))
      return -1;

#ifdef USE_SLIP_READ_BUFFER
   if(!(ofile_lst[desc].oflag&O_NONBLOCK)) {

      desc_t slip_desc=ofile_lst[desc].desc_prv;
      slip_read_t* p_slip_read = &(((slip_io_t*)ofile_lst[slip_desc].p)->read);
      if(!p_slip_read)
         return -1;

      if(p_slip_read->cb>0 && p_slip_read->i<p_slip_read->cb) {
         *c=p_slip_read->buf[p_slip_read->i++];
         return 1;
      }

      p_slip_read->i=0;
      while(ofile_lst[desc].pfsop->fdev.fdev_isset_read
            && ofile_lst[desc].pfsop->fdev.fdev_isset_read(desc))
         __wait_io_int(pthread_ptr);   //wait incomming data
      if((p_slip_read->cb=
             ofile_lst[desc].pfsop->fdev.fdev_read(desc,p_slip_read->buf,SLIP_READ_BUFFER_SZ))<=0)
         return p_slip_read->cb;
      *c=p_slip_read->buf[p_slip_read->i++];
   }
   return 1;
#else
   if(!(ofile_lst[desc].oflag&O_NONBLOCK)) {
      if(!first) {
         while(ofile_lst[desc].pfsop->fdev.fdev_isset_read
               && ofile_lst[desc].pfsop->fdev.fdev_isset_read(desc))
            __wait_io_int(pthread_ptr);   //wait incomming data
      }
      cb=ofile_lst[desc].pfsop->fdev.fdev_read(desc,c,1);
   }

   return cb;
#endif
}
/*--------------------------------------------
| Name:        kernel_sigqueue_timedwait
| Description:
| Parameters:  none
| Return Type: none
| Comments:
| See:
----------------------------------------------*/
int kernel_sigqueue_timedwait(struct kernel_sigevent_st* kernel_sigevent,int flag,const struct timespec * abs_timeout){
   struct kernel_sigqueue_st* p= &kernel_pthread_self()->kernel_sigqueue;
   if(!p)
      return -1;

   //wait event until timeout or event signaled
   if(kernel_sem_timedwait(&p->kernel_sem->object.kernel_object_sem.kernel_sem,flag,abs_timeout)<0)
      return -1;

   //extract sigevent in queue
   if(kernel_sigevent->si_code==SI_SYSTEM) { //filter event on SI_SYSTEM
      if(kernel_sigqueue_sysextract(p,kernel_sigevent)<0)
         return -1;
   }else{
      if(kernel_sigqueue_extract(p,kernel_sigevent)<0)
         return -1;
   }

   return 0;
}
Example #9
0
/*--------------------------------------------
| Name:        dev_mem_read
| Description:
| Parameters:  none
| Return Type: none
| Comments:
| See:
----------------------------------------------*/
int dev_mem_read(desc_t desc,char* buf, int size){
   int i=0;
   int j=-1;
   int data_offset;

   int ret=-1;

   kernel_pthread_t* pthread_ptr;

   if(!(pthread_ptr = kernel_pthread_self()))
      return -1;

   for(i=0; i<=MAX_MEM_ADDR; i++) {
      //nothing change for the current offset?
      if(i==MAX_MEM_ADDR) {
         // not register listener make simple copy of current address
         if(j>=0) {
            i=j;
            goto label_dev_mem_read_copy;
         }

         //nothing change at current offset
         if((ofile_lst[desc].oflag&O_NONBLOCK) || !ret)
            return ret;  //if !ret change detected on this descripteur but not at the current offset

         //no change detected for on any address for this desc
         __wait_io_int(pthread_ptr); //blocking call
         //restart find change
         i=0;
      }

      //get address index for current offset
      if(   (ofile_lst[desc].offset>=addr_list[i].addr)
            && (ofile_lst[desc].offset < (addr_list[i].addr+addr_list[i].len)) )
         j=i;

      //
      if(addr_list[i].vector_listener&(0x00000001<<desc)) //is it register listener
         j=-1;  //yes

      //change?
      if( (addr_list[i].vector_isset_read&(0x00000001<<desc)) ) {
         ret=0; ////something change yes
         //lseek() change at the current offset
         if(   (ofile_lst[desc].offset<addr_list[i].addr)
               || (ofile_lst[desc].offset >= (addr_list[i].addr+addr_list[i].len)) )
            continue;  //continue to try find change at the current offset

         //something change at the current offset go to read the address and copy in the buf

      }else{
         //continue to find change
         continue;
      }

      //yes, now read the address and copy in the buf
      //pthread_clear_event(&ofile_lst[desc].pthread_owner);
label_dev_mem_read_copy:
      //lock
      __dev_mem_lock();
      //check real address
      if(!addr_list[i].pdata) {
         __dev_mem_unlock();
         return -1;
      }

      //
      if(buf)
         addr_list[i].vector_isset_read&=~(0x00000001<<desc);

      data_offset= ofile_lst[desc].offset-addr_list[i].addr;
      if(size>(addr_list[i].len-data_offset))
         size = addr_list[i].len-data_offset;

      //WARNING TO DO
      //check new size<old size. risk of buffer overflow

      if(buf)
         memcpy(buf,(char*)addr_list[i].pdata+data_offset,size);
      else
         size=-size;

      ofile_lst[desc].offset+=size;

      //unlock
      __dev_mem_unlock();

      return size;
   }
   return ret;
}
/**
 * \brief Closes a socket. Standard BSD close() with internal name.
 * \param[in]  desc socket descriptor to close.
 * \return close() returns 0 on success and -1 on failure.
 * \callgraph
 */
int _sys_sock_close(int fd){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   hsock_t hsock  = 0;
   desc_t desc;
   int r;
   //
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(fd<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_CLOSED){
     __set_kernel_pthread_errno (ENOTCONN);
     return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_ABORTED){
     __set_kernel_pthread_errno (ECONNABORTED);
     return -1;
   }
   //
   if( ((socket_t*)hsock)->socksconn!=NULL){
      /*
      while( ((socket_t*)hsock)->w != ((socket_t*)hsock)->socksconn->_r )
         __WAIT_SOCKET_EVENT(hsock);
      */
   }
   //
   if( ((socket_t*)(hsock))->state == STATE_SOCKET_CLOSED 
      || ((socket_t*)(hsock))->state == STATE_SOCKET_ABORTED
      || ((socket_t*)(hsock))->state == STATE_SOCKET_ACCEPTED){
      __CLR_SOCKET_EVENT(hsock);

      close(fd);

      return -1;
   }
   //
   ((socket_t*)(hsock))->state=STATE_SOCKET_CLOSE;
   //
   while( ((socket_t*)(hsock))->state==STATE_SOCKET_WAIT )
      __WAIT_SOCKET_EVENT(pthread_ptr,hsock);
   //
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EINVAL);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   //
   __CLR_SOCKET_EVENT(hsock);
   //
   if(((socket_t*)hsock)->protocol==IPPROTO_UDP){
     //free udp connection
     ((socket_t*)hsock)->uip_udp_conn->lport = 0;
   }
   //
   r=close(fd);
   //
   if(!r)
     __set_kernel_pthread_errno(0);
   //
   return r;
#else
   return -1;
#endif
} //end of '_sys_sock_close'
/**
 * \brief Sends a packet to a remote host. Standard BSD sendto() with internal name.
 * \param[in]  desc socket descriptor created with socket()
 * \param[in]  buf buffer with payload to send
 * \param[in]  length length in bytes of the \p buf buffer
 * \param[in]  flags is formed by OR'ing options. No options are supported with current implementation.
 * \param[in]  dest_addr to destination address and port.
 * \param[in]  dest_len should be the length of \p dest_addr structure. Unused parameter with current implementation.
 * \details Writes data to the remote host specified by \p dest_addr into \p buf. 
            The socket must be a \ref SOCK_DGRAM (UDP) socket. 
            \p length should be the amount of data in the buffer. 
 * \return sendto() returns the amount of data which was written. If there is an error, -1 is returned.
 * \callgraph
 */
int _sys_sock_sendto(int fd, const void *buf, int length, int flags, const struct sockaddr *dest_addr,socklen_t dest_len){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   hsock_t hsock  = 0;
   desc_t desc;

   #if UIP_CONF_IPV6
   desc_t desc_if;
   #endif

   int r;
   //
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(fd<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_CLOSED){
     __set_kernel_pthread_errno (ENOTCONN);
     return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_ABORTED){
     __set_kernel_pthread_errno (ECONNABORTED);
     return -1;
   }
   if(((socket_t*)hsock)->protocol!=IPPROTO_UDP){
      __set_kernel_pthread_errno (EPROTONOSUPPORT);
      return -1;
   }
   //
   #if UIP_CONF_IPV6
   desc_if = uip_core_if_indextodesc(((socket_t*)hsock)->addr_in.sin6_scope_id,O_RDONLY);
   if(desc_if<0){
     __set_kernel_pthread_errno (EINVAL);
     return -1;
   }
   #endif
   /*to do
   if(dev_core_ioctl(desc_if,NETUP)<0){
     __set_kernel_pthread_errno (ENETDOWN);
     return -1;
   }
   */
   //lock
   __lock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   //
   #if UIP_CONF_IPV6
   memcpy(&((socket_t*)hsock)->addr_in_to,dest_addr,sizeof(struct _sockaddr_in6));
   #else
   memcpy(&((socket_t*)(hsock))->addr_in_to,dest_addr,sizeof(struct _sockaddr_in));
   #endif
   //unlock
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   //
   r=write(fd,(void*)buf,length);
   if(r<0){
      if( ((socket_t*)(hsock))->state==STATE_SOCKET_CLOSED){
        __set_kernel_pthread_errno (ENOTCONN);
        return -1;
      }
      if( ((socket_t*)(hsock))->state==STATE_SOCKET_ABORTED){
        __set_kernel_pthread_errno (ECONNABORTED);
        return -1;
      }
      if( ((socket_t*)(hsock))->state==STATE_SOCKET_NETDOWN){
        __set_kernel_pthread_errno (ENETDOWN);
        return -1;
      }
      //
      /*UIP_EVENT(EVT_UIP_SOCK + EVT_LVL_ERR + EVT_UIP_SOCK_SENDTO_FAIL, 
                 desc, &length, sizeof(length),
                 "sendto() failure (return %d)(flags %d)", r, flags);*/
   }else{
       __set_kernel_pthread_errno(0);
   }
   return r;
#else
   return -1;
#endif
} //end of _sys_sock_sendto()
/**
 * \brief Receives a packet on a openned socket. Standard BSD recvfrom() with internal name.
 * \param[in]  desc socket descriptor created with socket()
 * \param[out] buf buffer to copy received data
 * \param[in]  length length in bytes of the \p buf buffer
 * \param[in]  flags is formed by OR'ing options. \ref MSG_DONTWAIT and \ref MSG_PEEK supported in current implementation.
 * \param[out] address to get the source address of the received packet
 * \param[out] address_len is unused parameter with current implementation
 * \details Reads data from the remote host specified by \p address into \p buf. 
            The socket must be a \ref SOCK_DGRAM (UDP) socket. \p length should be the size of the buffer.\n
            recvfrom() may not fill the entire buffer.\n\n
            \ref MSG_DONTWAIT This flag enables non-blocking operation (recvfrom() will not block waiting for data).\n
            \ref MSG_PEEK This flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue. 
            Thus, a subsequent receive call will return the same data.\n
            In case of multiple sources received on the same socket 
            the \p address parameter will contain the source of the actual 
            dequeued packet (the one in \p buf buffer).
 * \return recvfrom() returns the amount of data which was read. Even with \ref MSG_PEEK flag, only actual amount of data read is returned which may be smaller than packet size (maxed to \p length parameter value). If there is an error, -1 is returned.
 * \callgraph
 */
int _sys_sock_recvfrom(int fd, void *buf, int length, int flags, struct sockaddr *address,socklen_t* address_len){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   hsock_t hsock  = 0;
   desc_t desc;
   
   #if UIP_CONF_IPV6
   desc_t desc_if;
   #endif

   int r;
   //
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(fd<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_CLOSED){
     __set_kernel_pthread_errno (ENOTCONN);
     return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_ABORTED){
     __set_kernel_pthread_errno (ECONNABORTED);
     return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_NETDOWN){
     __set_kernel_pthread_errno (ENETDOWN);
     return -1;
   }
   if(((socket_t*)hsock)->protocol!=IPPROTO_UDP){
      __set_kernel_pthread_errno (EPROTONOSUPPORT);
      return -1;
   }
   //
   #if UIP_CONF_IPV6
   desc_if = uip_core_if_indextodesc(((socket_t*)hsock)->addr_in.sin6_scope_id,O_RDONLY);
   if(desc_if<0){
     __set_kernel_pthread_errno (EINVAL);
     return -1;
   }
   #endif
   /* to do
   if(dev_core_ioctl(desc_if,NETUP)<0){
     __set_kernel_pthread_errno (ENETDOWN);
     return -1;
   }
   */
   //lock
   __lock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //Prepare flags
   if(flags & MSG_DONTWAIT)
       ofile_lst[desc].oflag |= O_NONBLOCK; //GD 2011/05/24 //GD 2011/07/05: standard MSG_DONTWAIT flag compliancy (but still a workaround to pass the flag to dev_core_read())
   if(flags & MSG_PEEK)
     ((socket_t*)hsock)->flags |=  MSG_PEEK;
   //unlock
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //
   if( r=read(fd,buf,length) )
   {
       //
       #if UIP_CONF_IPV6
       memcpy(address,&((socket_t*)hsock)->addr_in_from,sizeof(struct _sockaddr_in6));
       #else
       memcpy( address,&((socket_t*)(hsock))->addr_in_from,sizeof(struct _sockaddr_in));
       #endif   
   }
   if(r<0){
      if( ((socket_t*)(hsock))->state==STATE_SOCKET_CLOSED){
        __set_kernel_pthread_errno (ENOTCONN);
        return -1;
      }
      if( ((socket_t*)(hsock))->state==STATE_SOCKET_ABORTED){
        __set_kernel_pthread_errno (ECONNABORTED);
        return -1;
      }
      if( ((socket_t*)(hsock))->state==STATE_SOCKET_NETDOWN){
        __set_kernel_pthread_errno (ENETDOWN);
        return -1;
      }
      //
      /*UIP_EVENT(EVT_UIP_SOCK + EVT_LVL_ERR + EVT_UIP_SOCK_RECVFROM_FAIL, 
                 desc, &flags, sizeof(flags),
                 "recvfrom() failure (return %d)", r);*/
   }else{
       __set_kernel_pthread_errno(0);
   }
   //Enter Semaphore
   //lock
   __lock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //Restore flags
   if(flags & MSG_DONTWAIT)
       ofile_lst[desc].oflag &= ~(O_NONBLOCK);
   if(flags & MSG_PEEK)
     ((socket_t*)hsock)->flags &=  ~(MSG_PEEK);
   //unlock
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //
   return r;  
#else
   return -1;
#endif
} // end of _sys_sock_recvfrom()
Example #13
0
/*--------------------------------------------
| Name:        _system_alloca
| Description:
| Parameters:  none
| Return Type: none
| Comments:
| See:
----------------------------------------------*/
void* _system_alloca(size_t size) {
    kernel_pthread_t* pthread_ptr= kernel_pthread_self();
    return kernel_pthread_alloca(pthread_ptr,size);

}
/**
 * \brief Connects a socket to a remote host on a given address and port. Standard BSD connect() with internal name.
 * \param[in] desc socket descriptor created with socket()
 * \param[in] address must contain the address and port of the remote host. Must be in IPv6 format with current implementation.
 * \param[in] len is the length of \p address structure. (Unused parameter with current implementation. Assumes IPv6 structures length.)
 * \details connect() must be used in a TCP \b client application. The function call blocks until the connection is established.
 * \return On connection success, zero is returned. On error, -1 is returned.
 * \callgraph
 */
int _sys_sock_connect(int fd, struct _sockaddr *address,int len){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   struct uip_conn * uip_conn;
   desc_t desc;
   hsock_t hsock  = 0;


   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(fd<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_CLOSED){
     __set_kernel_pthread_errno (ENOTCONN);
     return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_ABORTED){
     __set_kernel_pthread_errno (ECONNABORTED);
     return -1;
   }
   if(((socket_t*)hsock)->protocol!=IPPROTO_TCP){
      __set_kernel_pthread_errno (EPROTONOSUPPORT);
      return -1;
   }
   //lock
   __lock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   __lock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //
   ((socket_t*)hsock)->state = STATE_SOCKET_CONNECT;
   //
   #if UIP_CONF_IPV6
   memcpy(&((socket_t*)hsock)->addr_in,address,sizeof(struct _sockaddr_in6));
   //
   uip_conn = uip_connect((uip_ipaddr_t*)(&((socket_t*)hsock)->addr_in.sin6_addr.s6_addr),
                  (u16_t)( ((socket_t*)hsock)->addr_in.sin6_port));
   #else
   ((socket_t*)hsock)->addr_in.sin_port = ((struct _sockaddr_in*)address)->sin_port;
   ((socket_t*)hsock)->addr_in.sin_addr.s_addr = ((struct _sockaddr_in*)address)->sin_addr.s_addr;
   //
   uip_conn = uip_connect((uip_ipaddr_t*)(&((socket_t*)hsock)->addr_in.sin_addr.s_addr),
                  (u16_t)( ((socket_t*)hsock)->addr_in.sin_port));
   #endif
   
   //
   if(!uip_conn){
      //unlock
      __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
      __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
      return -1;
   }
   //
   ((socket_t*)hsock)->r =0;
   ((socket_t*)hsock)->w =0;
   // 
   ((socket_t*)hsock)->socksconn = (struct socksconn_state *)(uip_conn->appstate.state);
   //
   ((socket_t*)hsock)->socksconn->__r  = 0;
   ((socket_t*)hsock)->socksconn->_r   = 0;
   ((socket_t*)hsock)->socksconn->_w   = 0;
   //
   ((socket_t*)hsock)->socksconn->hsocks = hsock;
   //unlock
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   
   //to do:lepton
   //Wake ip_stack????
   //to do:lepton: syscall kernel
   //OS_WakeTask(_OS_TASK_TCB(os_ipStack));
   //Wait uip_connected();
    uip_core_queue_put(UIP_POLL_REQUEST,desc,(void*)address,len);
    //
   __WAIT_SOCKET_EVENT(pthread_ptr,hsock);
   if(((socket_t*)hsock)->state != STATE_SOCKET_WAIT)
      return -1;
   //
   __set_kernel_pthread_errno (0);
   //
   return 0;
#else
   return -1;
#endif
} //end of _sys_sock_connect()
/**
 * \brief Binds a socket to a local port and IP address. Standard BSD bind() with internal name.
 * \param[in] desc socket descriptor created with socket()
 * \param[in] address must contain the address and port for the socket to bind to. Must be in IPv6 format with current implementation. Address to zero means port will be openned on every interfaces.
 * \param[in] len is the length of \p address structure. (Unused parameter with current implementation. Assumes IPv6 structures length.)
 * \details bin() must be used in a \b server application that waits for incomming connection/packets.
 * \return On success, zero is returned. On error, -1 is returned.
 * \callgraph
 */
int _sys_sock_bind(int fd, struct _sockaddr *address,int len){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   hsock_t hsock  = 0;

   #if UIP_CONF_IPV6
   desc_t desc_if;
   #endif

   desc_t desc;
   //
   //
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(fd<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   //lock
   __lock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   __lock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //
   #if UIP_CONF_IPV6
      ((socket_t*)hsock)->addr_in.sin6_port = ((struct _sockaddr_in6*)address)->sin6_port; 
      //interface index in list (see uip_core interface list)
      if( ((struct _sockaddr_in6*)address)->sin6_scope_id>=IF_LIST_MAX){
        //unlock
        __set_kernel_pthread_errno (EINVAL);
        //unlock
        __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
        __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
        return -1;
      } 
      //
      ((socket_t*)hsock)->addr_in.sin6_scope_id=((struct _sockaddr_in6*)address)->sin6_scope_id;
      //
      desc_if = uip_core_if_indextodesc(((socket_t*)hsock)->addr_in.sin6_scope_id,O_RDONLY);
      if(desc_if<0){
        __set_kernel_pthread_errno (EINVAL);
        //unlock
        __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
        __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
        return -1;
      }
      /* to do
      if(dev_core_ioctl(desc_if,NETUP)<0){
         __set_kernel_pthread_errno (ENETDOWN);
         //unlock
         __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
         __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
         return -1;
      }
      */
   #else
      ((socket_t*)hsock)->addr_in.sin_port = ((struct _sockaddr_in*)address)->sin_port;
   #endif
   //
   if(((socket_t*)hsock)->protocol==IPPROTO_UDP){
      ((socket_t*)hsock)->uip_udp_conn->rport = 0;//to do: check that
      uip_udp_bind(((socket_t*)hsock)->uip_udp_conn,((struct _sockaddr_in*)address)->sin_port);
   }
   //
   //unlock
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_write,desc,O_WRONLY);
   __unlock_io(ofile_lst[desc].owner_pthread_ptr_read,desc,O_RDONLY);
   //
   __set_kernel_pthread_errno (0);
   //
   return 0;
#else
   return -1;
#endif
} //end of _sys_sock_bind()
/**
 * \brief Creates a socket. Standard BSD socket() with internal name.
 * \param[in]  af ("familly" or "domain") should only be \ref AF_INET6 (IPv4 support has been disabled so no AF_INET support). Parameter is ignore in current implementation, AF_INET6 is forced.
 * \param[in]  type can be SOCK_STREAM for TCP sockets or SOCK_DGRAM for UDP sockets.
 * \param[in]  protocol can be IPPROTO_TCP with \ref SOCK_STREAM type or IPPROTO_UDP with \ref SOCK_DGRAM with 
 * \details UDP Example \code int desc = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); \endcode \n
            TCP Example \code int desc = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); \endcode
 * \return socket() returns a socket file descriptor (\ref desc_t) which is a small non-negative integer. This file descriptor number should be used for all other socket operations on that socket. If socket() encounters an error, it will return -1.
 * \callgraph
 */
int _sys_sock_socket(int af,int type,int protocol){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   int fd;
   desc_t desc = INVALID_DESC;
   int _protocol;
   hsock_t hsock  = 0;

   //
   if(protocol==IPPROTO_TCP){
      _protocol = IPPROTO_TCP;
   }else if(protocol==IPPROTO_UDP){
      _protocol = IPPROTO_UDP;
   }else if(!protocol && type==SOCK_STREAM){
      _protocol = IPPROTO_TCP;
   }else if(!protocol && type==SOCK_DGRAM){
      _protocol = IPPROTO_UDP;
   }else{
      __set_kernel_pthread_errno(EPROTONOSUPPORT);
      return -1;
   }
   //
   if((fd = open("/dev/sock",O_RDWR,0))<0)
      return -1;
   //
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0)
      return -1;
   //    
   _vfs_ioctl(desc,SETUIPSOCKOPT,_protocol);
   //
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   //
   if(((socket_t*)hsock)->protocol==IPPROTO_TCP)
      return fd;
   //
   ((socket_t*)hsock)->r =0;
   ((socket_t*)hsock)->w =0;
   //
   ((socket_t*)hsock)->state = STATE_SOCKET_OPENED;
   // 
   ((socket_t*)hsock)->uip_udp_conn = uip_udp_new((void*)0,0);
   //
   if( !((socket_t*)hsock)->uip_udp_conn ){
      close(desc);
      return -1;
   }
      
   //
   ((socket_t*)hsock)->socksconn = (struct socksconn_state *)(((socket_t*)hsock)->uip_udp_conn->appstate.state);
   //
   ((socket_t*)hsock)->socksconn->__r  = 0;
   ((socket_t*)hsock)->socksconn->_r   = 0;
   ((socket_t*)hsock)->socksconn->_w   = 0;
   //
   ((socket_t*)hsock)->socksconn->hsocks = hsock;
   //
   ((socket_t*)hsock)->state = STATE_SOCKET_WAIT;
   //
   __set_kernel_pthread_errno (0);
   //
   return fd;
#else
   return -1;
#endif
} //end of _sys_sock_socket()
/*-------------------------------------------
| Name:select
| Description:
| Parameters:
| Return Type:
| Comments:
| See:
---------------------------------------------*/
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout){
   char b;
   char count=0;
   char wait=0;
   ldiv_t lr;
   pid_t pid;
   kernel_pthread_t* pthread_ptr;

   fd_set rfds=0;
   fd_set wfds=0;
   fd_set efds=0;

   fd_set unlock_rfds;
   fd_set unlock_wfds;
   fd_set unlock_efds;

   if(!(pthread_ptr = kernel_pthread_self()))
      return -1;

   if((pid= pthread_ptr->pid)<1)
      return -1;

   //
   rfds = readfds  ? *readfds  : 0;
   wfds = writefds ? *writefds : 0;
   efds = errorfds ? *errorfds : 0;

   //default timeout
   lr.quot = 10; //10 ms;

   //check and lock internal file descriptor
   for(b=0; b<sizeof(fd_set)|| b<nfds; b++) {
      desc_t desc;

      //check
      if((desc = process_lst[pid]->desc_tbl[b])<0 )
         continue;
      /*
      if(!(ofile_lst[desc].oflag&O_NONBLOCK))
         continue;
      */

      //read
      if( ((rfds>>b) & 0x0001) ) {
         pthread_ptr->io_desc = desc;
         if(_trylock_io(pthread_ptr,ofile_lst[desc].desc,O_RDONLY)!=EBUSY) {
            //__atomic_in();
            {
               desc_t _desc=ofile_lst[desc].desc;
               //
               if(ofile_lst[_desc].owner_pthread_ptr_read!=pthread_ptr) {
                  do {
                     //check
                     if(ofile_lst[_desc].used<=0) {
                        __unlock_io(pthread_ptr,ofile_lst[desc].desc,O_RDONLY);
                        return -1; //error, stream not coherent :(
                     }
                     //
                     //begin of section: protection from io interrupt
                     __disable_interrupt_section_in();
                     //
                     ofile_lst[_desc].owner_pthread_ptr_read=pthread_ptr;
                     ofile_lst[_desc].owner_pid=pid;
                     //end of section: protection from io interrupt
                     __disable_interrupt_section_out();
                     //
                     //aware: continue operation on original desc (see fattach() and _vfs_open() note 1)
                  } while((_desc=ofile_lst[_desc].desc_nxt[0])>=0);
               }
            }
            //__atomic_out();
         }else if (readfds) {
            *readfds=(*readfds&(~(0x01<<b)));
         }
         continue;
      }

      //write
      if( ((wfds>>b) & 0x0001) ) {
         pthread_ptr->io_desc = desc;
         if(_trylock_io(pthread_ptr,desc,O_WRONLY)!=EBUSY) {
            __atomic_in();
            {
               desc_t _desc=ofile_lst[desc].desc;
               //
               if(ofile_lst[_desc].owner_pthread_ptr_write!=pthread_ptr) {
                  do {
                     //check
                     if(ofile_lst[_desc].used<=0) {
                        __atomic_out();
                        __unlock_io(pthread_ptr,ofile_lst[desc].desc,O_WRONLY);
                        return -1; //error, stream not coherent :(
                     }
                     //
                     //begin of section: protection from io interrupt
                     __disable_interrupt_section_in();
                     //
                     ofile_lst[_desc].owner_pthread_ptr_write=pthread_ptr;
                     ofile_lst[_desc].owner_pid=pid;
                     //end of section: protection from io interrupt
                     __disable_interrupt_section_out();
                     //
                     //aware: continue operation on original desc (see fattach() and _vfs_open() note 1)
                  } while((_desc=ofile_lst[_desc].desc_nxt[1])>=0);
               }
            }
            __atomic_out();
         }else if(writefds) {
            *writefds=(*writefds&(~(0x01<<b)));
         }
         continue;
      }

      //exception
      if( ((efds>>b) & 0x0001) ) {
         pthread_ptr->io_desc = desc;
         if(_trylock_io(pthread_ptr,desc,O_WRONLY)!=EBUSY) {
            //begin of section: protection from io interrupt
            __disable_interrupt_section_in();
            //
            ofile_lst[desc].owner_pid=pid;
            ofile_lst[desc].owner_pthread_ptr_write = pthread_ptr;
            //end of section: protection from io interrupt
            __disable_interrupt_section_out();
            //
         }else{
            *errorfds=(*errorfds&(~(0x01<<b)));
         }

         continue;
      }

   }

   //set file descriptor vector
   rfds = readfds  ? *readfds  : 0;
   wfds = writefds ? *writefds : 0;
   efds = errorfds ? *errorfds : 0;

   if(readfds)
      memset(readfds,0,sizeof(fd_set));
   if(writefds)
      memset(writefds,0,sizeof(fd_set));
   if(errorfds)
      memset(errorfds,0,sizeof(fd_set));

   //set unlock file descriptor vector
   unlock_rfds=rfds;
   unlock_wfds=wfds;
   unlock_efds=efds;

start:
   for(b=0; b<sizeof(fd_set)|| b<nfds; b++) {
      desc_t desc;
      int isset=0;

      //check
      if((desc = process_lst[pid]->desc_tbl[b])<0 )
         continue;
      /*
      if(!(ofile_lst[desc].oflag&O_NONBLOCK))
         continue;
      */

      //read
      if( ((rfds>>b) & 0x0001) ) {

         if(!ofile_lst[desc].pfsop->fdev.fdev_isset_read(desc)) {
            isset=1;
            if(readfds)
               *readfds=(*readfds|((0x01<<b)));
         }else if(readfds) {
            *readfds=(*readfds&(~(0x01<<b)));
         }
         //continue;
      }

      //write
      if( ((wfds>>b) & 0x0001) ) {
         if(!ofile_lst[desc].pfsop->fdev.fdev_isset_write(desc)) {
            isset=1;
            if(writefds)
               *writefds=(*writefds|((0x01<<b)));
         }else if(writefds) {
            *writefds=(*writefds&(~(0x01<<b)));
         }
         //continue;
      }

      //exception
      if( ((efds>>b) & 0x0001) ) {
         //to do: select on exception
         //continue;
      }

      if(isset)
         count++;
   }

   //wait
   if(!count && !wait) {
      struct timespec abs_timeout;
      //
      if(timeout) {
         abs_timeout.tv_sec   = timeout->tv_sec;
         abs_timeout.tv_nsec  = timeout->tv_usec*1000;
         __wait_io_int2(pthread_ptr,&abs_timeout);
      }else{
         /*   abs_timeout.tv_sec   = 0;
            abs_timeout.tv_nsec  = 0; */
         __wait_io_int2(pthread_ptr,NULL);
      }
      //

      //
      wait=1;
      goto start;
   }

   //unlock internal file descriptor
   for(b=0; b<sizeof(fd_set)|| b<nfds; b++) {
      desc_t desc;
      int isset=0;

      //check
      if((desc = process_lst[pid]->desc_tbl[b])<0 )
         continue;
      /*
      if(!(ofile_lst[desc].oflag&O_NONBLOCK))
         continue;
      */

      //unlock descriptor
      if( ((unlock_rfds>>b) & 0x0001) ) {
         __unlock_io(pthread_ptr,ofile_lst[desc].desc,O_RDONLY); //yes isset=1 or wait =1 then select is terminated
      }
      if( ((unlock_wfds>>b) & 0x0001) ) {
         __unlock_io(pthread_ptr,ofile_lst[desc].desc,O_WRONLY); //yes isset=1 or wait =1 then select is terminated
      }
   }

   //reset file descriptor vector
   if(!count) {
      if(readfds)
         memset(readfds,0,sizeof(fd_set));
      if(writefds)
         memset(writefds,0,sizeof(fd_set));
      if(errorfds)
         memset(errorfds,0,sizeof(fd_set));

   }

   return count;
}
/**
 * \brief Start listening to the specified port. Standard BSD listen() with internal name.
 * \param[in] desc is a socket that has been created with socket(), bound to a local address with bind(), and is listening for connections after a listen(). 
 * \param[out] address is a pointer to a \ref _sockaddr structure. This structure is filled in with the address of the peer socket, as known to the communications layer. The format is always IPv6 in this implementation.
 * \param[in,out] len is a value-result argument: it should initially contain the size of the structure pointed to by \p address; on return it will contain the actual length (in bytes) of the address returned.
 * \details The accept() system call is used with connection-based socket types (\ref SOCK_STREAM only in this implementation). 
            It extracts the first connection request on the queue of pending connections, 
            creates a new connected socket, and returns a new file descriptor referring to that socket. 
            The newly created socket is not in the listening state. The original socket \p desc is unaffected by this call. 
 * \note Details may be added on blocking/non-blocking behavior.
 * \return On connection success, zero is returned. On error, -1 is returned.
 * \callgraph
 */
int _sys_sock_accept(int fd, struct _sockaddr *address,int* len){
#if defined (__KERNEL_NET_IPSTACK) && defined (USE_UIP_CORE)
   pid_t pid;
   kernel_pthread_t* pthread_ptr;
   hsock_t hsock  = 0;
   hsock_t hcsock = 0;
   desc_t desc;
   
   if(!(pthread_ptr = kernel_pthread_self())){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   if((pid=pthread_ptr->pid)<=0){
      __set_kernel_pthread_errno(ESRCH);
      return -1;
   }
   //
   if(fd<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   //
   desc = process_lst[pid]->desc_tbl[fd];
   if(desc<0){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EBADF);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_CLOSED){
     __set_kernel_pthread_errno (ENOTCONN);
     return -1;
   }
   if( ((socket_t*)(hsock))->state==STATE_SOCKET_ABORTED){
     __set_kernel_pthread_errno (ECONNABORTED);
     return -1;
   }
   if(((socket_t*)hsock)->protocol!=IPPROTO_TCP){
      __set_kernel_pthread_errno (EPROTONOSUPPORT);
      return -1;
   }
   //Make ready to accept connection
   ((socket_t*)hsock)->state = STATE_SOCKET_LISTEN;
   //wait connected operation from socketEngine
   __WAIT_SOCKET_EVENT(pthread_ptr,hsock);
    if(!ofile_lst[desc].used){
      __set_kernel_pthread_errno (EINVAL);
      return -1;
   }
   if(! (hsock  = ofile_lst[desc].p) ){
      __set_kernel_pthread_errno (ENOTSOCK);
      return -1;
   }
   if(((socket_t*)hsock)->state!=STATE_SOCKET_CONNECTED){
     __set_kernel_pthread_errno (ENOTCONN);
     return -1;
   }
   //((socket_t*)hsock)->state=STATE_SOCKET_ACCEPTED;
   //wait Accepted operation from socketEngine
   //__WAIT_SOCKET_EVENT(hsock);
   //
   hcsock   = ((socket_t*)hsock)->hsocks;
   //
   #if UIP_CONF_IPV6
   memcpy(address,&((socket_t*)hcsock)->addr_in,sizeof(struct _sockaddr_in6));
   //
   *len=sizeof(struct _sockaddr_in6);
   //
   #else
   ((struct _sockaddr_in*)address)->sin_port = ((socket_t*)hcsock)->addr_in.sin_port;
   ((struct _sockaddr_in*)address)->sin_addr.s_addr = ((socket_t*)hcsock)->addr_in.sin_addr.s_addr;
   //
   *len=sizeof(struct _sockaddr_in);
   //
   #endif
   
   /*if(((socket_t*)hsock)->state!=STATE_SOCKET_LISTEN)
      return NULL;*/
   //
   __set_kernel_pthread_errno (0);
   //
   return ((socket_t*)hcsock)->fd;
#else
   return -1;
#endif
} //end of _sys_sock_accept()