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

version» Context lines:

pike.git/src/modules/_Stdio/file.c:440: Inside #if defined(PIKE_DEBUG)
   /* Don't cause a fatal when opening fds by number    * if the fd belongs to a backend... */    if ((fd >= 0) && !(flags & FILE_NOT_OPENED))    debug_check_fd_not_in_use (fd);   #endif    change_fd_for_box(&THIS->box, fd);   }      /* Use ptrdiff_t for the fd since we're passed a void * and should    * read it as an integer of the same size. */ - static void do_close_fd(ptrdiff_t fd) + static int do_close_fd(ptrdiff_t fd)   {    int ret; -  if (fd < 0) return; +  int preve; +  if (fd < 0) return 0; +  errno = 0;    do { -  +  preve = errno;    ret = fd_close(fd);    } while ((ret == -1) && (errno == EINTR)); -  +  if ((ret == -1) && preve) return 0; +  return ret;   }      #ifdef HAVE_PIKE_SEND_FD   /* Close the queued fds in fd_info, either due to them being successfully    * sent, or due to the connection being closed. */   static void do_close_fd_info(int *fd_info)   {    int num_fds = fd_info[1];    int *fds = fd_info + 2;    while (num_fds) {
pike.git/src/modules/_Stdio/file.c:548: Inside #if defined(HAVE_PIKE_SEND_FD)
  #ifdef HAVE_PIKE_SEND_FD    if (THIS->fd_info) do_close_fd_info(THIS->fd_info);   #endif       for (ev = 0; ev < NELEM (THIS->event_cbs); ev++) {    free_svalue(& THIS->event_cbs[ev]);    SET_SVAL(THIS->event_cbs[ev], PIKE_T_INT, NUMBER_NUMBER, integer, 0);    }   }    - static void close_fd_quietly(void) + static void close_fd(int quiet)   {    int fd=FD; -  +  int olde = 0;    if(fd<0) return;       free_fd_stuff();    SUB_FD_EVENTS (THIS, ~0); -  +  /* NB: The fd will always be closed on return from fd_close() +  * (except for the EINTR case on eg HPUX). +  */    change_fd_for_box (&THIS->box, -1);    -  +  if ( (THIS->flags & FILE_NOT_OPENED) ) +  return; +     while(1)    {    int i, e;    THREADS_ALLOW_UID();    i=fd_close(fd);    e=errno;    THREADS_DISALLOW_UID();    -  +  /* fprintf(stderr, "fd_close(%d): ret: %d, errno: %d\n", fd, i, e); */ +     check_threads_etc();       if(i < 0)    { -  +  ERRNO = errno = e;    switch(e)    { -  default: { +  default: +  push_int(e); +  f_strerror(1); +  +  if (quiet) { +  /* NB: FIXME: This has quite a bit of overhead... */    JMP_BUF jmp;    if (SETJMP (jmp))    call_handle_error();    else { -  ERRNO=errno=e; -  change_fd_for_box (&THIS->box, fd); -  push_int(e); -  f_strerror(1); +     Pike_error("Failed to close file: %S\n", Pike_sp[-1].u.string);    }    UNSETJMP (jmp); -  break; +  } else { +  Pike_error("Failed to close file: %S\n", Pike_sp[-1].u.string);    } -  -  case EBADF: +     break;    - #ifdef SOLARIS -  /* It's actually OK. This is a bug in Solaris 8. */ -  case EAGAIN: + #if 0 + #ifdef ENOSPC +  case ENOSPC: +  /* FreeBSD: The underlying object did not fit, cached data was lost. */    break;   #endif -  -  case EINTR: -  continue; -  } -  } + #endif + #ifdef ECONNRESET +  case ECONNRESET: +  /* FreeBSD: The peer shut down the connection before all pending data +  * was delivered. +  */    break; -  } - } + #endif    - static void close_fd(void) - { -  int fd=FD; -  if(fd<0) return; -  -  free_fd_stuff(); -  SUB_FD_EVENTS (THIS, ~0); -  change_fd_for_box (&THIS->box, -1); -  -  if ( (THIS->flags & FILE_NOT_OPENED) ) -  return; -  -  while(1) -  { -  int i, e; -  THREADS_ALLOW_UID(); -  i=fd_close(fd); -  e=errno; -  THREADS_DISALLOW_UID(); -  -  check_threads_etc(); -  -  if(i < 0) -  { -  switch(e) -  { -  default: -  ERRNO=errno=e; -  change_fd_for_box (&THIS->box, fd); -  push_int(e); -  f_strerror(1); -  Pike_error("Failed to close file: %S\n", Pike_sp[-1].u.string); -  break; -  +     case EBADF: -  +  if (olde) { +  /* Probably an OS where fds are closed on EINTR (ie most). */ +  ERRNO = errno = 0; +  break; +  }    Pike_error("Internal error: Closing a non-active file descriptor %d.\n",fd);    break;      #ifdef SOLARIS    /* It's actually OK. This is a bug in Solaris 8. */    case EAGAIN:    break;   #endif -  +     case EINTR: -  +  olde = e;    continue;    }    }    break;    }   }      void my_set_close_on_exec(int fd, int to)   {    set_close_on_exec(fd, to);
