pike.git / src / modules / _Stdio / file.c

version» Context lines:

pike.git/src/modules/_Stdio/file.c:941:    *! The capability of sending and receiving remote file    *! descriptors is only available on some operating systems.    *! This capability is indicated by the precence of @[__HAVE_SEND_FD__].    *!    *! @seealso    *! @[send_fd()], @[read()], @[fd_factory()], @[__HAVE_SEND_FD__]    */   #ifdef HAVE_PIKE_SEND_FD   static void receive_fds(int *fds, size_t num_fds)   { -  size_t i; +  volatile size_t i;       for (i = 0; i < num_fds; i++) {    int fd = fds[i];    if (fd >= 0) {    JMP_BUF jmp;    if (SETJMP(jmp))    call_handle_error();    else {    push_new_fd_object(fd_fd_factory_fun_num, fd,    low_fd_query_properties(fd), 0);
pike.git/src/modules/_Stdio/file.c:4993:    push_int(0);    } else {    push_int(1);    }   }   #endif /* HAVE_SYS_UN_H */      /*! @decl int(0..1) connect(string dest_addr, int dest_port)    *! @decl int(0..1) connect(string dest_addr, int dest_port, @    *! string src_addr, int src_port) +  *! @decl string(0..255)|int(0..0) connect(string dest_addr, int dest_port, @ +  *! string|int(0..0) src_addr, int|int(0..0) src_port, @ +  *! string(0..255) data)    *!    *! Open a TCP/IP connection to the specified destination.    *!    *! In nonblocking mode, success is indicated with the write-callback,    *! and failure with the close-callback or the read_oob-callback.    *! -  +  *! If the @[data] argument is included the socket will use +  *! TCP_FAST_OPEN if available, if not the data will @i{not be +  *! sent@}. In the data case the function either returns the data +  *! that has not been sent (only one packet can be sent with this +  *! option) or 0 if the connection failed immediately. +  *!    *! @returns -  *! Returns @expr{1@} on success, and @expr{0@} on failure. +  *! Returns @expr{1@} or the remaining @expr{data@} on success, and +  *! @expr{0@} on failure.    *!    *! @note    *! In nonblocking mode @expr{0@} (zero) may be returned and @[errno()] set    *! to @tt{EWOULDBLOCK@} or @tt{WSAEWOULDBLOCK@}. This should not be regarded    *! as a connection failure. -  +  *!    */   static void file_connect(INT32 args)   {    PIKE_SOCKADDR addr;    int addr_len;    struct pike_string *dest_addr = NULL;    struct pike_string *src_addr = NULL; -  +  struct pike_string *data = NULL;    struct svalue *dest_port = NULL;    struct svalue *src_port = NULL;       int tmp, was_closed = FD < 0; -  int tries; +  int fd, sent = 0;       if (args < 4) {    get_all_args("connect", args, "%S%*", &dest_addr, &dest_port); -  +  } if( args == 5 ) { +  struct svalue *src_sv; +  get_all_args("connect", args, "%S%*%*%*%S", +  &dest_addr, &dest_port, &src_sv, &src_port, &data); +  if(TYPEOF(*src_sv) != PIKE_T_INT ) +  { +  if (TYPEOF(*src_sv) != PIKE_T_STRING || src_sv->u.string->size_shift) +  SIMPLE_BAD_ARG_ERROR("connect", 3, "int|string(8bit)"); +  src_addr = src_sv->u.string; +  }    } else {    get_all_args("connect", args, "%S%*%S%*",    &dest_addr, &dest_port, &src_addr, &src_port);    }       if(TYPEOF(*dest_port) != PIKE_T_INT &&    (TYPEOF(*dest_port) != PIKE_T_STRING || dest_port->u.string->size_shift))    SIMPLE_BAD_ARG_ERROR("connect", 2, "int|string(8bit)");       if(src_port && TYPEOF(*src_port) != PIKE_T_INT &&
pike.git/src/modules/_Stdio/file.c:5045:       addr_len = get_inet_addr(&addr, dest_addr->str,    (TYPEOF(*dest_port) == PIKE_T_STRING?    dest_port->u.string->str : NULL),    (TYPEOF(*dest_port) == PIKE_T_INT?    dest_port->u.integer : -1), 0);    INVALIDATE_CURRENT_TIME();       if(was_closed)    { -  if (args < 4) { +  if (!src_addr) {    push_int(-1);    push_int(0);    push_int(SOCKADDR_FAMILY(addr));    file_open_socket(3);    } else {    push_svalue(src_port);    ref_push_string(src_addr);    file_open_socket(2);    }    if(UNSAFE_IS_ZERO(Pike_sp-1) || FD < 0)    Pike_error("Stdio.File->connect(): Failed to open socket.\n");    pop_stack();    }    -  for(tries = 0;; tries++) -  { -  tmp=FD; +  fd = FD;    THREADS_ALLOW(); -  tmp=fd_connect(tmp, (struct sockaddr *)&addr, addr_len); -  THREADS_DISALLOW(); -  if(tmp<0) -  switch(errno) +  for(;;)    { - #if 0 -  /* Even though this code is robust(er) now, -  * it has no business here and should be dealt -  * with at the Pike programming level. -  */ - #ifdef EADDRINUSE -  case EADDRINUSE: - #endif - #ifdef WSAEADDRINUSE -  case WSAEADDRINUSE: - #endif -  if(tries > INUSE_TIMEOUT/INUSE_BUSYWAIT_DELAY) + #ifdef MSG_FASTOPEN +  if( data )    { -  /* errno = EAGAIN; */ /* no ports available */ -  break; +  tmp = sendto(fd, data->str, data->len, MSG_FASTOPEN, +  (struct sockaddr *)&addr, addr_len );    } -  sysleep(INUSE_BUSYWAIT_DELAY); -  /* FALL_THROUGH */ +  else   #endif -  case EINTR: -  continue; +  { +  tmp=fd_connect(fd, (struct sockaddr *)&addr, addr_len);    } -  +  if( tmp<0 && (errno==EINTR)) +  continue;    break;    } -  +  THREADS_DISALLOW();    -  +     if(tmp < 0   #ifdef EINPROGRESS    && !(errno==EINPROGRESS && (THIS->open_mode & FILE_NONBLOCKING))   #endif   #ifdef WSAEWOULDBLOCK    && !(errno==WSAEWOULDBLOCK && (THIS->open_mode & FILE_NONBLOCKING))   #endif   #ifdef EWOULDBLOCK    && !(errno==EWOULDBLOCK && (THIS->open_mode & FILE_NONBLOCKING))   #endif
pike.git/src/modules/_Stdio/file.c:5116:    /* something went wrong */    ERRNO=errno;    if (was_closed) {    while (fd_close (FD) && errno == EINTR) {}    change_fd_for_box (&THIS->box, -1);    errno = ERRNO;    }    pop_n_elems(args);    push_int(0);    }else{ -  +     ERRNO=0; -  +  if( data ) +  { +  push_string( make_shared_binary_string( data->str + tmp, data->len-tmp ) ); +  stack_pop_n_elems_keep_top( args ); +  } +  else +  {    pop_n_elems(args);    push_int(1);    }    } -  + }      /*! @decl string query_address()    *! @decl string query_address(int(0..1) local)    *!    *! Get address and port of a socket end-point.    *!    *! @param local    *! If the argument @[local] is not specified, or is @expr{0@}    *! (zero), the remote end-point is returned. Otherwise, if @[local]    *! is @expr{1@}, the local end-point is returned.