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

version» Context lines:

pike.git/src/modules/_Stdio/file.c:17:   #include "pike_macros.h"   #include "backend.h"   #include "fd_control.h"   #include "module_support.h"   #include "operators.h"   #include "pike_security.h"   #include "bignum.h"   #include "builtin_functions.h"   #include "gc.h"   #include "time_stuff.h" -  + #include "iobuffer.h"   #include "file_machine.h"   #include "file.h"   #include "pike_error.h"   #include "signal_handler.h"   #include "pike_types.h"   #include "threads.h"   #include "program_id.h"      #ifdef HAVE_SYS_TYPE_H   #include <sys/types.h>
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:1209:    if (!cmsg) {    errno = ENOMEM;    return -1;    }       msg.msg_control = cmsg;    msg.msg_controllen = cmsg->cmsg_len = CMSG_LEN(num_fds * sizeof(int));    cmsg->cmsg_level = SOL_SOCKET;    cmsg->cmsg_type = SCM_RIGHTS;    -  MEMCPY(CMSG_DATA(cmsg), fds, num_fds * sizeof(int)); +  memcpy(CMSG_DATA(cmsg), fds, num_fds * sizeof(int));    msg.msg_flags = 0;      #else    /* BSD */    msg.msg_accrights = (void *)fds;    msg.msg_accrightslen = num_fds * sizeof(int);   #endif    msg.msg_name = NULL;    msg.msg_namelen = 0;    msg.msg_iov = iov;
pike.git/src/modules/_Stdio/file.c:1376:    if(FD < 0)    Pike_error("File not open.\n");       if(!args)    {    len=0x7fffffff;    }    else    {    if(TYPEOF(Pike_sp[-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->read()", 1, "int"); +  SIMPLE_BAD_ARG_ERROR("read", 1, "int");    len=Pike_sp[-args].u.integer;    if(len<0)    Pike_error("Cannot read negative number of characters.\n");    }       if(args > 1 && !UNSAFE_IS_ZERO(Pike_sp+1-args))    {    all=0;    }else{    all=1;
pike.git/src/modules/_Stdio/file.c:1656:    if(FD < 0)    Pike_error("File not open.\n");       if(!args)    {    len=0x7fffffff;    }    else    {    if(TYPEOF(Pike_sp[-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->read_oob", 1, "int"); +  SIMPLE_BAD_ARG_ERROR("read_oob", 1, "int");    len=Pike_sp[-args].u.integer;    if(len<0)    Pike_error("Cannot read negative number of characters.\n");    }       if(args > 1 && !UNSAFE_IS_ZERO(Pike_sp+1-args))    {    all=0;    }else{    all=1;
pike.git/src/modules/_Stdio/file.c:1720:    ADD_FD_EVENTS2 (f, 1 << event, flags);    }   }      #undef CBFUNCS      #define CBFUNCS(CB, EVENT) \    static void PIKE_CONCAT(file_set_,CB) (INT32 args) \    { \    if(!args) \ -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->set_" #CB, 1); \ +  SIMPLE_TOO_FEW_ARGS_ERROR("set_" #CB, 1); \    set_fd_event_cb (THIS, Pike_sp-args, EVENT, 0); \    }      #define CBFUNCS2(CB, EVENT) \    static void PIKE_CONCAT(file_set_,CB) (INT32 args) \    { \    if(args<2) \ -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->set_" #CB, 2); \ +  SIMPLE_TOO_FEW_ARGS_ERROR("set_" #CB, 2); \    if (TYPEOF(Pike_sp[1-args]) != PIKE_T_INT) \ -  SIMPLE_ARG_TYPE_ERROR("Stdio.File->set_" #CB, 2, "int"); \ +  SIMPLE_ARG_TYPE_ERROR("set_" #CB, 2, "int"); \    set_fd_event_cb (THIS, Pike_sp-args, EVENT, \    Pike_sp[1-args].u.integer); \    }      CBFUNCS(read_callback, PIKE_FD_READ)   CBFUNCS(write_callback, PIKE_FD_WRITE)   CBFUNCS(read_oob_callback, PIKE_FD_READ_OOB)   CBFUNCS(write_oob_callback, PIKE_FD_WRITE_OOB)   CBFUNCS2(fs_event_callback, PIKE_FD_FS_EVENT)   
pike.git/src/modules/_Stdio/file.c:1874:    *! @seealso    *! @[read()], @[write_oob()], @[send_fd()]    */   static void file_write(INT32 args)   {    ptrdiff_t written, i;    struct pike_string *str;       if(args<1 || ((TYPEOF(Pike_sp[-args]) != PIKE_T_STRING) &&    (TYPEOF(Pike_sp[-args]) != PIKE_T_ARRAY))) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->write()", 1, "string|array(string)"); +  SIMPLE_BAD_ARG_ERROR("write", 1, "string|array(string)");       if(FD < 0)    Pike_error("File not open for write.\n");       if (TYPEOF(Pike_sp[-args]) == PIKE_T_ARRAY) {    struct array *a = Pike_sp[-args].u.array;       if( (a->type_field & ~BIT_STRING) &&    (array_fix_type_field(a) & ~BIT_STRING) ) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->write()", 1, "string|array(string)"); +  SIMPLE_BAD_ARG_ERROR("write", 1, "string|array(string)");       i = a->size;    while(i--)    if (a->item[i].u.string->size_shift)    Pike_error("Bad argument 1 to file->write().\n"    "Element %ld is a wide string.\n",    DO_NOT_WARN((long)i));      #ifdef HAVE_WRITEV    if (args > 1) {
pike.git/src/modules/_Stdio/file.c:1972: Inside #if defined(HAVE_WRITEV)
   THREADS_DISALLOW();       /* fprintf(stderr, "writev(%d, 0x%08x, %d) => %d\n",    fd, (unsigned int)iov, cnt, i); */       e=errno; /* check_threads_etc may effect errno */    check_threads_etc();       if(i<0)    { -  /* perror("writev"); */ +    #ifdef HAVE_PIKE_SEND_FD    if (fd_info) {    restore_fd_info(fd_info);    }   #endif    switch(e)    {    default:    free(iovbase);    ERRNO=errno=e;
pike.git/src/modules/_Stdio/file.c:2190:    *!    *! @seealso    *! @[read_oob()], @[write()]    */   static void file_write_oob(INT32 args)   {    ptrdiff_t written, i;    struct pike_string *str;       if(args<1 || TYPEOF(Pike_sp[-args]) != PIKE_T_STRING) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->write_oob()",1,"string"); +  SIMPLE_BAD_ARG_ERROR("write_oob",1,"string");       if(args > 1)    {    f_sprintf(args);    args=1;    }       if(FD < 0)    Pike_error("File not open for write_oob.\n");   
pike.git/src/modules/_Stdio/file.c:2300: Inside #if defined(HAVE_PIKE_SEND_FD)
  static void file_send_fd(INT32 args)   {    int other_fd;    struct object *o = NULL;    struct my_file *f = NULL;    int *fd_info = NULL;       if(args<1 || (TYPEOF(Pike_sp[-args]) != PIKE_T_OBJECT) ||    !(o = Pike_sp[-args].u.object)->prog ||    (o->prog->inherits[SUBTYPEOF(Pike_sp[-args])].prog != file_program)) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->send_fd()", 1, "object(is Stdio.Fd)"); +  SIMPLE_BAD_ARG_ERROR("send_fd", 1, "Stdio.Fd");       f = (struct my_file *)    (o->storage + o->prog->inherits[SUBTYPEOF(Pike_sp[-args])].storage_offset);       if (f->box.fd == -1) {    Pike_error("Bad argument 1 to Stdio.File->send_fd(): "    "File descriptor not open.\n");    }       if(FD < 0)
pike.git/src/modules/_Stdio/file.c:2395: Inside #if defined(SO_LINGER)
   */   static void file_linger(INT32 args)   {    int fd = FD;    int linger = -1;    struct linger li;       if(fd < 0)    Pike_error("File not open.\n");    -  get_all_args("Stdio.File->linger", args, ".%d", &linger); +  get_all_args("linger", args, ".%d", &linger);       if ((linger < -1) || (linger > 0xffff)) { -  SIMPLE_BAD_ARG_ERROR("Stdio.File->linger()", 1, "int(-1..65535)"); +  SIMPLE_BAD_ARG_ERROR("linger", 1, "int(-1..65535)");    }       if (linger == -1) {    li.l_onoff = 0;    li.l_linger = 15;    } else {    li.l_onoff = 1;    li.l_linger = linger;    }   
pike.git/src/modules/_Stdio/file.c:2680:    */   static void file_open(INT32 args)   {    int flags,fd;    int access;    int err;    struct pike_string *str, *flag_str;    close_fd();       if(args < 2) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->open", 2); +  SIMPLE_TOO_FEW_ARGS_ERROR("open", 2);       if(TYPEOF(Pike_sp[-args]) != PIKE_T_STRING &&    TYPEOF(Pike_sp[-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->open", 1, "string|int"); +  SIMPLE_BAD_ARG_ERROR("open", 1, "string|int");       if(TYPEOF(Pike_sp[1-args]) != PIKE_T_STRING) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->open", 2, "string"); +  SIMPLE_BAD_ARG_ERROR("open", 2, "string");       if (args > 2)    {    if (TYPEOF(Pike_sp[2-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->open", 3, "int"); +  SIMPLE_BAD_ARG_ERROR("open", 3, "int");    access = Pike_sp[2-args].u.integer;    } else    access = 00666;       flags = parse((flag_str = Pike_sp[1-args].u.string)->str);       if (TYPEOF(Pike_sp[-args]) == PIKE_T_STRING)    {    str=Pike_sp[-args].u.string;   
pike.git/src/modules/_Stdio/file.c:2847: Inside #if defined(HAVE_OPENAT)
  static void file_openat(INT32 args)   {    int flags, fd, dir_fd;    int access = 00666;    int err;    struct pike_string *str, *flag_str;       if((dir_fd = FD) < 0)    Pike_error("File not open.\n");    -  get_all_args("Stdio.File->openat", args, "%S%S.%d", -  &str, &flag_str, &access); +  get_all_args("openat", args, "%S%S.%d", &str, &flag_str, &access);       flags = parse(flag_str->str);       if (string_has_null(str)) {    /* Filenames with NUL are not supported. */    ERRNO = errno = ENOENT;    pop_n_elems(args);    push_int(0);    return;    }
pike.git/src/modules/_Stdio/file.c:2967: Inside #if !defined(__NT__) && (defined(HAVE_POSIX_OPENPT) || defined(PTY_MASTER_PATHNAME))
   */   static void file_openpt(INT32 args)   {    int flags,fd;   #ifdef HAVE_POSIX_OPENPT    struct pike_string *flag_str;   #endif    close_fd();       if(args < 1) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->openpt", 2); +  SIMPLE_TOO_FEW_ARGS_ERROR("openpt", 2);       if(TYPEOF(Pike_sp[-args]) != PIKE_T_STRING) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->openpt", 1, "string"); +  SIMPLE_BAD_ARG_ERROR("openpt", 1, "string");      #ifdef HAVE_POSIX_OPENPT    flags = parse((flag_str = Pike_sp[-args].u.string)->str);       if(!( flags & (FILE_READ | FILE_WRITE)))    Pike_error("Must open file for at least one of read and write.\n");       do {    THREADS_ALLOW_UID();    fd=posix_openpt(map(flags));
pike.git/src/modules/_Stdio/file.c:3088:    */   static void file_seek(INT32 args)   {   #ifdef SEEK64    INT64 to = 0;   #else    off_t to = 0;   #endif       if( args < 1) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->seek", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR("seek", 1);      #if defined (SEEK64)    if(is_bignum_object_in_svalue(&Pike_sp[-args])) {    if (!int64_from_bignum(&to, Pike_sp[-args].u.object))    Pike_error ("Bad argument 1 to Stdio.File->seek(). Offset too large.\n");    }    else   #endif    if(TYPEOF(Pike_sp[-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->seek", 1, "int"); +  SIMPLE_BAD_ARG_ERROR("seek", 1, "int");    else    to=Pike_sp[-args].u.integer;       if(FD < 0)    Pike_error("File not open.\n");       if(args>1)    {    if(TYPEOF(Pike_sp[-args+1]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->seek", 2, "int"); +  SIMPLE_BAD_ARG_ERROR("seek", 2, "int");    to *= Pike_sp[-args+1].u.integer;    }    if(args>2)    {    if(TYPEOF(Pike_sp[-args+2]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->seek", 3, "int"); +  SIMPLE_BAD_ARG_ERROR("seek", 3, "int");    to += Pike_sp[-args+2].u.integer;    }       ERRNO=0;      #if defined(HAVE_LSEEK64) && !defined(__NT__)    to = lseek64(FD,to,to<0 ? SEEK_END : SEEK_SET);   #else    to = fd_lseek(FD,to,to<0 ? SEEK_END : SEEK_SET);   #endif
pike.git/src/modules/_Stdio/file.c:3189:   static void file_truncate(INT32 args)   {   #if defined(INT64)    INT64 len = 0;   #else    off_t len = 0;   #endif    int res;       if(args<1) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->truncate", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR("truncate", 1);      #if defined (INT64)   #if defined (HAVE_FTRUNCATE64) || SIZEOF_OFF_T > SIZEOF_INT_TYPE    if(is_bignum_object_in_svalue(&Pike_sp[-args])) {    if (!int64_from_bignum(&len, Pike_sp[-args].u.object))    Pike_error ("Bad argument 1 to Stdio.File->truncate(). Length too large.\n");    }    else   #endif   #endif    if(TYPEOF(Pike_sp[-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->truncate", 1, "int"); +  SIMPLE_BAD_ARG_ERROR("truncate", 1, "int");    else    len = Pike_sp[-args].u.integer;       if(FD < 0)    Pike_error("File not open.\n");       ERRNO=0;   #ifdef HAVE_FTRUNCATE64    res = ftruncate64 (FD, len);   #else
pike.git/src/modules/_Stdio/file.c:3778:    *!    *! @seealso    *! @[query_backend], @[set_nonblocking], @[set_read_callback], @[set_write_callback], @[set_fs_event_callback]    */   static void file_set_backend (INT32 args)   {    struct my_file *f = THIS;    struct Backend_struct *backend;       if (!args) -  SIMPLE_TOO_FEW_ARGS_ERROR ("Stdio.File->set_backend", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR ("set_backend", 1);    if (TYPEOF(Pike_sp[-args]) != PIKE_T_OBJECT) -  SIMPLE_BAD_ARG_ERROR ("Stdio.File->set_backend", 1, "object(Pike.Backend)"); +  SIMPLE_BAD_ARG_ERROR ("set_backend", 1, "Pike.Backend");    backend = get_storage (Pike_sp[-args].u.object, Backend_program);    if (!backend) -  SIMPLE_BAD_ARG_ERROR ("Stdio.File->set_backend", 1, "object(Pike.Backend)"); +  SIMPLE_BAD_ARG_ERROR ("set_backend", 1, "Pike.Backend");       /* FIXME: Only allow set_backend() if the file is open? */      #ifdef __NT__    if ((THIS->box.fd >= 0) &&    !(fd_query_properties(THIS->box.fd, fd_CAN_NONBLOCK) & fd_CAN_NONBLOCK)) {    Pike_error("set_backend() on non-socket!\n");    }   #endif /* __NT__ */   
pike.git/src/modules/_Stdio/file.c:3886:    *!    *! Default is that the file WILL be closed on exec except for    *! stdin, stdout and stderr.    *!    *! @seealso    *! @[Process.create_process()], @[exec()]    */   static void file_set_close_on_exec(INT32 args)   {    if(args < 1) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->set_close_on_exec", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR("set_close_on_exec", 1);    if(FD <0)    Pike_error("File not open.\n");       if(UNSAFE_IS_ZERO(Pike_sp-args))    {    my_set_close_on_exec(FD,0);    }else{    my_set_close_on_exec(FD,1);    }    pop_n_elems(args);
pike.git/src/modules/_Stdio/file.c:3963:    *! this object. As opposed to using @[open] with a file descriptor    *! number, it will be closed by this object upon destruct or when    *! @[close] is called.    *!    *! @seealso    *! @[release_fd()]    */   static void file_take_fd(INT32 args)   {    if (args < 1) -  SIMPLE_TOO_FEW_ARGS_ERROR ("Stdio.File->take_fd", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR ("take_fd", 1);    if (TYPEOF(Pike_sp[-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR ("Stdio.File->take_fd", 0, "int"); +  SIMPLE_BAD_ARG_ERROR ("take_fd", 0, "int");    change_fd_for_box(&THIS->box, Pike_sp[-args].u.integer);    pop_n_elems(args);   }      PMOD_EXPORT struct object *file_make_object_from_fd(int fd, int mode, int guess)   {    struct object *o;    struct my_file *f;    if (Pike_fp->context->prog == file_program) {    /* Called from within the file (aka Fd) object.
pike.git/src/modules/_Stdio/file.c:4070:    *! @[open_socket()], @[accept()]    */   static void file_set_buffer(INT32 args)   {    INT32 bufsize;    int flags;       if(FD==-1)    Pike_error("Stdio.File->set_buffer() on closed file.\n");    if(!args) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->set_buffer", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR("set_buffer", 1);    if(TYPEOF(Pike_sp[-args]) != PIKE_T_INT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->set_buffer", 1, "int"); +  SIMPLE_BAD_ARG_ERROR("set_buffer", 1, "int");       bufsize=Pike_sp[-args].u.integer;    if(bufsize < 0)    Pike_error("Bufsize must be larger than zero.\n");       if(args>1)    {    if(TYPEOF(Pike_sp[1-args]) != PIKE_T_STRING) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->set_buffer", 2, "string"); +  SIMPLE_BAD_ARG_ERROR("set_buffer", 2, "string");    flags=parse(Pike_sp[1-args].u.string->str);    }else{    flags=FILE_READ | FILE_WRITE;    }    pop_n_elems(args);      #ifdef SOCKET_BUFFER_MAX   #if SOCKET_BUFFER_MAX    if(bufsize>SOCKET_BUFFER_MAX) bufsize=SOCKET_BUFFER_MAX;   #endif
pike.git/src/modules/_Stdio/file.c:4158:   int my_socketpair(int family, int type, int protocol, int sv[2])   {    static struct sockaddr_in my_addr;    struct sockaddr_in addr,addr2;    int retries=0;    /* Solaris and AIX think this variable should be a size_t, everybody else    * thinks it should be an int.    */    ACCEPT_SIZE_T len;    -  MEMSET(&addr,0,sizeof(struct sockaddr_in)); +  memset(&addr,0,sizeof(struct sockaddr_in));       /* We lie, we actually create an AF_INET socket... */    if(family != AF_UNIX || type != SOCK_STREAM)    {    errno=EINVAL;    return -1;    }       sv[0] = -1;   
pike.git/src/modules/_Stdio/file.c:4190:    SP_DEBUG((stderr, "my_socketpair:fd_socket() failed, errno:%d\n",    errno));    return -1;    }       /* I wonder what is most common a loopback on ip# 127.0.0.1 or    * a loopback with the name "localhost"?    * Let's hope those few people who don't have socketpair have    * a loopback on 127.0.0.1    */ -  MEMSET(&my_addr,0,sizeof(struct sockaddr_in)); +  memset(&my_addr,0,sizeof(struct sockaddr_in));    my_addr.sin_family=AF_INET;    my_addr.sin_addr.s_addr=htonl(INADDR_ANY);    my_addr.sin_port=htons(0);          /* Bind our sockets on any port */    if(fd_bind(socketpair_fd, (struct sockaddr *)&my_addr, sizeof(addr)) < 0)    {    SP_DEBUG((stderr, "my_socketpair:fd_bind() failed, errno:%d\n",    errno));
pike.git/src/modules/_Stdio/file.c:4606:    *!    *! @seealso    *! @[assign()], @[dup()]    */   static void file_dup2(INT32 args)   {    struct object *o;    struct my_file *fd;       if(args < 1) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->dup2", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR("dup2", 1);       if(FD < 0)    Pike_error("File not open.\n");       if(TYPEOF(Pike_sp[-args]) != PIKE_T_OBJECT) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->dup2", 1, "Stdio.File"); +  SIMPLE_BAD_ARG_ERROR("dup2", 1, "Stdio.File");       o=Pike_sp[-args].u.object;       fd=get_file_storage(o);       if(!fd) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->dup2", 1, "Stdio.File"); +  SIMPLE_BAD_ARG_ERROR("dup2", 1, "Stdio.File");       if(fd->box.fd < 0) {    int new_fd;    if((new_fd = fd_dup(FD)) < 0)    {    ERRNO = errno;    pop_n_elems(args);    push_int(0);    return;    }
pike.git/src/modules/_Stdio/file.c:4725:       if (args) {    PIKE_SOCKADDR addr;    int addr_len;    char *name;    int o;       if (TYPEOF(Pike_sp[-args]) != PIKE_T_INT &&    (TYPEOF(Pike_sp[-args]) != PIKE_T_STRING ||    Pike_sp[-args].u.string->size_shift)) { -  SIMPLE_BAD_ARG_ERROR("Stdio.File->open_socket", 1, "int|string (8bit)"); +  SIMPLE_BAD_ARG_ERROR("open_socket", 1, "int|string(8bit)");    }    if (args > 1 && !UNSAFE_IS_ZERO(&Pike_sp[1-args])) {    if (TYPEOF(Pike_sp[1-args]) != PIKE_T_STRING) { -  SIMPLE_BAD_ARG_ERROR("Stdio.File->open_socket", 2, "string"); +  SIMPLE_BAD_ARG_ERROR("open_socket", 2, "string");    }       name = Pike_sp[1-args].u.string->str;    } else {    name = NULL;    }    addr_len = get_inet_addr(&addr, name,    (TYPEOF(Pike_sp[-args]) == PIKE_T_STRING?    Pike_sp[-args].u.string->str : NULL),    (TYPEOF(Pike_sp[-args]) == PIKE_T_INT?
pike.git/src/modules/_Stdio/file.c:4875:    push_int(1);   }      /*! @decl int(0..1) set_keepalive(int(0..1) on_off)    */   static void file_set_keepalive(INT32 args)   {    int tmp, i;    INT_TYPE t;    -  get_all_args("Stdio.File->set_keepalive", args, "%i", &t); +  get_all_args("set_keepalive", args, "%i", &t);       /* In case int and INT_TYPE have different sizes */    tmp = t;      #ifdef SO_KEEPALIVE    i = fd_setsockopt(FD,SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));    if(i)    {    ERRNO=errno;    }else{
pike.git/src/modules/_Stdio/file.c:4943:    *! @[path] had a quite restrictive length limit (~100 characters)    *! prior to Pike 7.8.334.    */   static void file_connect_unix( INT32 args )   {    struct sockaddr_un *name;    int addr_len;    int tmp;       if( args < 1 ) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->connect_unix", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR("connect_unix", 1);    if( (TYPEOF(Pike_sp[-args]) != PIKE_T_STRING) ||    (Pike_sp[-args].u.string->size_shift) )    Pike_error("Illegal argument. Expected string(8bit)\n");       /* NOTE: Some operating systems (eg Linux 2.6) do not support    * paths longer than what fits into a plain struct sockaddr_un.    */    addr_len = sizeof(struct sockaddr_un) + Pike_sp[-args].u.string->len + 1 -    sizeof(name->sun_path);    name = xalloc(addr_len);
pike.git/src/modules/_Stdio/file.c:4994:    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("Stdio.File->connect", args, "%S%*", &dest_addr, &dest_port); +  if (args < 4) +  { +  get_all_args("connect", args, "%S%*", &dest_addr, &dest_port); +  } +  else 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("Stdio.File->connect", args, "%S%*%S%*", +  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("Stdio.File->connect", 2, "int|string (8bit)"); +  SIMPLE_BAD_ARG_ERROR("connect", 2, "int|string(8bit)");       if(src_port && TYPEOF(*src_port) != PIKE_T_INT &&    (TYPEOF(*src_port) != PIKE_T_STRING || src_port->u.string->size_shift)) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->connect", 4, "int|string (8bit)"); +  SIMPLE_BAD_ARG_ERROR("connect", 4, "int|string(8bit)");      /* fprintf(stderr, "connect: family: %d\n", SOCKADDR_FAMILY(addr)); */       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:5117:    /* 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.
pike.git/src/modules/_Stdio/file.c:5235:    *! @note    *! Throws an error if not all data could be written.    *!    *! @seealso    *! @[write()]    */   static void file_lsh(INT32 args)   {    ptrdiff_t len;    if(args < 1) -  SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.File->`<<", 1); +  SIMPLE_TOO_FEW_ARGS_ERROR("`<<", 1);    if(args > 1)    pop_n_elems(args-1);       if(TYPEOF(Pike_sp[-1]) != PIKE_T_STRING)    {    ref_push_type_value(string_type_string);    stack_swap();    f_cast();    }   
pike.git/src/modules/_Stdio/file.c:5270:    *! See @[open()].    *!    *! @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_BAD_ARG_ERROR("Stdio.File->create", 1, "int|string"); +  SIMPLE_BAD_ARG_ERROR("create", 1, "int|string");       close_fd();    file_open(args);   }      #ifdef _REENTRANT      struct new_thread_data   {    INT32 from, to;
pike.git/src/modules/_Stdio/file.c:5348: Inside #if defined(_REENTRANT)
  void file_proxy(INT32 args)   {    struct my_file *f;    struct new_thread_data *p;    int from, to;       THREAD_T id;    check_all_args("Stdio.File->proxy",args, BIT_OBJECT,0);    f=get_file_storage(Pike_sp[-args].u.object);    if(!f) -  SIMPLE_BAD_ARG_ERROR("Stdio.File->proxy", 1, "Stdio.File"); +  SIMPLE_BAD_ARG_ERROR("proxy", 1, "Stdio.File");       from=fd_dup(f->box.fd);    if(from<0)    {    ERRNO=errno;    Pike_error("Failed to dup proxy fd. (errno=%d)\n",errno);    }    to=fd_dup(FD);    if(to<0)    {
pike.git/src/modules/_Stdio/file.c:5853:    *! In Pike 7.5 and later OOB operations are always present.    */      PIKE_MODULE_EXIT   {    exit_stdio_efuns();    exit_stdio_stat();       exit_stdio_udp();    exit_stdio_sendfile(); +  exit_stdio_buffer();       if(file_program)    {    free_program(file_program);    file_program=0;    }    if(file_ref_program)    {    free_program(file_ref_program);    file_ref_program=0;
pike.git/src/modules/_Stdio/file.c:6061:   #endif      PIKE_MODULE_INIT   {    struct object *o;       Pike_compiler->new_program->id = PROG_MODULE_STDIO_ID;       init_stdio_efuns();    init_stdio_stat(); -  +  init_stdio_buffer();    START_NEW_PROGRAM_ID(STDIO_FD);    ADD_STORAGE(struct my_file);      #define FILE_FUNC(X,Y,Z) \    PIKE_CONCAT(Y,_function_number) = ADD_FUNCTION(X,Y,Z,0);   #define FILE_OBJ tObjImpl_STDIO_FD   #include "file_functions.h"       MAP_VARIABLE("_read_callback",tMix,0,    OFFSETOF(my_file, event_cbs[PIKE_FD_READ]),PIKE_T_MIXED);