UnixFileDescriptorHandle.st
changeset 15990 358873f8b450
parent 14667 f6a830b971f3
child 15995 c832f7a2b036
equal deleted inserted replaced
15989:824d113634fc 15990:358873f8b450
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
       
    13 "{ Package: 'stx:libbasic' }"
    12 "{ Package: 'stx:libbasic' }"
    14 
    13 
    15 OSFileHandle subclass:#UnixFileDescriptorHandle
    14 OSFileHandle subclass:#UnixFileDescriptorHandle
    16 	instanceVariableNames:''
    15 	instanceVariableNames:''
    17 	classVariableNames:''
    16 	classVariableNames:''
    55     INT fd = (INT)(__externalAddressVal(self));
    54     INT fd = (INT)(__externalAddressVal(self));
    56     INT cnt, offs;
    55     INT cnt, offs;
    57     int nInstBytes, objSize;
    56     int nInstBytes, objSize;
    58 
    57 
    59     if (! __bothSmallInteger(count, firstIndex)) {
    58     if (! __bothSmallInteger(count, firstIndex)) {
    60 	goto bad;
    59         goto bad;
    61     }
    60     }
    62     cnt = __smallIntegerVal(count);
    61     cnt = __smallIntegerVal(count);
    63     offs = __smallIntegerVal(firstIndex) - 1;
    62     offs = __smallIntegerVal(firstIndex) - 1;
    64 
    63 
    65     if (fd < 0) {
    64     if (fd < 0) {
    66 	goto bad;
    65         goto bad;
    67     }
    66     }
    68     if (__isExternalBytesLike(aByteBuffer)) {
    67     if (__isExternalBytesLike(aByteBuffer)) {
    69 	OBJ sz;
    68         OBJ sz;
    70 
    69 
    71 	nInstBytes = 0;
    70         nInstBytes = 0;
    72 	extPtr = (char *)(__externalBytesAddress(aByteBuffer));
    71         extPtr = (char *)(__externalBytesAddress(aByteBuffer));
    73 	if (extPtr == NULL) goto bad;
    72         if (extPtr == NULL) goto bad;
    74 	sz = __externalBytesSize(aByteBuffer);
    73         sz = __externalBytesSize(aByteBuffer);
    75 	if (__isSmallInteger(sz)) {
    74         if (__isSmallInteger(sz)) {
    76 	    objSize = __smallIntegerVal(sz);
    75             objSize = __smallIntegerVal(sz);
    77 	} else {
    76         } else {
    78 	    objSize = -1; /* unknown */
    77             objSize = -1; /* unknown */
    79 	}
    78         }
    80     } else {
    79     } else {
    81 	OBJ oClass;
    80         OBJ oClass = __Class(aByteBuffer);
    82 	int nInstVars;
    81         int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
    83 
    82 
    84 	oClass = __Class(aByteBuffer);
    83         nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
    85 	switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
    84         switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
    86 	    case BYTEARRAY:
    85             case BYTEARRAY:
    87 	    case WORDARRAY:
    86             case WORDARRAY:
    88 	    case LONGARRAY:
    87             case LONGARRAY:
    89 	    case SWORDARRAY:
    88             case SWORDARRAY:
    90 	    case SLONGARRAY:
    89             case SLONGARRAY:
    91 	    case FLOATARRAY:
    90             case FLOATARRAY:
    92 	    case DOUBLEARRAY:
    91             case DOUBLEARRAY:
    93 		break;
    92 #ifdef __NEED_DOUBLE_ALIGN
    94 	    default:
    93                 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
    95 		goto bad;
    94 #endif
    96 	}
    95                 break;
    97 	extPtr = (char *)0;
    96             case LONGLONGARRAY:
    98 	nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
    97             case SLONGLONGARRAY:
    99 	nInstBytes = __OBJS2BYTES__(nInstVars);
    98 #ifdef __NEED_LONGLONG_ALIGN
   100 	objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
    99                 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
       
   100 #endif
       
   101             default:
       
   102                 goto bad;
       
   103         }
       
   104         extPtr = (char *)0;
       
   105         objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
   101     }
   106     }
   102     if ((offs >= 0)
   107     if ((offs >= 0)
   103      && (cnt >= 0)
   108      && (cnt >= 0)
   104      && ((objSize == -1) || (objSize >= (cnt + offs)))) {
   109      && ((objSize == -1) || (objSize >= (cnt + offs)))) {
   105 	nRead = 0;
   110         nRead = 0;
   106 
   111 
   107 	do {
   112         do {
   108 	    int n;
   113             int n;
   109 
   114 
   110 	    if (extPtr) {
   115             if (extPtr) {
   111 		n = read(fd, extPtr+offs, cnt);
   116                 n = read(fd, extPtr+offs, cnt);
   112 	    } else {
   117             } else {
   113 		char *bp;
   118                 char *bp;
   114 
   119 
   115 		/*
   120                 /*
   116 		 * on interrupt, anObject may be moved to another location.
   121                  * on interrupt, anObject may be moved to another location.
   117 		 * So we recompute the byte-address here.
   122                  * So we recompute the byte-address here.
   118 		 */
   123                  */
   119 		bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
   124                 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
   120 
   125 
   121 		n = read(fd, bp + offs, cnt);
   126                 n = read(fd, bp + offs, cnt);
   122 	    }
   127             }
   123 	    if (n > 0) {
   128             if (n > 0) {
   124 		cnt -= n;
   129                 cnt -= n;
   125 		offs += n;
   130                 offs += n;
   126 		nRead += n;
   131                 nRead += n;
   127 	    } else {
   132             } else {
   128 		if (n < 0) {
   133                 if (n < 0) {
   129 		    if (errno == EINTR) {
   134                     if (errno == EINTR) {
   130 			continue;
   135                         continue;
   131 		    }
   136                     }
   132 		    break;
   137                     break;
   133 		}
   138                 }
   134 	    }
   139             }
   135 	} while (cnt > 0);
   140         } while (cnt > 0);
   136 
   141 
   137 	RETURN (__mkSmallInteger(nRead));
   142         RETURN (__mkSmallInteger(nRead));
   138     }
   143     }
   139 bad: ;
   144 bad: ;
   140 %}.
   145 %}.
   141     ^ self primitiveFailed
   146     ^ self primitiveFailed
   142 
   147 
   161     INT fd = (INT)(__externalAddressVal(self));
   166     INT fd = (INT)(__externalAddressVal(self));
   162     INT cnt, offs;
   167     INT cnt, offs;
   163     int nInstBytes, objSize;
   168     int nInstBytes, objSize;
   164 
   169 
   165     if (! __bothSmallInteger(count, firstIndex)) {
   170     if (! __bothSmallInteger(count, firstIndex)) {
   166 	goto bad;
   171         goto bad;
   167     }
   172     }
   168     cnt = __smallIntegerVal(count);
   173     cnt = __smallIntegerVal(count);
   169     offs = __smallIntegerVal(firstIndex) - 1;
   174     offs = __smallIntegerVal(firstIndex) - 1;
   170 
   175 
   171     if (fd < 0) {
   176     if (fd < 0) {
   172 	goto bad;
   177         goto bad;
   173     }
   178     }
   174     if (__isExternalBytesLike(aByteBuffer)) {
   179     if (__isExternalBytesLike(aByteBuffer)) {
   175 	OBJ sz;
   180         OBJ sz;
   176 
   181 
   177 	nInstBytes = 0;
   182         nInstBytes = 0;
   178 	extPtr = (char *)(__externalBytesAddress(aByteBuffer));
   183         extPtr = (char *)(__externalBytesAddress(aByteBuffer));
   179 	if (extPtr == NULL) goto bad;
   184         if (extPtr == NULL) goto bad;
   180 	sz = __externalBytesSize(aByteBuffer);
   185         sz = __externalBytesSize(aByteBuffer);
   181 	if (__isSmallInteger(sz)) {
   186         if (__isSmallInteger(sz)) {
   182 	    objSize = __smallIntegerVal(sz);
   187             objSize = __smallIntegerVal(sz);
   183 	} else {
   188         } else {
   184 	    objSize = -1; /* unknown */
   189             objSize = -1; /* unknown */
   185 	}
   190         }
   186     } else {
   191     } else {
   187 	OBJ oClass;
   192         OBJ oClass = __Class(aByteBuffer);
   188 	int nInstVars;
   193         int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
   189 
   194 
   190 	oClass = __Class(aByteBuffer);
   195         nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
   191 	switch (__smallIntegerVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
   196         switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
   192 	    case BYTEARRAY:
   197             case BYTEARRAY:
   193 	    case WORDARRAY:
   198             case WORDARRAY:
   194 	    case LONGARRAY:
   199             case LONGARRAY:
   195 	    case SWORDARRAY:
   200             case SWORDARRAY:
   196 	    case SLONGARRAY:
   201             case SLONGARRAY:
   197 	    case FLOATARRAY:
   202             case FLOATARRAY:
   198 	    case DOUBLEARRAY:
   203             case DOUBLEARRAY:
   199 		break;
   204 #ifdef __NEED_DOUBLE_ALIGN
   200 	    default:
   205                 nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
   201 		goto bad;
   206 #endif
   202 	}
   207                 break;
   203 	extPtr = (char *)0;
   208             case LONGLONGARRAY:
   204 	nInstVars = __smallIntegerVal(__ClassInstPtr(oClass)->c_ninstvars);
   209             case SLONGLONGARRAY:
   205 	nInstBytes = __OBJS2BYTES__(nInstVars);
   210 #ifdef __NEED_LONGLONG_ALIGN
   206 	objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
   211                 nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
       
   212 #endif
       
   213             default:
       
   214                 goto bad;
       
   215         }
       
   216         extPtr = (char *)0;
       
   217         objSize = __Size(aByteBuffer) - OHDR_SIZE - nInstBytes;
   207     }
   218     }
   208     if ((offs >= 0)
   219     if ((offs >= 0)
   209      && (cnt >= 0)
   220      && (cnt >= 0)
   210      && ((objSize == -1) || (objSize >= (cnt + offs)))) {
   221      && ((objSize == -1) || (objSize >= (cnt + offs)))) {
   211 	nWritten = 0;
   222         nWritten = 0;
   212 
   223 
   213 	do {
   224         do {
   214 	    int n;
   225             int n;
   215 
   226 
   216 	    if (extPtr) {
   227             if (extPtr) {
   217 		n = write(fd, extPtr+offs, cnt);
   228                 n = write(fd, extPtr+offs, cnt);
   218 	    } else {
   229             } else {
   219 		char *bp;
   230                 char *bp;
   220 
   231 
   221 		/*
   232                 /*
   222 		 * on interrupt, anObject may be moved to another location.
   233                  * on interrupt, anObject may be moved to another location.
   223 		 * So we recompute the byte-address here.
   234                  * So we recompute the byte-address here.
   224 		 */
   235                  */
   225 		bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
   236                 bp = __ByteArrayInstPtr(aByteBuffer)->ba_element + nInstBytes;
   226 
   237 
   227 		n = write(fd, bp + offs, cnt);
   238                 n = write(fd, bp + offs, cnt);
   228 	    }
   239             }
   229 	    if (n > 0) {
   240             if (n > 0) {
   230 		cnt -= n;
   241                 cnt -= n;
   231 		offs += n;
   242                 offs += n;
   232 		nWritten += n;
   243                 nWritten += n;
   233 	    } else {
   244             } else {
   234 		if (n < 0) {
   245                 if (n < 0) {
   235 		    if (errno == EINTR) {
   246                     if (errno == EINTR) {
   236 			continue;
   247                         continue;
   237 		    }
   248                     }
   238 		    break;
   249                     break;
   239 		}
   250                 }
   240 	    }
   251             }
   241 	} while (cnt > 0);
   252         } while (cnt > 0);
   242 
   253 
   243 	RETURN (__mkSmallInteger(nWritten));
   254         RETURN (__mkSmallInteger(nWritten));
   244     }
   255     }
   245 bad: ;
   256 bad: ;
   246 %}.
   257 %}.
   247     ^ self primitiveFailed
   258     ^ self primitiveFailed
   248 
   259 
   286 ! !
   297 ! !
   287 
   298 
   288 !UnixFileDescriptorHandle class methodsFor:'documentation'!
   299 !UnixFileDescriptorHandle class methodsFor:'documentation'!
   289 
   300 
   290 version
   301 version
   291     ^ '$Header: /cvs/stx/stx/libbasic/UnixFileDescriptorHandle.st,v 1.9 2013-01-17 22:37:55 cg Exp $'
   302     ^ '$Header: /cvs/stx/stx/libbasic/UnixFileDescriptorHandle.st,v 1.10 2014-02-12 12:55:06 stefan Exp $'
   292 ! !
   303 ! !
       
   304