pike.git/src/modules/_Stdio/file.c:2353: Inside #if defined(TCP_NODELAY)
   }    if (errno) {    ERRNO = errno;    push_int(0);    } else {    push_int(1);    }   }   #endif    + #ifndef SHUT_RD + #define SHUT_RD 0 + #endif + #ifndef SHUT_WR + #define SHUT_WR 1 + #endif +    static int do_close(int flags)   {    struct my_file *f = THIS;    if(FD == -1) return 1; /* already closed */    ERRNO=0;       flags &= f->open_mode;       switch(flags & (FILE_READ | FILE_WRITE))    {    case 0:    return 0;       case FILE_READ:    if(f->open_mode & FILE_WRITE)    {    SUB_FD_EVENTS (f, PIKE_BIT_FD_READ|PIKE_BIT_FD_READ_OOB|PIKE_BIT_FD_FS_EVENT); -  fd_shutdown(FD, 0); +  fd_shutdown(FD, SHUT_RD);    f->open_mode &=~ FILE_READ;    return 0;    }else{    f->flags&=~FILE_NOT_OPENED; -  close_fd(); +  close_fd(0);    return 1;    }       case FILE_WRITE:    if(f->open_mode & FILE_READ)    {    SUB_FD_EVENTS (f, PIKE_BIT_FD_WRITE|PIKE_BIT_FD_WRITE_OOB|PIKE_BIT_FD_FS_EVENT); -  fd_shutdown(FD, 1); +  fd_shutdown(FD, SHUT_WR);    f->open_mode &=~ FILE_WRITE;   #ifdef HAVE_PIKE_SEND_FD    if (f->fd_info) do_close_fd_info(f->fd_info);   #endif    return 0;    }else{    f->flags&=~FILE_NOT_OPENED; -  close_fd(); +  close_fd(0);    return 1;    }       case FILE_READ | FILE_WRITE:    f->flags&=~FILE_NOT_OPENED; -  close_fd(); +  close_fd(0);    return 1;       default:    Pike_fatal("Bug in switch implementation!\n");    UNREACHABLE(return 0);    }   }      /*! @decl string grantpt()    *!
