diff options
Diffstat (limited to 'erts/emulator/drivers')
| -rw-r--r-- | erts/emulator/drivers/common/gzio.c | 5 | ||||
| -rw-r--r-- | erts/emulator/drivers/common/inet_drv.c | 237 | ||||
| -rw-r--r-- | erts/emulator/drivers/unix/unix_efile.c | 581 | ||||
| -rw-r--r-- | erts/emulator/drivers/win32/registry_drv.c | 2 | 
4 files changed, 97 insertions, 728 deletions
diff --git a/erts/emulator/drivers/common/gzio.c b/erts/emulator/drivers/common/gzio.c index a9303d55bc..ca6d25adb4 100644 --- a/erts/emulator/drivers/common/gzio.c +++ b/erts/emulator/drivers/common/gzio.c @@ -21,11 +21,6 @@  #include "erl_driver.h"  #include "sys.h" -#ifdef VXWORKS -/* pull in FOPEN from zutil.h instead */ -#undef F_OPEN -#endif -  #ifdef __WIN32__  #ifndef HAVE_CONFLICTING_FREAD_DECLARATION  #define HAVE_CONFLICTING_FREAD_DECLARATION diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 8f4fff0f40..3210ffa92a 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -284,27 +284,15 @@ static unsigned long one_value = 1;  #else -#ifdef VXWORKS -#include <sockLib.h> -#include <sys/times.h> -#include <iosLib.h> -#include <taskLib.h> -#include <selectLib.h> -#include <ioLib.h> -#else  #include <sys/time.h>  #ifdef NETDB_H_NEEDS_IN_H  #include <netinet/in.h>  #endif  #include <netdb.h> -#endif  #include <sys/socket.h>  #include <netinet/in.h> -#ifdef VXWORKS -#include <rpc/rpctypes.h> -#endif  #ifdef DEF_INADDR_LOOPBACK_IN_RPC_TYPES_H  #include <rpc/types.h>  #endif @@ -312,12 +300,10 @@ static unsigned long one_value = 1;  #include <netinet/tcp.h>  #include <arpa/inet.h> -#if (!defined(VXWORKS))  #include <sys/param.h>  #ifdef HAVE_ARPA_NAMESER_H  #include <arpa/nameser.h>  #endif -#endif  #ifdef HAVE_SYS_SOCKIO_H  #include <sys/sockio.h> @@ -331,7 +317,7 @@ static unsigned long one_value = 1;  /* SCTP support -- currently for UNIX platforms only: */  #undef HAVE_SCTP -#if (!defined(VXWORKS) && !defined(__WIN32__) && defined(HAVE_SCTP_H)) +#if (!defined(__WIN32__) && defined(HAVE_SCTP_H))  #include <netinet/sctp.h> @@ -478,15 +464,8 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)  #define sock_connect(s, addr, len)  connect((s), (addr), (len))  #define sock_listen(s, b)           listen((s), (b))  #define sock_bind(s, addr, len)     bind((s), (addr), (len)) -#ifdef VXWORKS -#define sock_getopt(s,t,n,v,l)      wrap_sockopt(&getsockopt,\ -                                                 s,t,n,v,(unsigned int)(l)) -#define sock_setopt(s,t,n,v,l)      wrap_sockopt(&setsockopt,\ -                                                 s,t,n,v,(unsigned int)(l)) -#else  #define sock_getopt(s,t,n,v,l)      getsockopt((s),(t),(n),(v),(l))  #define sock_setopt(s,t,n,v,l)      setsockopt((s),(t),(n),(v),(l)) -#endif  #define sock_name(s, addr, len)     getsockname((s), (addr), (len))  #define sock_peer(s, addr, len)     getpeername((s), (addr), (len))  #define sock_ntohs(x)               ntohs((x)) @@ -535,6 +514,12 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)  #endif /* __WIN32__ */ +#ifdef HAVE_SOCKLEN_T +#  define SOCKLEN_T socklen_t +#else +#  define SOCKLEN_T int +#endif +  #include "packet_parser.h"  #define get_int24(s) ((((unsigned char*) (s))[0] << 16) | \ @@ -675,6 +660,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)  #define UDP_OPT_MULTICAST_LOOP 13 /* set/get IP multicast loopback */  #define UDP_OPT_ADD_MEMBERSHIP 14 /* add an IP group membership */  #define UDP_OPT_DROP_MEMBERSHIP 15 /* drop an IP group membership */ +#define INET_OPT_IPV6_V6ONLY 16 /* IPv6 only socket, no mapped v4 addrs */  /* LOPT is local options */  #define INET_LOPT_BUFFER      20  /* min buffer size hint */  #define INET_LOPT_HEADER      21  /* list header size */ @@ -685,7 +671,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)  #define INET_LOPT_EXITONCLOSE 26  /* exit port on active close or not ! */  #define INET_LOPT_TCP_HIWTRMRK     27  /* set local high watermark */  #define INET_LOPT_TCP_LOWTRMRK     28  /* set local low watermark */ -#define INET_LOPT_BIT8             29  /* set 8 bit detection */ +                                /* 29  unused */  #define INET_LOPT_TCP_SEND_TIMEOUT 30  /* set send timeout */  #define INET_LOPT_TCP_DELAY_SEND   31  /* Delay sends until next poll */  #define INET_LOPT_PACKET_SIZE      32  /* Max packet size */ @@ -720,12 +706,6 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)  #define INET_IFOPT_FLAGS      6  #define INET_IFOPT_HWADDR     7 -/* INET_LOPT_BIT8 options */ -#define INET_BIT8_CLEAR 0 -#define INET_BIT8_SET   1 -#define INET_BIT8_ON    2 -#define INET_BIT8_OFF   3 -  /* INET_REQ_GETSTAT enumeration */  #define INET_STAT_RECV_CNT   1  #define INET_STAT_RECV_MAX   2 @@ -921,7 +901,6 @@ typedef struct {      int   mode;                 /* BINARY | LIST  				   (affect how to interpret hsz) */      int   exitf;                /* exit port on close or not */ -    int   bit8f;                /* check if data has bit number 7 set */      int   deliver;              /* Delivery mode, TERM or PORT */      ErlDrvTermData caller;      /* recipient of sync reply */ @@ -940,8 +919,6 @@ typedef struct {      int   sfamily;              /* address family */      enum PacketParseType htype; /* header type (TCP only?) */      unsigned int psize;         /* max packet size (TCP only?) */ -    int   bit8;                 /* set if bit8f==true and data some data -				   seen had the 7th bit set */      inet_address remote;        /* remote address for connected sockets */      inet_address peer_addr;     /* fake peer address */      inet_address name_addr;     /* fake local address */ @@ -1191,6 +1168,7 @@ static ErlDrvTermData am_reuseaddr;  static ErlDrvTermData am_dontroute;  static ErlDrvTermData am_priority;  static ErlDrvTermData am_tos; +static ErlDrvTermData am_ipv6_v6only;  #endif  /* speical errors for bad ports and sequences */ @@ -3363,17 +3341,6 @@ static int packet_error_message(udp_descriptor* udesc, int err)  } -/* scan buffer for bit 7 */ -static void scanbit8(inet_descriptor* desc, const char* buf, int len) -{ -    int c; - -    if (!desc->bit8f || desc->bit8) return; -    c = 0; -    while(len--) c |= *buf++; -    desc->bit8 = ((c & 0x80) != 0); -} -  /*   ** active=TRUE:  **  (NOTE! distribution MUST use active=TRUE, deliver=PORT) @@ -3391,8 +3358,6 @@ static int tcp_reply_data(tcp_descriptor* desc, char* buf, int len)      packet_get_body(desc->inet.htype, &body, &bodylen); -    scanbit8(INETP(desc), body, bodylen); -      if (desc->inet.deliver == INET_DELIVER_PORT) {          code = inet_port_data(INETP(desc), body, bodylen);      } @@ -3424,8 +3389,6 @@ tcp_reply_binary_data(tcp_descriptor* desc, ErlDrvBinary* bin, int offs, int len      packet_get_body(desc->inet.htype, &body, &bodylen);      offs = body - bin->orig_bytes; /* body offset now */ -    scanbit8(INETP(desc), body, bodylen); -      if (desc->inet.deliver == INET_DELIVER_PORT)          code = inet_port_binary_data(INETP(desc), bin, offs, bodylen);      else if ((code=packet_parse(desc->inet.htype, buf, len, &desc->http_state, @@ -3451,8 +3414,6 @@ packet_reply_binary_data(inet_descriptor* desc, unsigned  int hsz,  {      int code; -    scanbit8(desc, bin->orig_bytes+offs, len); -      if (desc->active == INET_PASSIVE)  	/* "inet" is actually for both UDP and SCTP, as well as TCP! */  	return inet_async_binary_data(desc, hsz, bin, offs, len, extra); @@ -3527,6 +3488,7 @@ static void inet_init_sctp(void) {      INIT_ATOM(dontroute);      INIT_ATOM(priority);      INIT_ATOM(tos); +    INIT_ATOM(ipv6_v6only);      /* Option names */      INIT_ATOM(sctp_rtoinfo); @@ -5313,50 +5275,6 @@ static ErlDrvSSizeT inet_ctl_getifaddrs(inet_descriptor* desc_p,  #endif - - -#ifdef VXWORKS -/* -** THIS is a terrible creature, a bug in the TCP part -** of the old VxWorks stack (non SENS) created a race. -** If (and only if?) a socket got closed from the other -** end and we tried a set/getsockopt on the TCP level, -** the task would generate a bus error... -*/ -static STATUS wrap_sockopt(STATUS (*function)() /* Yep, no parameter -                                                   check */, -                           int s, int level, int optname, -                           char *optval, unsigned int optlen  -                           /* optlen is a pointer if function  -                              is getsockopt... */) -{ -    fd_set rs; -    struct timeval timeout; -    int to_read; -    int ret; - -    FD_ZERO(&rs); -    FD_SET(s,&rs); -    memset(&timeout,0,sizeof(timeout)); -    if (level == IPPROTO_TCP) { -        taskLock(); -        if (select(s+1,&rs,NULL,NULL,&timeout)) { -            if (ioctl(s,FIONREAD,(int)&to_read) == ERROR || -                to_read == 0) { /* End of file, other end closed? */ -                sock_errno() = EBADF; -                taskUnlock(); -                return ERROR; -            } -        } -        ret = (*function)(s,level,optname,optval,optlen); -        taskUnlock(); -    } else { -        ret = (*function)(s,level,optname,optval,optlen); -    } -    return ret; -} -#endif -  /* Per H @ Tail-f: The original code here had problems that possibly     only occur if you abuse it for non-INET sockets, but anyway:     a) If the getsockopt for SO_PRIORITY or IP_TOS failed, the actual @@ -5382,13 +5300,8 @@ static int setopt_prio_tos_trick      int          res;      int          res_prio;      int          res_tos; -#ifdef HAVE_SOCKLEN_T -	    socklen_t -#else -		int -#endif -		tmp_arg_sz_prio = sizeof(tmp_ival_prio), -		tmp_arg_sz_tos  = sizeof(tmp_ival_tos); +    SOCKLEN_T    tmp_arg_sz_prio = sizeof(tmp_ival_prio); +    SOCKLEN_T    tmp_arg_sz_tos  = sizeof(tmp_ival_tos);      res_prio = sock_getopt(fd, SOL_SOCKET, SO_PRIORITY,  		      (char *) &tmp_ival_prio, &tmp_arg_sz_prio); @@ -5532,29 +5445,6 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)  	    desc->exitf = ival;  	    continue; -	case INET_LOPT_BIT8: -	    DEBUGF(("inet_set_opts(%ld): s=%d, BIT8=%d\r\n", -		    (long)desc->port, desc->s, ival)); -	    switch(ival) { -	    case INET_BIT8_ON: -		desc->bit8f = 1; -		desc->bit8  = 0; -		break; -	    case INET_BIT8_OFF: -		desc->bit8f = 0; -		desc->bit8  = 0; -		break; -	    case INET_BIT8_CLEAR: -		desc->bit8f = 1; -		desc->bit8  = 0; -		break; -	    case INET_BIT8_SET: -		desc->bit8f = 1; -		desc->bit8  = 1; -		break; -	    } -	    continue; -  	case INET_LOPT_TCP_HIWTRMRK:  	    if (desc->stype == SOCK_STREAM) {  		tcp_descriptor* tdesc = (tcp_descriptor*) desc; @@ -5636,23 +5526,11 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)  	case INET_OPT_SNDBUF:    type = SO_SNDBUF;   	    DEBUGF(("inet_set_opts(%ld): s=%d, SO_SNDBUF=%d\r\n",  		    (long)desc->port, desc->s, ival)); -	    /*  -	     * Setting buffer sizes in VxWorks gives unexpected results -	     * our workaround is to leave it at default. -	     */ -#ifdef VXWORKS -	    goto skip_os_setopt; -#else  	    break; -#endif  	case INET_OPT_RCVBUF:    type = SO_RCVBUF;   	    DEBUGF(("inet_set_opts(%ld): s=%d, SO_RCVBUF=%d\r\n",  		    (long)desc->port, desc->s, ival)); -#ifdef VXWORKS -	    goto skip_os_setopt; -#else  	    break; -#endif  	case INET_OPT_LINGER:    type = SO_LINGER;   	    if (len < 4)  		return -1; @@ -5743,6 +5621,23 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)  #endif /* HAVE_MULTICAST_SUPPORT */ +	case INET_OPT_IPV6_V6ONLY: +#if HAVE_DECL_IPV6_V6ONLY +	    proto = IPPROTO_IPV6; +	    type = IPV6_V6ONLY; +	    propagate = 1; +	    DEBUGF(("inet_set_opts(%ld): s=%d, IPV6_V6ONLY=%d\r\n", +		    (long)desc->port, desc->s, ival)); +	    break; +#elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) +	    /* Fake a'la OpenBSD; set to 'true' is fine but 'false' invalid. */ +	    if (ival != 0) continue; +	    else return -1; +	    break; +#else +	    continue; +#endif +  	case INET_OPT_RAW:  	    if (len < 8) {  		return -1; @@ -5774,9 +5669,6 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)  	}  	DEBUGF(("inet_set_opts(%ld): s=%d returned %d\r\n",  		(long)desc->port, desc->s, res)); -#ifdef VXWORKS -skip_os_setopt: -#endif  	if (type == SO_RCVBUF) {  	    /* make sure we have desc->bufsz >= SO_RCVBUF */  	    if (ival > desc->bufsz) @@ -6075,6 +5967,22 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)  	    continue; /* Option not supported -- ignore it */  #	endif +	case INET_OPT_IPV6_V6ONLY: +#       if HAVE_DECL_IPV6_V6ONLY +	{ +	    arg.ival= get_int32 (curr);   curr += 4; +	    proto   = IPPROTO_IPV6; +	    type    = IPV6_V6ONLY; +	    arg_ptr = (char*) (&arg.ival); +	    arg_sz  = sizeof  ( arg.ival); +	    break; +	} +#       elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) +#           error Here is a fix for Win IPv6 SCTP missing +#       else +	    continue; /* Option not supported -- ignore it */ +#       endif +  	case SCTP_OPT_AUTOCLOSE:  	{  	    arg.ival= get_int32 (curr);	  curr += 4; @@ -6437,15 +6345,6 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc,  	    put_int32(desc->exitf, ptr);  	    continue; -	case INET_LOPT_BIT8: -	    *ptr++ = opt; -	    if (desc->bit8f) { -		put_int32(desc->bit8, ptr); -	    } else { -		put_int32(INET_BIT8_OFF, ptr); -	    } -	    continue; -  	case INET_LOPT_TCP_HIWTRMRK:  	    if (desc->stype == SOCK_STREAM) {  		*ptr++ = opt; @@ -6572,6 +6471,22 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc,  	    break;  #endif /* HAVE_MULTICAST_SUPPORT */ +	case INET_OPT_IPV6_V6ONLY: +#if HAVE_DECL_IPV6_V6ONLY +	    proto = IPPROTO_IPV6; +	    type = IPV6_V6ONLY; +	    break; +#elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) +	    /* Fake reading 'true' */ +	    *ptr++ = opt; +	    put_int32(1, ptr); +	    ptr += 4; +	    continue; +#else +	    TRUNCATE_TO(0,ptr); +	    continue; /* skip - no result */ +#endif +  	case INET_OPT_RAW:  	    {  		int data_provided; @@ -6876,6 +6791,7 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc,  	case INET_OPT_DONTROUTE:  	case INET_OPT_PRIORITY :  	case INET_OPT_TOS      : +	case INET_OPT_IPV6_V6ONLY:  	case SCTP_OPT_AUTOCLOSE:  	case SCTP_OPT_MAXSEG   :  	/* The following options return true or false:	       */ @@ -6948,6 +6864,20 @@ static ErlDrvSSizeT sctp_fill_opts(inet_descriptor* desc,  		continue;  #	    endif  	    } +	    case INET_OPT_IPV6_V6ONLY: +#           if HAVE_DECL_IPV6_V6ONLY +	    { +		proto  = IPPROTO_IPV6; +		type   = IPV6_V6ONLY; +		tag    = am_ipv6_v6only; +		break; +	    } +#           elif defined(__WIN32__) && defined(HAVE_IN6) && defined(AF_INET6) +#               error Here is a fix for Win IPv6 SCTP needed +#           else +		/* Not supported -- ignore */ +		continue; +#           endif  	    case SCTP_OPT_AUTOCLOSE:  	    {  		proto  = IPPROTO_SCTP; @@ -7504,8 +7434,6 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol)      desc->mode    = INET_MODE_LIST;    /* list mode */      desc->exitf   = 1;                 /* exit port when close on active   					  socket */ -    desc->bit8f   = 0; -    desc->bit8    = 0;      desc->deliver = INET_DELIVER_TERM; /* standard term format */      desc->active  = INET_PASSIVE;      /* start passive */      desc->oph = NULL; @@ -7813,8 +7741,8 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,  	desc->state = INET_STATE_BOUND;  	if ((port = inet_address_port(&local)) == 0) { -	    len = sizeof(local); -	    sock_name(desc->s, (struct sockaddr*) &local, (unsigned int*)&len); +	    SOCKLEN_T adrlen = sizeof(local); +	    sock_name(desc->s, &local.sa, &adrlen);  	    port = inet_address_port(&local);  	}  	port = sock_ntohs(port); @@ -7849,8 +7777,6 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,        return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);      } -#ifndef VXWORKS -      case INET_REQ_GETSERVBYNAME: { /* L1 Name-String L2 Proto-String */  	char namebuf[256];  	char protobuf[256]; @@ -7901,8 +7827,6 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,  	return ctl_reply(INET_REP_OK, srv->s_name, len, rbuf, rsize);      } -#endif /* !VXWORKS */	 -      default:  	return ctl_xerror(EXBADPORT, rbuf, rsize);      } @@ -8133,7 +8057,6 @@ static tcp_descriptor* tcp_inet_copy(tcp_descriptor* desc,SOCKET s,      /* Some flags must be inherited at this point */      copy_desc->inet.mode     = desc->inet.mode;      copy_desc->inet.exitf    = desc->inet.exitf; -    copy_desc->inet.bit8f    = desc->inet.bit8f;      copy_desc->inet.deliver  = desc->inet.deliver;      copy_desc->inet.htype    = desc->inet.htype;       copy_desc->inet.psize    = desc->inet.psize;  @@ -9838,7 +9761,6 @@ static udp_descriptor* sctp_inet_copy(udp_descriptor* desc, SOCKET s, int* err)      /* Some flags must be inherited at this point */      copy_desc->inet.mode     = desc->inet.mode;      copy_desc->inet.exitf    = desc->inet.exitf; -    copy_desc->inet.bit8f    = desc->inet.bit8f;      copy_desc->inet.deliver  = desc->inet.deliver;      copy_desc->inet.htype    = desc->inet.htype;      copy_desc->inet.psize    = desc->inet.psize; @@ -10240,6 +10162,7 @@ static ErlDrvSSizeT packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf,  	    }  	    new_udesc->inet.state = INET_STATE_CONNECTED;  	    new_udesc->inet.stype = SOCK_STREAM; +	    SET_NONBLOCKING(new_udesc->inet.s);  	    inet_reply_ok_port(desc, new_udesc->inet.dport);  	    (*rbuf)[0] = INET_REP; diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index b250bac4dc..cf7af71b92 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -45,23 +45,6 @@  #include <fcntl.h>  #endif /* DARWIN */ -#ifdef VXWORKS -#include <ioLib.h> -#include <dosFsLib.h> -#include <nfsLib.h> -#include <sys/stat.h> -/* -** Not nice to include usrLib.h as MANY normal variable names get reported -** as shadowing globals, like 'i' for example. -** Instead we declare the only function we use here -*/ -/* - * #include <usrLib.h> - */ -extern STATUS copy(char *, char *); -#include <errno.h> -#endif -  #ifdef SUNOS4  #  define getcwd(buf, size) getwd(buf)  #endif @@ -93,276 +76,27 @@ extern STATUS copy(char *, char *);  #define DIR_MODE  0777  #endif -#ifdef VXWORKS /* Currently only used on vxworks */ - -#define EF_ALLOC(S)		driver_alloc((S)) -#define EF_REALLOC(P, S)	driver_realloc((P), (S)) -#define EF_SAFE_ALLOC(S)	ef_safe_alloc((S)) -#define EF_SAFE_REALLOC(P, S)	ef_safe_realloc((P), (S)) -#define EF_FREE(P)		do { if((P)) driver_free((P)); } while(0) - -void erl_exit(int n, char *fmt, ...); - -static void *ef_safe_alloc(Uint s) -{ -    void *p = EF_ALLOC(s); -    if (!p) erl_exit(1, -		     "unix efile drv: Can't allocate %lu bytes of memory\n", -		     (unsigned long)s); -    return p; -} - -#if 0 /* Currently not used */ - -static void *ef_safe_realloc(void *op, Uint s) -{ -    void *p = EF_REALLOC(op, s); -    if (!p) erl_exit(1, -		     "unix efile drv: Can't reallocate %lu bytes of memory\n", -		     (unsigned long)s); -    return p; -} - -#endif /* #if 0 */ -#endif /* #ifdef VXWORKS */ -  #define IS_DOT_OR_DOTDOT(s) \      (s[0] == '.' && (s[1] == '\0' || (s[1] == '.' && s[2] == '\0'))) -#ifdef VXWORKS -static int vxworks_to_posix(int vx_errno); -#endif - -/* -** VxWorks (not) strikes again. Too long RESULTING paths -** may give the infamous bus error. Have to check ALL -** filenames and pathnames. No wonder the emulator is slow on -** these cards... -*/ -#ifdef VXWORKS -#define CHECK_PATHLEN(Name, ErrInfo)		\ -   if (path_size(Name) > PATH_MAX) {		\ -       errno = ENAMETOOLONG;			\ -       return check_error(-1, ErrInfo);		\ -   } -#else -#define CHECK_PATHLEN(X,Y) /* Nothing */ -#endif -  static int check_error(int result, Efile_error* errInfo);  static int  check_error(int result, Efile_error *errInfo)  {      if (result < 0) { -#ifdef VXWORKS -	errInfo->posix_errno = errInfo->os_errno = vxworks_to_posix(errno); -#else  	errInfo->posix_errno = errInfo->os_errno = errno; -#endif  	return 0;      }      return 1;  } -#ifdef VXWORKS - -/* - * VxWorks has different error codes for different file systems. - * We map those to POSIX ones. - */ -static int -vxworks_to_posix(int vx_errno) -{ -    DEBUGF(("[vxworks_to_posix] vx_errno: %08x\n", vx_errno)); -    switch (vx_errno) { -	/* dosFsLib mapping */ -#ifdef S_dosFsLib_FILE_ALREADY_EXISTS     -    case S_dosFsLib_FILE_ALREADY_EXISTS: return EEXIST; -#else -    case S_dosFsLib_FILE_EXISTS: return EEXIST; -#endif -#ifdef S_dosFsLib_BAD_DISK -    case S_dosFsLib_BAD_DISK: return EIO; -#endif -#ifdef S_dosFsLib_CANT_CHANGE_ROOT -    case S_dosFsLib_CANT_CHANGE_ROOT: return EINVAL; -#endif -#ifdef S_dosFsLib_NO_BLOCK_DEVICE -    case S_dosFsLib_NO_BLOCK_DEVICE: return ENOTBLK; -#endif -#ifdef S_dosFsLib_BAD_SEEK -    case S_dosFsLib_BAD_SEEK: return ESPIPE; -#endif -    case S_dosFsLib_VOLUME_NOT_AVAILABLE: return ENXIO; -    case S_dosFsLib_DISK_FULL: return ENOSPC; -    case S_dosFsLib_FILE_NOT_FOUND: return ENOENT; -    case S_dosFsLib_NO_FREE_FILE_DESCRIPTORS: return ENFILE; -    case S_dosFsLib_INVALID_NUMBER_OF_BYTES: return EINVAL; -    case S_dosFsLib_ILLEGAL_NAME: return EINVAL; -    case S_dosFsLib_CANT_DEL_ROOT: return EACCES; -    case S_dosFsLib_NOT_FILE: return EISDIR; -    case S_dosFsLib_NOT_DIRECTORY: return ENOTDIR; -    case S_dosFsLib_NOT_SAME_VOLUME: return EXDEV; -    case S_dosFsLib_READ_ONLY: return EACCES; -    case S_dosFsLib_ROOT_DIR_FULL: return ENOSPC; -    case S_dosFsLib_DIR_NOT_EMPTY: return EEXIST; -    case S_dosFsLib_NO_LABEL: return ENXIO; -    case S_dosFsLib_INVALID_PARAMETER: return EINVAL; -    case S_dosFsLib_NO_CONTIG_SPACE: return ENOSPC; -    case S_dosFsLib_FD_OBSOLETE: return EBADF; -    case S_dosFsLib_DELETED: return EINVAL; -    case S_dosFsLib_INTERNAL_ERROR: return EIO; -    case S_dosFsLib_WRITE_ONLY: return EACCES; -	/* nfsLib mapping - is needed since Windriver has used */ -	/* inconsistent error codes (errno.h/nfsLib.h). */ -    case S_nfsLib_NFS_OK: return 0; -    case S_nfsLib_NFSERR_PERM: return EPERM; -    case S_nfsLib_NFSERR_NOENT: return ENOENT; -    case S_nfsLib_NFSERR_IO: return EIO; -    case S_nfsLib_NFSERR_NXIO: return ENXIO; -#ifdef S_nfsLib_NFSERR_ACCES -    case S_nfsLib_NFSERR_ACCES: return EACCES; -#else -    case S_nfsLib_NFSERR_ACCESS: return EACCES; -#endif -    case S_nfsLib_NFSERR_EXIST: return EEXIST; -    case S_nfsLib_NFSERR_NODEV: return ENODEV; -    case S_nfsLib_NFSERR_NOTDIR: return ENOTDIR; -    case S_nfsLib_NFSERR_ISDIR: return EISDIR; -    case S_nfsLib_NFSERR_FBIG: return EFBIG; -    case S_nfsLib_NFSERR_NOSPC: return ENOSPC; -    case S_nfsLib_NFSERR_ROFS: return EROFS; -    case S_nfsLib_NFSERR_NAMETOOLONG: return ENAMETOOLONG; -    case S_nfsLib_NFSERR_NOTEMPTY: return EEXIST; -    case S_nfsLib_NFSERR_DQUOT: return ENOSPC; -    case S_nfsLib_NFSERR_STALE: return EINVAL; -    case S_nfsLib_NFSERR_WFLUSH: return ENXIO; -	/* And sometimes (...) the error codes are from ioLib (as in the */ -	/* case of the (for nfsLib) unimplemented rename function) */ -    case  S_ioLib_DISK_NOT_PRESENT: return EIO; -#if S_ioLib_DISK_NOT_PRESENT != S_ioLib_NO_DRIVER -    case S_ioLib_NO_DRIVER: return ENXIO; -#endif -    case S_ioLib_UNKNOWN_REQUEST: return ENOSYS; -    case  S_ioLib_DEVICE_TIMEOUT: return EIO; -#ifdef S_ioLib_UNFORMATED -	/* Added (VxWorks 5.2 -> 5.3.1) */ -  #if S_ioLib_UNFORMATED != S_ioLib_DEVICE_TIMEOUT -    case S_ioLib_UNFORMATED: return EIO; -  #endif -#endif -#if S_ioLib_DEVICE_TIMEOUT != S_ioLib_DEVICE_ERROR -    case S_ioLib_DEVICE_ERROR: return ENXIO; -#endif -    case S_ioLib_WRITE_PROTECTED: return EACCES; -    case S_ioLib_NO_FILENAME: return EINVAL; -    case S_ioLib_CANCELLED: return EINTR; -    case  S_ioLib_NO_DEVICE_NAME_IN_PATH: return EINVAL; -    case  S_ioLib_NAME_TOO_LONG: return ENAMETOOLONG; -#ifdef S_objLib_OBJ_UNAVAILABLE -    case S_objLib_OBJ_UNAVAILABLE: return ENOENT; -#endif - -      /* Temporary workaround for a weird error in passFs  -	 (VxWorks Simsparc only). File operation fails because of -	 ENOENT, but errno is not set. */ -#ifdef SIMSPARCSOLARIS -    case 0: return ENOENT; -#endif - -    } -    /* If the error code matches none of the above, assume */ -    /* it is a POSIX one already. The upper bits (>=16) are */ -    /* cleared since VxWorks uses those bits to indicate in */ -    /* what module the error occured. */ -    return vx_errno & 0xffff; -} - -static int  -vxworks_enotsup(Efile_error *errInfo)  -{ -    errInfo->posix_errno = errInfo->os_errno = ENOTSUP; -    return 0; -} - -static int  -count_path_length(char *pathname, char *pathname2) -{ -    static int stack[PATH_MAX / 2 + 1]; -    int sp = 0; -    char *tmp; -    char *cpy = NULL; -    int i; -    int sum; -    for(i = 0;i < 2;++i) { -	if (!i) { -	    cpy = EF_SAFE_ALLOC(strlen(pathname)+1); -	    strcpy(cpy, pathname); -	} else if (pathname2 != NULL) { -	    EF_FREE(cpy); -	    cpy = EF_SAFE_ALLOC(strlen(pathname2)+1); -	    strcpy(cpy, pathname2); -	} else  -	    break; -	     -	for (tmp = strtok(cpy,"/"); tmp != NULL; tmp = strtok(NULL,"/")) { -	    if (!strcmp(tmp,"..") && sp > 0) -		--sp; -	    else if (strcmp(tmp,"."))  -		stack[sp++] = strlen(tmp); -	} -    } -    if (cpy != NULL) -	EF_FREE(cpy); -    sum = 0; -    for(i = 0;i < sp; ++i) -	sum += stack[i]+1; -    return (sum) ? sum : 1; -} - -static int  -path_size(char *pathname)  -{ -    static char currdir[PATH_MAX+2]; -    if (*pathname == '/')  -	return count_path_length(pathname,NULL); -    ioDefPathGet(currdir); -    strcat(currdir,"/"); -    return count_path_length(currdir,pathname); -} -     -#endif /* VXWORKS */ -  int  efile_mkdir(Efile_error* errInfo,	/* Where to return error codes. */  	    char* name)			/* Name of directory to create. */  { -    CHECK_PATHLEN(name,errInfo);  #ifdef NO_MKDIR_MODE -#ifdef VXWORKS -	/* This is a VxWorks/nfs workaround for erl_tar to create -	 * non-existant directories. (of some reason (...) VxWorks -	 * returns, the *non-module-prefixed*, 0xd code when -	 * trying to create a directory in a directory that doesn't exist). -	 * (see efile_openfile) -	 */ -    if (mkdir(name) < 0) { -	struct stat sb; -	if (name[0] == '\0') { -	/* Return the correct error code enoent */  -	    errno = S_nfsLib_NFSERR_NOENT; -	} else if (stat(name, &sb) == OK) { -	    errno = S_nfsLib_NFSERR_EXIST; -	} else if((strchr(name, '/') != NULL) && (errno == 0xd)) { -	/* Return the correct error code enoent */  -	    errno = S_nfsLib_NFSERR_NOENT; -	} -	return check_error(-1, errInfo); -    } else return 1; -#else      return check_error(mkdir(name), errInfo); -#endif  #else      return check_error(mkdir(name, DIR_MODE), errInfo);  #endif @@ -372,16 +106,9 @@ int  efile_rmdir(Efile_error* errInfo,	/* Where to return error codes. */  	    char* name)			/* Name of directory to delete. */  { -    CHECK_PATHLEN(name, errInfo);      if (rmdir(name) == 0) {  	return 1;      } -#ifdef VXWORKS -    if (name[0] == '\0') { -	/* Return the correct error code enoent */  -	errno = S_nfsLib_NFSERR_NOENT; -    } -#else      if (errno == ENOTEMPTY) {  	errno = EEXIST;      } @@ -401,7 +128,6 @@ efile_rmdir(Efile_error* errInfo,	/* Where to return error codes. */  	}  	errno = saved_errno;      } -#endif      return check_error(-1, errInfo);  } @@ -409,7 +135,6 @@ int  efile_delete_file(Efile_error* errInfo,	/* Where to return error codes. */  		  char* name)		/* Name of file to delete. */  { -    CHECK_PATHLEN(name,errInfo);      if (unlink(name) == 0) {  	return 1;      } @@ -457,32 +182,13 @@ efile_rename(Efile_error* errInfo,	/* Where to return error codes. */  	     char* src,		        /* Original name. */  	     char* dst)			/* New name. */  { -    CHECK_PATHLEN(src,errInfo); -    CHECK_PATHLEN(dst,errInfo); -#ifdef VXWORKS -	 -    /* First check if src == dst, if so, just return. */ -    /* VxWorks dos file system destroys the file otherwise, */ -    /* VxWorks nfs file system rename doesn't work at all. */ -    if(strcmp(src, dst) == 0) -	return 1; -#endif      if (rename(src, dst) == 0) {  	return 1;      } -#ifdef VXWORKS -    /* nfs for VxWorks doesn't support rename. We try to emulate it */ -    /* (by first copying src to dst and then deleting src). */ -    if(errno == S_ioLib_UNKNOWN_REQUEST &&     /* error code returned  -						  by ioLib (!) */  -       copy(src, dst) == OK && -       unlink(src) == OK) -	return 1; -#endif      if (errno == ENOTEMPTY) {  	errno = EEXIST;      } -#if defined (sparc) && !defined(VXWORKS) +#if defined (sparc)      /*       * SunOS 4.1.4 reports overwriting a non-empty directory with a       * directory as EINVAL instead of EEXIST (first rule out the correct @@ -543,7 +249,6 @@ int  efile_chdir(Efile_error* errInfo,   /* Where to return error codes. */  	    char* name)		    /* Name of directory to make current. */  { -    CHECK_PATHLEN(name, errInfo);      return check_error(chdir(name), errInfo);  } @@ -600,8 +305,6 @@ efile_readdir(Efile_error* errInfo,	/* Where to return error codes. */       * If this is the first call, we must open the directory.       */ -    CHECK_PATHLEN(name, errInfo); -      if (*p_dir_handle == NULL) {  	dp = opendir(name);  	if (dp == NULL) @@ -641,26 +344,8 @@ efile_openfile(Efile_error* errInfo,	/* Where to return error codes. */      struct stat statbuf;      int fd;      int mode;			/* Open mode. */ -#ifdef VXWORKS -    char pathbuff[PATH_MAX+2]; -    char sbuff[PATH_MAX*2]; -    char *totbuff = sbuff; -    int nameneed; -#endif - - -    CHECK_PATHLEN(name, errInfo); - -#ifdef VXWORKS -    /* Have to check that it's not a directory. */ -    if (stat(name,&statbuf) != ERROR && ISDIR(statbuf)) { -	errno = EISDIR; -	return check_error(-1, errInfo); -    }	 -#endif	      if (stat(name, &statbuf) >= 0 && !ISREG(statbuf)) { -#if !defined(VXWORKS) && !defined(OSE)  	/*  	 * For UNIX only, here is some ugly code to allow  	 * /dev/null to be opened as a file. @@ -677,12 +362,9 @@ efile_openfile(Efile_error* errInfo,	/* Where to return error codes. */  	    }  	}  	if (!(dev_null_ino && statbuf.st_ino == dev_null_ino)) { -#endif  	    errno = EISDIR;  	    return check_error(-1, errInfo); -#if !defined(VXWORKS) && !defined(OSE)  	} -#endif      }      switch (flags & (EFILE_MODE_READ|EFILE_MODE_WRITE)) { @@ -706,49 +388,14 @@ efile_openfile(Efile_error* errInfo,	/* Where to return error codes. */      if (flags & EFILE_MODE_APPEND) {  	mode &= ~O_TRUNC; -#ifndef VXWORKS -	mode |= O_APPEND; /* Dont make VxWorks think things it shouldn't */ -#endif +	mode |= O_APPEND;      }      if (flags & EFILE_MODE_EXCL) {  	mode |= O_EXCL;      } -#ifdef VXWORKS -    if (*name != '/') { -	/* Make sure it is an absolute pathname, because ftruncate needs it */ -	ioDefPathGet(pathbuff); -	strcat(pathbuff,"/"); -	nameneed = strlen(pathbuff) + strlen(name) + 1; -	if (nameneed > PATH_MAX*2) -	    totbuff = EF_SAFE_ALLOC(nameneed); -	strcpy(totbuff,pathbuff); -	strcat(totbuff,name); -	fd = open(totbuff, mode, FILE_MODE); -	if (totbuff != sbuff) -	    EF_FREE(totbuff); -    } else { -	fd = open(name, mode, FILE_MODE); -    } -#else      fd = open(name, mode, FILE_MODE); -#endif - -#ifdef VXWORKS - -	/* This is a VxWorks/nfs workaround for erl_tar to create  -	 * non-existant directories. (of some reason (...) VxWorks -	 * returns, the *non-module-prefixed*, 0xd code when -	 * trying to write a file in a directory that doesn't exist). -	 * (see efile_mkdir) -	 */ -    if ((fd < 0) && (strchr(name, '/') != NULL) && (errno == 0xd)) { -	/* Return the correct error code enoent */  -	errno = S_nfsLib_NFSERR_NOENT; -	return check_error(-1, errInfo); -    } -#endif      if (!check_error(fd, errInfo))  	return 0; @@ -797,11 +444,7 @@ efile_fsync(Efile_error *errInfo, /* Where to return error codes. */  	    int fd)               /* File descriptor for file to sync. */  {  #ifdef NO_FSYNC -#ifdef VXWORKS -    return check_error(ioctl(fd, FIOSYNC, 0), errInfo);  -#else -  undefined fsync -#endif /* VXWORKS */ +  undefined fsync /* XXX: Really? */  #else  #if defined(DARWIN) && defined(F_FULLFSYNC)      return check_error(fcntl(fd, F_FULLFSYNC), errInfo); @@ -818,21 +461,8 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,      struct stat statbuf;	/* Information about the file */      int result; -#ifdef VXWORKS -    if (*name == '\0') { -	errInfo->posix_errno = errInfo->os_errno = ENOENT; -	return 0; -    } -#endif - -    CHECK_PATHLEN(name, errInfo); -      if (info_for_link) { -#if (defined(VXWORKS)) -	result = stat(name, &statbuf); -#else  	result = lstat(name, &statbuf); -#endif      } else {  	result = stat(name, &statbuf);      }	 @@ -849,19 +479,9 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,  #ifdef NO_ACCESS      /* Just look at read/write access for owner. */ -#ifdef VXWORKS - -    pInfo->access = FA_NONE; -    if(statbuf.st_mode & S_IRUSR) -        pInfo->access |= FA_READ; -    if(statbuf.st_mode & S_IWUSR) -        pInfo->access |= FA_WRITE; -     -#else      pInfo->access = ((statbuf.st_mode >> 6) & 07) >> 1; -#endif /* VXWORKS */  #else      pInfo->access = FA_NONE;      if (access(name, R_OK) == 0) @@ -902,35 +522,6 @@ efile_write_info(Efile_error *errInfo, Efile_info *pInfo, char *name)  {      struct utimbuf tval; -    CHECK_PATHLEN(name, errInfo); - -#ifdef VXWORKS - -    if (pInfo->mode != -1) { -	int fd; -	struct stat statbuf; - -	fd = open(name, O_RDONLY, 0); -	if (!check_error(fd, errInfo)) -	    return 0; -	if (fstat(fd, &statbuf) < 0) { -	    close(fd); -	    return check_error(-1, errInfo); -	} -	if (pInfo->mode & S_IWUSR) { -	    /* clear read only bit */ -	    statbuf.st_attrib &= ~DOS_ATTR_RDONLY; -	} else { -	    /* set read only bit */ -	    statbuf.st_attrib |= DOS_ATTR_RDONLY; -	} -	/* This should work for dos files but not for nfs ditos, so don't  -	 * report errors (to avoid problems when running e.g. erl_tar) -	 */ -	ioctl(fd, FIOATTRIBSET, statbuf.st_attrib); -	close(fd); -    } -#else      /*       * On some systems chown will always fail for a non-root user unless       * POSIX_CHOWN_RESTRICTED is not set.  Others will succeed as long as  @@ -952,20 +543,10 @@ efile_write_info(Efile_error *errInfo, Efile_info *pInfo, char *name)  	}      } -#endif /* !VXWORKS */ -      tval.actime  = pInfo->accessTime;      tval.modtime = pInfo->modifyTime; -#ifdef VXWORKS -    /* VxWorks' utime doesn't work when the file is a nfs mounted -     * one, don't report error if utime fails. -     */ -    utime(name, &tval); -    return 1; -#else      return check_error(utime(name, &tval), errInfo); -#endif  } @@ -979,11 +560,6 @@ efile_write(Efile_error* errInfo,	/* Where to return error codes. */  {      ssize_t written;			/* Bytes written in last operation. */ -#ifdef VXWORKS -    if (flags & EFILE_MODE_APPEND) { -	lseek(fd, 0, SEEK_END); /* Naive append emulation on VXWORKS */ -    } -#endif      while (count > 0) {  	if ((written = write(fd, buf, count)) < 0) {  	    if (errno != EINTR) @@ -1012,12 +588,6 @@ efile_writev(Efile_error* errInfo,   /* Where to return error codes */      ASSERT(iovcnt >= 0); -#ifdef VXWORKS -    if (flags & EFILE_MODE_APPEND) { -	lseek(fd, 0, SEEK_END);      /* Naive append emulation on VXWORKS */ -    } -#endif -      while (cnt < iovcnt) {  	if ((! iov[cnt].iov_base) || (iov[cnt].iov_len <= 0)) {  	    /* Empty buffer - skip */ @@ -1226,118 +796,6 @@ efile_seek(Efile_error* errInfo,      /* Where to return error codes. */  int  efile_truncate_file(Efile_error* errInfo, int *fd, int flags)  { -#ifdef VXWORKS -    off_t offset; -    char namebuf[PATH_MAX+1]; -    char namebuf2[PATH_MAX+10]; -    int new; -    int dummy; -    int i; -    int left; -    static char buff[1024]; -    struct stat st; -    Efile_error tmperr; - -    if ((offset = lseek(*fd, 0, 1)) < 0) { -	return check_error((int) offset,errInfo); -    } -    if (ftruncate(*fd, offset) < 0) { -	if (vxworks_to_posix(errno) != EINVAL) { -	    return check_error(-1, errInfo); -	} -	/* -	** Kludge -	*/ -	if(ioctl(*fd,FIOGETNAME,(int) namebuf) < 0) { -	    return check_error(-1, errInfo); -	} -	for(i=0;i<1000;++i) { -	    sprintf(namebuf2,"%s%d",namebuf,i); -	    CHECK_PATHLEN(namebuf2,errInfo); -	    if (stat(namebuf2,&st) < 0) { -		break; -	    } -	} -	if (i > 1000) { -	    errno = EINVAL; -	    return check_error(-1, errInfo); -	} -	if (close(*fd) < 0) { -	    return check_error(-1, errInfo); -	} -	if (efile_rename(&tmperr,namebuf,namebuf2) < 0) { -	    i = check_error(-1,&tmperr); -	    if (!efile_openfile(errInfo,namebuf,flags | EFILE_NO_TRUNCATE, -				fd,&dummy)) { -		*fd = -1; -	    } else { -		*errInfo = tmperr; -	    } -	    return i; -	} -	if ((*fd = open(namebuf2, O_RDONLY, 0)) < 0) { -	    i = check_error(-1,errInfo); -	    efile_rename(&tmperr,namebuf2,namebuf); /* at least try */ -	    if (!efile_openfile(errInfo,namebuf,flags | EFILE_NO_TRUNCATE, -				fd,&dummy)) { -		*fd = -1; -	    } else { -		lseek(*fd,offset,SEEK_SET); -	    } -	    return i; -	} -	/* Point of no return... */ - -	if ((new = open(namebuf,O_RDWR | O_CREAT, FILE_MODE)) < 0) { -	    close(*fd); -	    *fd = -1; -	    return 0; -	} -	left = offset; -	 -	while (left) { -	    if ((i = read(*fd,buff,(left > 1024) ? 1024 : left)) < 0) { -		i = check_error(-1,errInfo); -		close(new); -		close(*fd); -		unlink(namebuf); -		efile_rename(&tmperr,namebuf2,namebuf); /* at least try */ -		if (!efile_openfile(errInfo,namebuf,flags | EFILE_NO_TRUNCATE, -				    fd,&dummy)) { -		    *fd = -1; -		} else { -		    lseek(*fd,offset,SEEK_SET); -		} -		return i; -	    } -	    left -= i; -	    if (write(new,buff,i) < 0) { -		i = check_error(-1,errInfo); -		close(new); -		close(*fd); -		unlink(namebuf); -		rename(namebuf2,namebuf); /* at least try */ -		if (!efile_openfile(errInfo,namebuf,flags | EFILE_NO_TRUNCATE, -				    fd,&dummy)) { -		    *fd = -1; -		} else { -		    lseek(*fd,offset,SEEK_SET); -		} -		return i; -	    } -	} -	close(*fd); -	unlink(namebuf2); -	close(new); -	i = efile_openfile(errInfo,namebuf,flags | EFILE_NO_TRUNCATE,fd, -			   &dummy); -	if (i) { -	    lseek(*fd,offset,SEEK_SET); -	} -	return i; -    } -    return 1; -#else  #ifndef NO_FTRUNCATE      off_t offset; @@ -1347,15 +805,11 @@ efile_truncate_file(Efile_error* errInfo, int *fd, int flags)  #else      return 1;  #endif -#endif  }  int  efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size)  { -#ifdef VXWORKS -    return vxworks_enotsup(errInfo); -#else      int len;      ASSERT(size > 0);      len = readlink(name, buffer, size-1); @@ -1364,7 +818,6 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size)      }      buffer[len] = '\0';      return 1; -#endif  }  int @@ -1377,21 +830,13 @@ efile_altname(Efile_error* errInfo, char* name, char* buffer, size_t size)  int  efile_link(Efile_error* errInfo, char* old, char* new)  { -#ifdef VXWORKS -    return vxworks_enotsup(errInfo); -#else      return check_error(link(old, new), errInfo); -#endif  }  int  efile_symlink(Efile_error* errInfo, char* old, char* new)  { -#ifdef VXWORKS -    return vxworks_enotsup(errInfo); -#else      return check_error(symlink(old, new), errInfo); -#endif  }  int @@ -1406,8 +851,8 @@ efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset,  }  #ifdef HAVE_SENDFILE -// For some reason the maximum size_t cannot be used as the max size -// 3GB seems to work on all platforms +/* For some reason the maximum size_t cannot be used as the max size +   3GB seems to work on all platforms */  #define SENDFILE_CHUNK_SIZE ((1UL << 30) -1)  /* @@ -1444,7 +889,7 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,  #if defined(__linux__)      ssize_t retval;      do { -      // check if *nbytes is 0 or greater than chunk size +      /* check if *nbytes is 0 or greater than chunk size */        if (*nbytes == 0 || *nbytes > SENDFILE_CHUNK_SIZE)  	retval = sendfile(out_fd, in_fd, offset, SENDFILE_CHUNK_SIZE);        else @@ -1455,7 +900,7 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,        }      } while (retval == SENDFILE_CHUNK_SIZE);      if (written != 0) { -      // -1 is not returned by the linux API so we have to simulate it +      /* -1 is not returned by the linux API so we have to simulate it */        retval = -1;        errno = EAGAIN;      } @@ -1468,23 +913,29 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,      do {        fdrec.sfv_off = *offset;        len = 0; -      // check if *nbytes is 0 or greater than chunk size +      /* check if *nbytes is 0 or greater than chunk size */        if (*nbytes == 0 || *nbytes > SENDFILE_CHUNK_SIZE)  	fdrec.sfv_len = SENDFILE_CHUNK_SIZE;        else  	fdrec.sfv_len = *nbytes;        retval = sendfilev(out_fd, &fdrec, 1, &len); -      if (retval != -1 || errno == EAGAIN || errno == EINTR) { + +      /* Sometimes sendfilev can return -1 and still send data.  +         When that happens we just pretend that no error happend. */ +      if (retval != -1 || errno == EAGAIN || errno == EINTR || +	  len != 0) {          *offset += len;  	*nbytes -= len;  	written += len; +	if (errno != EAGAIN && errno != EINTR && len != 0) +	  retval = len;        }      } while (len == SENDFILE_CHUNK_SIZE);  #elif defined(DARWIN)      int retval;      off_t len;      do { -      // check if *nbytes is 0 or greater than chunk size +      /* check if *nbytes is 0 or greater than chunk size */        if(*nbytes > SENDFILE_CHUNK_SIZE)  	len = SENDFILE_CHUNK_SIZE;        else diff --git a/erts/emulator/drivers/win32/registry_drv.c b/erts/emulator/drivers/win32/registry_drv.c index 1fad34e380..5b200ebd32 100644 --- a/erts/emulator/drivers/win32/registry_drv.c +++ b/erts/emulator/drivers/win32/registry_drv.c @@ -344,7 +344,7 @@ fix_value_result(RegPort* rp, LONG result, DWORD type,  #ifdef DEBUG  	if (ok != ERROR_SUCCESS) {  	    char buff[256]; -	    sprintf(buff,"Failure in registry_drv line %d, error = %d", +	    erts_snprintf(buff, sizeof(buff), "Failure in registry_drv line %d, error = %d",  		    __LINE__, GetLastError());  	    MessageBox(NULL, buff, "Internal error", MB_OK);  	    ASSERT(ok == ERROR_SUCCESS);  | 
