Ignore:
Timestamp:
Feb 9, 2009, 9:26:35 AM (17 years ago)
Author:
Paul Smedley
Message:

Updates to sys_read and sys_write to address read/write failures with EINTR - addresses tickets 69 and 71

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.0/source/lib/system.c

    r163 r164  
    2929#endif
    3030
    31 #ifdef __OS2__
    32 unsigned long _System DosSleep (unsigned long ulInterval);
    33 // On OS/2 - we randomly get 'Resource Temporarily Unavailable' errors - ignore these
    34 // ticket:69 code may enter an infinite loop, added a 60sec timeout
    35 #define OS2_EAGAIN_RETRY_INIT time_t t1 = time(NULL);
    36 #define OS2_EAGAIN_RETRY_CHECK \
    37         if (ret == -1) {                        \
    38                 DEBUG(10,("sys_read: op failed, errno: %d,%s\n", errno, strerror(errno))); \
    39         }                                       \
    40         if (ret==-1 && errno==EAGAIN) {         \
    41                 DosSleep(100);                  \
    42                 if (time(NULL) - t1 > 60)       \
    43                         break;                  \
    44                 errno = EINTR;                  \
    45         }
    46 #else
    47 #define OS2_EAGAIN_RETRY_INIT
    48 #define OS2_EAGAIN_RETRY_CHECK
    49 #endif
    50 
    5131/*
    5232   The idea is that this file will eventually have wrappers around all
     
    139119A read wrapper that will deal with EINTR.
    140120********************************************************************/
    141 
     121#ifndef __OS2__
    142122ssize_t sys_read(int fd, void *buf, size_t count)
    143123{
    144         OS2_EAGAIN_RETRY_INIT;
    145124        ssize_t ret;
     125
    146126        do {
    147127                ret = read(fd, buf, count);
    148                 OS2_EAGAIN_RETRY_CHECK;
    149128        } while (ret == -1 && errno == EINTR);
    150129        return ret;
    151130}
     131#else
     132ssize_t sys_read(int fd, void *buf, size_t count)
     133{
     134        ssize_t ret;
     135        int fds, err = 0;
     136
     137        int timeout=1000; /* Timeout for select */
     138        do {
     139                if (err == EAGAIN && timeout != 0) {
     140                        fds = fd;
     141                        ret = os2_select(&fds, 1, 0, 0, timeout);
     142                        if (ret != 1) {
     143                                err = errno;
     144                                DEBUG(3,("sys_read: select ret: %d,%s\n", ret, strerror(errno)));
     145                                if (ret == 0) {
     146                                        err = errno = EAGAIN;
     147                                        ret = -1;
     148                                        continue;
     149                                }
     150                                if (err == EINTR)
     151                                        continue;
     152                                return -1;
     153                        }
     154                }
     155                ret = read(fd, buf, count);
     156                err = errno;
     157        } while (ret == -1 && (errno == EINTR  || (errno == EAGAIN && timeout != 0)));
     158        return ret;
     159}
     160#endif
    152161
    153162/*******************************************************************
    154163A write wrapper that will deal with EINTR.
    155164********************************************************************/
    156 
     165 
     166#ifndef __OS2__
    157167ssize_t sys_write(int fd, const void *buf, size_t count)
    158168{
    159169        ssize_t ret;
     170
    160171        do {
    161172                ret = write(fd, buf, count);
    162 #ifndef __OS2__
    163173        } while (ret == -1 && errno == EINTR);
    164 #else
    165 /* On OS/2 - we randomly get 'Resource Temporarily Unavailable' errors - ignore these */
    166         } while (ret == -1 && ((errno == EINTR)||(errno == EAGAIN)));
    167 #endif
    168         if (errno == EAGAIN)
    169174        return ret;
    170175}
     176
     177#else
     178ssize_t sys_write(int fd, const void *buf, size_t count)
     179{
     180        ssize_t ret;
     181        int fds, err = 0;
     182
     183        int timeout=1000; /* Timeout for select */
     184        do {
     185                if (err == EAGAIN && timeout != 0) {
     186                        fds = fd;
     187                        ret = os2_select(&fds, 0, 1, 0, timeout);
     188                        if (ret != 1) {
     189                                err = errno;
     190                                DEBUG(3,("sys_write: select ret: %d,%s\n", ret, strerror(errno)));
     191                                if (ret == 0) {
     192                                        err = errno = EAGAIN;
     193                                        ret = -1;
     194                                        continue;
     195                                }
     196                                if (err == EINTR)
     197                                        continue;
     198                                return -1;
     199                        }
     200                }
     201                ret = write(fd, buf, count);
     202                err = errno;   
     203        } while (ret == -1 && (errno == EINTR || (errno == EAGAIN && timeout != 0)));
     204        return ret;
     205}
     206#endif
    171207
    172208/*******************************************************************
     
    10301066        if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
    10311067                DEBUG(0,("sys_setgroups: Malloc fail.\n"));
    1032                 return -1;   
     1068                return -1;     
    10331069        }
    10341070 
     
    11191155        for (i=0; i<10; i++) {
    11201156                generate_random_buffer((unsigned char *)&uid,
    1121                                        sizeof(uid));
     1157                                           sizeof(uid));
    11221158                if (getpwuid(uid) == NULL) {
    11231159                        break;
     
    11391175
    11401176        ADD_TO_ARRAY(NULL, struct passwd, new_pwd, &fake_pwd,
    1141                     &num_fake_pwd);
     1177                        &num_fake_pwd);
    11421178
    11431179        DEBUG(10, ("Added fake user %s, have %d fake users\n",
     
    15771613{
    15781614#if defined(HAVE_DLSYM)
    1579     return dlsym(handle, symbol);
    1580 #else
    1581     return NULL;
     1615        return dlsym(handle, symbol);
     1616#else
     1617        return NULL;
    15821618#endif
    15831619}
     
    18251861
    18261862static struct {
    1827         int space;
     1863                int space;
    18281864        const char *name;
    18291865        size_t len;
     
    18311867extattr[] = {
    18321868        { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
    1833         { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
     1869                { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
    18341870};
    18351871
     
    19271963
    19281964        while (True) {
    1929             if (filedes)
     1965                if (filedes)
    19301966                retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
    1931             else
     1967                else
    19321968                retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
    1933             if (retval) break;
    1934             for (index = 0; index < al->al_count; index++) {
     1969                if (retval) break;
     1970                for (index = 0; index < al->al_count; index++) {
    19351971                ae = ATTR_ENTRY(attr_buffer, index);
    19361972                ent_size = strlen(ae->a_name) + sizeof("user.");
    19371973                if (left >= ent_size) {
    1938                     strncpy(bp, "user.", sizeof("user."));
    1939                     strncat(bp, ae->a_name, ent_size - sizeof("user."));
    1940                     bp += ent_size;
    1941                     left -= ent_size;
     1974                        strncpy(bp, "user.", sizeof("user."));
     1975                        strncat(bp, ae->a_name, ent_size - sizeof("user."));
     1976                        bp += ent_size;
     1977                        left -= ent_size;
    19421978                } else if (size) {
    1943                     errno = ERANGE;
    1944                     retval = -1;
    1945                     break;
     1979                        errno = ERANGE;
     1980                        retval = -1;
     1981                        break;
    19461982                }
    19471983                total_size += ent_size;
    1948             }
    1949             if (al->al_more == 0) break;
     1984                }
     1985                if (al->al_more == 0) break;
    19501986        }
    19511987        if (retval == 0) {
    1952             flags |= ATTR_ROOT;
    1953             cursor = 0;
    1954             while (True) {
     1988                flags |= ATTR_ROOT;
     1989                cursor = 0;
     1990                while (True) {
    19551991                if (filedes)
    1956                     retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
     1992                        retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
    19571993                else
    1958                     retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
     1994                        retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
    19591995                if (retval) break;
    19601996                for (index = 0; index < al->al_count; index++) {
    1961                     ae = ATTR_ENTRY(attr_buffer, index);
    1962                     ent_size = strlen(ae->a_name) + sizeof("system.");
    1963                     if (left >= ent_size) {
     1997                        ae = ATTR_ENTRY(attr_buffer, index);
     1998                        ent_size = strlen(ae->a_name) + sizeof("system.");
     1999                        if (left >= ent_size) {
    19642000                        strncpy(bp, "system.", sizeof("system."));
    19652001                        strncat(bp, ae->a_name, ent_size - sizeof("system."));
    19662002                        bp += ent_size;
    19672003                        left -= ent_size;
    1968                     } else if (size) {
     2004                        } else if (size) {
    19692005                        errno = ERANGE;
    19702006                        retval = -1;
    19712007                        break;
    1972                     }
    1973                     total_size += ent_size;
     2008                        }
     2009                        total_size += ent_size;
    19742010                }
    19752011                if (al->al_more == 0) break;
    1976             }
     2012                }
    19772013        }
    19782014        return (ssize_t)(retval ? retval : total_size);
     
    22002236
    22012237#if !defined(HAVE_SETXATTR)
    2202 #define XATTR_CREATE  0x1       /* set value, fail if attr already exists */
    2203 #define XATTR_REPLACE 0x2       /* set value, fail if attr does not exist */
     2238#define XATTR_CREATE  0x1          /* set value, fail if attr already exists */
     2239#define XATTR_REPLACE 0x2          /* set value, fail if attr does not exist */
    22042240#endif
    22052241
     
    24392475        int newfd = dup(attrdirfd);
    24402476        /* CAUTION: The originating file descriptor should not be
    2441                     used again following the call to fdopendir().
    2442                     For that reason we dup() the file descriptor
    2443                     here to make things more clear. */
     2477                                used again following the call to fdopendir().
     2478                                For that reason we dup() the file descriptor
     2479                        here to make things more clear. */
    24442480        dirp = fdopendir(newfd);
    24452481
     
    25312567 Return the major devicenumber for UNIX extensions.
    25322568****************************************************************************/
    2533                                                                                                                
     2569                                                                                                                                                                                                                               
    25342570uint32 unix_dev_major(SMB_DEV_T dev)
    25352571{
    25362572#if defined(HAVE_DEVICE_MAJOR_FN)
    2537         return (uint32)major(dev);
    2538 #else
    2539         return (uint32)(dev >> 8);
    2540 #endif
    2541 }
    2542                                                                                                                
     2573                return (uint32)major(dev);
     2574#else
     2575                return (uint32)(dev >> 8);
     2576#endif
     2577}
     2578                                                                                                                                                                                                                               
    25432579/****************************************************************************
    25442580 Return the minor devicenumber for UNIX extensions.
    25452581****************************************************************************/
    2546                                                                                                                
     2582                                                                                                                                                                                                                               
    25472583uint32 unix_dev_minor(SMB_DEV_T dev)
    25482584{
    25492585#if defined(HAVE_DEVICE_MINOR_FN)
    2550         return (uint32)minor(dev);
    2551 #else
    2552         return (uint32)(dev & 0xff);
     2586                return (uint32)minor(dev);
     2587#else
     2588                return (uint32)(dev & 0xff);
    25532589#endif
    25542590}
     
    25592595 An aio_read wrapper that will deal with 64-bit sizes.
    25602596********************************************************************/
    2561                                                                                                                                            
     2597                                                                                                                                                                                                                                                                                   
    25622598int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
    25632599{
    25642600#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
    2565         return aio_read64(aiocb);
     2601                return aio_read64(aiocb);
    25662602#elif defined(HAVE_AIO_READ)
    2567         return aio_read(aiocb);
     2603                return aio_read(aiocb);
    25682604#else
    25692605        errno = ENOSYS;
     
    25752611 An aio_write wrapper that will deal with 64-bit sizes.
    25762612********************************************************************/
    2577                                                                                                                                            
     2613                                                                                                                                                                                                                                                                                   
    25782614int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
    25792615{
    25802616#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
    2581         return aio_write64(aiocb);
     2617                return aio_write64(aiocb);
    25822618#elif defined(HAVE_AIO_WRITE)
    2583         return aio_write(aiocb);
     2619                return aio_write(aiocb);
    25842620#else
    25852621        errno = ENOSYS;
     
    25912627 An aio_return wrapper that will deal with 64-bit sizes.
    25922628********************************************************************/
    2593                                                                                                                                            
     2629                                                                                                                                                                                                                                                                                   
    25942630ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
    25952631{
    25962632#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
    2597         return aio_return64(aiocb);
     2633                return aio_return64(aiocb);
    25982634#elif defined(HAVE_AIO_RETURN)
    2599         return aio_return(aiocb);
     2635                return aio_return(aiocb);
    26002636#else
    26012637        errno = ENOSYS;
     
    26112647{
    26122648#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
    2613         return aio_cancel64(fd, aiocb);
     2649                return aio_cancel64(fd, aiocb);
    26142650#elif defined(HAVE_AIO_CANCEL)
    2615         return aio_cancel(fd, aiocb);
     2651                return aio_cancel(fd, aiocb);
    26162652#else
    26172653        errno = ENOSYS;
     
    26272663{
    26282664#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
    2629         return aio_error64(aiocb);
     2665                return aio_error64(aiocb);
    26302666#elif defined(HAVE_AIO_ERROR)
    2631         return aio_error(aiocb);
     2667                return aio_error(aiocb);
    26322668#else
    26332669        errno = ENOSYS;
     
    26432679{
    26442680#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
    2645         return aio_fsync64(op, aiocb);
     2681                return aio_fsync64(op, aiocb);
    26462682#elif defined(HAVE_AIO_FSYNC)
    2647         return aio_fsync(op, aiocb);
     2683                return aio_fsync(op, aiocb);
    26482684#else
    26492685        errno = ENOSYS;
     
    26592695{
    26602696#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
    2661         return aio_suspend64(cblist, n, timeout);
     2697                return aio_suspend64(cblist, n, timeout);
    26622698#elif defined(HAVE_AIO_FSYNC)
    2663         return aio_suspend(cblist, n, timeout);
     2699                return aio_suspend(cblist, n, timeout);
    26642700#else
    26652701        errno = ENOSYS;
Note: See TracChangeset for help on using the changeset viewer.