pike.git/src/modules/_Stdio/file.c:2484:   #endif   }   #endif /* HAVE_GRANTPT || USE_PT_CHMOD || USE_CHGPT */      /*! @decl int close()    *! @decl int close(string direction)    *!    *! Close a file or stream.    *!    *! If direction is not specified, both the read and the write -  *! direction is closed. Otherwise only the directions specified is +  *! direction are closed. Otherwise only the directions specified is    *! closed.    *!    *! @returns -  *! Nonzero is returned if the file or stream wasn't open in the -  *! specified direction, zero otherwise. +  *! Returns @expr{1@} if the file or stream now is closed in +  *! all directions, and @expr{0@} otherwise.    *!    *! @throws    *! An exception is thrown if an I/O error occurs.    *!    *! The default behaviour for sockets is typically to flush buffered    *! data in the background, but this can be changed with @[linger()].    *!    *! @note    *! @[close()] has no effect if this file object has been associated    *! with an already opened file, i.e. if @[open()] was given an
pike.git/src/modules/_Stdio/file.c:2607:    *!    *! @seealso    *! @[close()]    */   static void file_open(INT32 args)   {    int flags,fd;    int access;    int err;    struct pike_string *str, *flag_str; -  close_fd(); +  close_fd(0);       if(args < 2)    SIMPLE_WRONG_NUM_ARGS_ERROR("open", 2);       if(TYPEOF(Pike_sp[-args]) != PIKE_T_STRING &&    TYPEOF(Pike_sp[-args]) != PIKE_T_INT)    SIMPLE_ARG_TYPE_ERROR("open", 1, "string|int");       if(TYPEOF(Pike_sp[1-args]) != PIKE_T_STRING)    SIMPLE_ARG_TYPE_ERROR("open", 2, "string");
pike.git/src/modules/_Stdio/file.c:2767: Inside #if !defined(__NT__) && (defined(HAVE_POSIX_OPENPT) || defined(PTY_MASTER_PATHNAME))
   *!    *! @seealso    *! @[grantpt()]    */   static void file_openpt(INT32 args)   {    int flags,fd;   #ifdef HAVE_POSIX_OPENPT    struct pike_string *flag_str;   #endif -  close_fd(); +  close_fd(0);       if(args < 1)    SIMPLE_WRONG_NUM_ARGS_ERROR("openpt", 1);       if(TYPEOF(Pike_sp[-args]) != PIKE_T_STRING)    SIMPLE_ARG_TYPE_ERROR("openpt", 1, "string");      #ifdef HAVE_POSIX_OPENPT    flags = parse((flag_str = Pike_sp[-args].u.string)->str);   
pike.git/src/modules/_Stdio/file.c:4271:       int type=fd_CAN_NONBLOCK | fd_BIDIRECTIONAL;    int reverse;       check_all_args("file->pipe",args, BIT_INT | BIT_VOID, 0);    if(args && !SUBTYPEOF(Pike_sp[-1])) type = Pike_sp[-args].u.integer;       reverse = type & fd_REVERSE;    type &= ~fd_REVERSE;    -  close_fd(); +  close_fd(0);    pop_n_elems(args);    ERRNO=0;       do    {   #ifdef PIPE_CAPABILITIES    if(!(type & ~(PIPE_CAPABILITIES)))    {    i=fd_pipe(&inout[0]);    if (i >= 0) {
pike.git/src/modules/_Stdio/file.c:4384:    IDENTIFIER_PIKE_FUNCTION) && (i->func.offset != -1)) {    /* receive_fd() is not a prototype. */    f->flags |= FILE_HAVE_RECV_FD;    }    break;       case PROG_EVENT_EXIT:    if(!(f->flags & (FILE_NO_CLOSE_ON_DESTRUCT |    FILE_LOCK_FD |    FILE_NOT_OPENED))) -  close_fd_quietly(); +  close_fd(1);    else    free_fd_stuff();   #ifdef HAVE_PIKE_SEND_FD    if (f->fd_info) {    free(f->fd_info);    f->fd_info = NULL;    }   #endif    unhook_fd_callback_box (&f->box);    break;
pike.git/src/modules/_Stdio/file.c:4567:   }      /*! @decl int(0..1) open_socket(int|void port, string|void addr, @    *! int|string|void family_hint)    */   static void file_open_socket(INT32 args)   {    int fd;    int family=-1;    -  close_fd(); +  close_fd(0);       if (args > 2 && TYPEOF(Pike_sp[2-args]) == PIKE_T_INT &&    Pike_sp[2-args].u.integer != 0)    family = Pike_sp[2-args].u.integer;    else if (args > 2 && TYPEOF(Pike_sp[2-args]) == PIKE_T_STRING &&    !Pike_sp[2-args].u.string->size_shift) {    PIKE_SOCKADDR addr;    get_inet_addr(&addr, (char *) STR0(Pike_sp[2-args].u.string),    NULL, -1, 0);    family = SOCKADDR_FAMILY(addr);
pike.git/src/modules/_Stdio/file.c:4883:    name = xalloc(addr_len);       name->sun_family=AF_UNIX;    strcpy( name->sun_path, Pike_sp[-args].u.string->str );   #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN    /* Length including NUL. */    name->sun_len = Pike_sp[-args].u.string->len + 1;   #endif    pop_n_elems(args);    -  close_fd(); +  close_fd(0);    change_fd_for_box (&THIS->box, socket(AF_UNIX,SOCK_STREAM,0));       if( FD < 0 )    {    free(name);    ERRNO = errno;    push_int(0);    return;    }   
pike.git/src/modules/_Stdio/file.c:5200:    *! @seealso    *! @[open()]    */   static void file_create(INT32 args)   {    if(!args) return;    if(TYPEOF(Pike_sp[-args]) != PIKE_T_STRING &&    TYPEOF(Pike_sp[-args]) != PIKE_T_INT)    SIMPLE_ARG_TYPE_ERROR("create", 1, "int|string");    -  close_fd(); +  close_fd(0);    file_open(args);   }      #ifdef _REENTRANT      struct new_thread_data   {    INT32 from, to;    char buffer[READ_BUFFER];   };