1260 %{ |
1260 %{ |
1261 HFILE f = NULL; |
1261 HFILE f = NULL; |
1262 int pass = 0; |
1262 int pass = 0; |
1263 |
1263 |
1264 if (!__isNonNilObject(encodedPathName) |
1264 if (!__isNonNilObject(encodedPathName) |
1265 || !(__isStringLike(openmode) || __isArrayLike(openmode))) |
1265 || !(__isStringLike(openmode) || __isArrayLike(openmode))) |
1266 goto badArgument; |
1266 goto badArgument; |
1267 |
1267 |
1268 retry: |
1268 retry: |
1269 #ifdef __VMS__ |
1269 #ifdef __VMS__ |
1270 if (__isStringLike(encodedPathName)) { |
1270 if (__isStringLike(encodedPathName)) { |
1271 do { |
1271 do { |
1272 /* |
1272 /* |
1273 * allow passing additional RMS arguments. |
1273 * allow passing additional RMS arguments. |
1274 * stupid: DEC does not seem to offer an interface for passing a char **. |
1274 * stupid: DEC does not seem to offer an interface for passing a char **. |
1275 */ |
1275 */ |
1276 __threadErrno = 0; |
1276 __threadErrno = 0; |
1277 |
1277 |
1278 { |
1278 { |
1279 if (__isArray(attributeSpec)) { |
1279 if (__isArray(attributeSpec)) { |
1280 OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; |
1280 OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; |
1281 int numAttrib = 0; |
1281 int numAttrib = 0; |
1282 int i; |
1282 int i; |
1283 |
1283 |
1284 numAttrib = __arraySize(attributeSpec); |
1284 numAttrib = __arraySize(attributeSpec); |
1285 for (i=0; i<numAttrib;i++) { |
1285 for (i=0; i<numAttrib;i++) { |
1286 if (! __isStringLike(ap[i])) { |
1286 if (! __isStringLike(ap[i])) { |
1287 __threadErrno = EINVAL; /* invalid argument */ |
1287 __threadErrno = EINVAL; /* invalid argument */ |
1288 goto getOutOfHere; |
1288 goto getOutOfHere; |
1289 } |
1289 } |
1290 } |
1290 } |
1291 switch (numAttrib) { |
1291 switch (numAttrib) { |
1292 case 0: |
1292 case 0: |
1293 __BEGIN_INTERRUPTABLE__ |
1293 __BEGIN_INTERRUPTABLE__ |
1294 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode)); |
1294 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode)); |
1295 __END_INTERRUPTABLE__ |
1295 __END_INTERRUPTABLE__ |
1296 break; |
1296 break; |
1297 case 1: |
1297 case 1: |
1298 __BEGIN_INTERRUPTABLE__ |
1298 __BEGIN_INTERRUPTABLE__ |
1299 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1299 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1300 __stringVal(ap[0])); |
1300 __stringVal(ap[0])); |
1301 __END_INTERRUPTABLE__ |
1301 __END_INTERRUPTABLE__ |
1302 break; |
1302 break; |
1303 case 2: |
1303 case 2: |
1304 __BEGIN_INTERRUPTABLE__ |
1304 __BEGIN_INTERRUPTABLE__ |
1305 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1305 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1306 __stringVal(ap[0]), __stringVal(ap[1])); |
1306 __stringVal(ap[0]), __stringVal(ap[1])); |
1307 __END_INTERRUPTABLE__ |
1307 __END_INTERRUPTABLE__ |
1308 break; |
1308 break; |
1309 case 3: |
1309 case 3: |
1310 __BEGIN_INTERRUPTABLE__ |
1310 __BEGIN_INTERRUPTABLE__ |
1311 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1311 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1312 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2])); |
1312 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2])); |
1313 __END_INTERRUPTABLE__ |
1313 __END_INTERRUPTABLE__ |
1314 break; |
1314 break; |
1315 case 4: |
1315 case 4: |
1316 __BEGIN_INTERRUPTABLE__ |
1316 __BEGIN_INTERRUPTABLE__ |
1317 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1317 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1318 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1318 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1319 __stringVal(ap[3])); |
1319 __stringVal(ap[3])); |
1320 __END_INTERRUPTABLE__ |
1320 __END_INTERRUPTABLE__ |
1321 break; |
1321 break; |
1322 case 5: |
1322 case 5: |
1323 __BEGIN_INTERRUPTABLE__ |
1323 __BEGIN_INTERRUPTABLE__ |
1324 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1324 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1325 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1325 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1326 __stringVal(ap[3]), __stringVal(ap[4])); |
1326 __stringVal(ap[3]), __stringVal(ap[4])); |
1327 __END_INTERRUPTABLE__ |
1327 __END_INTERRUPTABLE__ |
1328 break; |
1328 break; |
1329 case 6: |
1329 case 6: |
1330 __BEGIN_INTERRUPTABLE__ |
1330 __BEGIN_INTERRUPTABLE__ |
1331 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1331 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1332 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1332 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1333 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5])); |
1333 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5])); |
1334 __END_INTERRUPTABLE__ |
1334 __END_INTERRUPTABLE__ |
1335 break; |
1335 break; |
1336 case 7: |
1336 case 7: |
1337 __BEGIN_INTERRUPTABLE__ |
1337 __BEGIN_INTERRUPTABLE__ |
1338 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1338 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1339 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1339 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1340 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1340 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1341 __stringVal(ap[6])); |
1341 __stringVal(ap[6])); |
1342 __END_INTERRUPTABLE__ |
1342 __END_INTERRUPTABLE__ |
1343 break; |
1343 break; |
1344 case 8: |
1344 case 8: |
1345 __BEGIN_INTERRUPTABLE__ |
1345 __BEGIN_INTERRUPTABLE__ |
1346 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1346 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1347 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1347 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1348 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1348 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1349 __stringVal(ap[6]), __stringVal(ap[7])); |
1349 __stringVal(ap[6]), __stringVal(ap[7])); |
1350 __END_INTERRUPTABLE__ |
1350 __END_INTERRUPTABLE__ |
1351 break; |
1351 break; |
1352 case 9: |
1352 case 9: |
1353 __BEGIN_INTERRUPTABLE__ |
1353 __BEGIN_INTERRUPTABLE__ |
1354 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1354 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1355 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1355 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1356 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1356 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1357 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8])); |
1357 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8])); |
1358 __END_INTERRUPTABLE__ |
1358 __END_INTERRUPTABLE__ |
1359 break; |
1359 break; |
1360 case 10: |
1360 case 10: |
1361 __BEGIN_INTERRUPTABLE__ |
1361 __BEGIN_INTERRUPTABLE__ |
1362 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1362 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1363 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1363 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1364 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1364 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1365 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]), |
1365 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]), |
1366 __stringVal(ap[9])); |
1366 __stringVal(ap[9])); |
1367 __END_INTERRUPTABLE__ |
1367 __END_INTERRUPTABLE__ |
1368 break; |
1368 break; |
1369 default: |
1369 default: |
1370 __threadErrno = E2BIG; /* too many args */ |
1370 __threadErrno = E2BIG; /* too many args */ |
1371 goto getOutOfHere; |
1371 goto getOutOfHere; |
1372 } |
1372 } |
1373 } else if (attributeSpec != nil) { |
1373 } else if (attributeSpec != nil) { |
1374 __threadErrno = EINVAL; /* invalid argument */ |
1374 __threadErrno = EINVAL; /* invalid argument */ |
1375 goto getOutOfHere; |
1375 goto getOutOfHere; |
1376 } else { |
1376 } else { |
1377 /* |
1377 /* |
1378 * create file as sequential streamLF by default. |
1378 * create file as sequential streamLF by default. |
1379 */ |
1379 */ |
1380 __BEGIN_INTERRUPTABLE__ |
1380 __BEGIN_INTERRUPTABLE__ |
1381 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf"); |
1381 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf"); |
1382 __END_INTERRUPTABLE__ |
1382 __END_INTERRUPTABLE__ |
1383 } |
1383 } |
1384 } |
1384 } |
1385 } while ((f == NULL) && (__threadErrno == EINTR)); |
1385 } while ((f == NULL) && (__threadErrno == EINTR)); |
1386 } |
1386 } |
1387 #else /* not VMS */ |
1387 #else /* not VMS */ |
1388 |
1388 |
1389 # ifdef WIN32 |
1389 # ifdef WIN32 |
1390 { |
1390 { |
1391 DWORD share = 0, access = 0, create = 0, attr = 0; |
1391 DWORD share = 0, access = 0, create = 0, attr = 0; |
1392 char * __openmode; |
1392 char * __openmode; |
1393 HANDLE handle; |
1393 HANDLE handle; |
1394 SECURITY_ATTRIBUTES sa; |
1394 SECURITY_ATTRIBUTES sa; |
1395 |
1395 |
1396 if (__isStringLike(openmode)) { |
1396 if (__isStringLike(openmode)) { |
1397 share = FILE_SHARE_READ|FILE_SHARE_WRITE; |
1397 share = FILE_SHARE_READ|FILE_SHARE_WRITE; |
1398 __openmode = __stringVal(openmode); |
1398 __openmode = __stringVal(openmode); |
1399 if (strcmp(__openmode, "rb") == 0) { |
1399 if (strcmp(__openmode, "rb") == 0) { |
1400 access = GENERIC_READ; |
1400 access = GENERIC_READ; |
1401 create = OPEN_EXISTING; |
1401 create = OPEN_EXISTING; |
1402 } else if (strcmp(__openmode, "rb+") == 0) { |
1402 } else if (strcmp(__openmode, "rb+") == 0) { |
1403 access = GENERIC_READ | GENERIC_WRITE; |
1403 access = GENERIC_READ | GENERIC_WRITE; |
1404 create = OPEN_EXISTING; |
1404 create = OPEN_EXISTING; |
1405 } else if (strcmp(__openmode, "wb") == 0) { |
1405 } else if (strcmp(__openmode, "wb") == 0) { |
1406 access = GENERIC_WRITE; |
1406 access = GENERIC_WRITE; |
1407 create = CREATE_ALWAYS; |
1407 create = CREATE_ALWAYS; |
1408 } else if (strcmp(__openmode, "wb+") == 0) { |
1408 } else if (strcmp(__openmode, "wb+") == 0) { |
1409 access = GENERIC_READ | GENERIC_WRITE; |
1409 access = GENERIC_READ | GENERIC_WRITE; |
1410 create = CREATE_ALWAYS; |
1410 create = CREATE_ALWAYS; |
1411 } else if (strcmp(__openmode, "ab") == 0) { |
1411 } else if (strcmp(__openmode, "ab") == 0) { |
1412 access = FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1412 access = FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1413 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1413 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1414 create = OPEN_ALWAYS; |
1414 create = OPEN_ALWAYS; |
1415 } else if (strcmp(__openmode, "ab+") == 0) { |
1415 } else if (strcmp(__openmode, "ab+") == 0) { |
1416 access = GENERIC_READ |FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1416 access = GENERIC_READ |FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1417 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1417 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1418 create = OPEN_ALWAYS; |
1418 create = OPEN_ALWAYS; |
1419 } else { |
1419 } else { |
1420 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1420 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1421 } |
1421 } |
1422 } else if (__isArrayLike(openmode)) { |
1422 } else if (__isArrayLike(openmode)) { |
1423 OBJ *ap = __arrayVal(openmode); |
1423 OBJ *ap = __arrayVal(openmode); |
1424 int numAttrib = __arraySize(openmode); |
1424 int numAttrib = __arraySize(openmode); |
1425 int i; |
1425 int i; |
1426 |
1426 |
1427 __openmode = "rb+"; |
1427 __openmode = "rb+"; |
1428 |
1428 |
1429 for (i=0; i<numAttrib; i++) { |
1429 for (i=0; i<numAttrib; i++) { |
1430 OBJ attrSym = ap[i]; |
1430 OBJ attrSym = ap[i]; |
1431 |
1431 |
1432 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1432 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1433 share |= FILE_SHARE_READ; |
1433 share |= FILE_SHARE_READ; |
1434 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1434 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1435 share |= FILE_SHARE_WRITE; |
1435 share |= FILE_SHARE_WRITE; |
1436 |
1436 |
1437 } else if (attrSym == @symbol(GENERIC_READ)) { |
1437 } else if (attrSym == @symbol(GENERIC_READ)) { |
1438 access |= GENERIC_READ; |
1438 access |= GENERIC_READ; |
1439 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1439 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1440 access |= GENERIC_WRITE; |
1440 access |= GENERIC_WRITE; |
1441 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1441 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1442 access |= GENERIC_READ|GENERIC_WRITE; |
1442 access |= GENERIC_READ|GENERIC_WRITE; |
1443 |
1443 |
1444 } else if (attrSym == @symbol(CREATE_NEW)) { |
1444 } else if (attrSym == @symbol(CREATE_NEW)) { |
1445 create |= CREATE_NEW; |
1445 create |= CREATE_NEW; |
1446 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1446 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1447 create |= CREATE_ALWAYS; |
1447 create |= CREATE_ALWAYS; |
1448 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1448 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1449 create |= OPEN_EXISTING; |
1449 create |= OPEN_EXISTING; |
1450 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1450 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1451 create |= OPEN_ALWAYS; |
1451 create |= OPEN_ALWAYS; |
1452 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1452 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1453 create |= TRUNCATE_EXISTING; |
1453 create |= TRUNCATE_EXISTING; |
1454 |
1454 |
1455 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1455 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1456 attr |= FILE_ATTRIBUTE_HIDDEN; |
1456 attr |= FILE_ATTRIBUTE_HIDDEN; |
1457 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1457 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1458 attr |= FILE_ATTRIBUTE_READONLY; |
1458 attr |= FILE_ATTRIBUTE_READONLY; |
1459 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1459 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1460 attr |= FILE_FLAG_WRITE_THROUGH; |
1460 attr |= FILE_FLAG_WRITE_THROUGH; |
1461 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1461 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1462 attr |= FILE_FLAG_SEQUENTIAL_SCAN; |
1462 attr |= FILE_FLAG_SEQUENTIAL_SCAN; |
1463 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1463 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1464 attr |= FILE_FLAG_DELETE_ON_CLOSE; |
1464 attr |= FILE_FLAG_DELETE_ON_CLOSE; |
1465 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1465 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1466 __openmode = __stringVal(attrSym); |
1466 __openmode = __stringVal(attrSym); |
1467 } else { |
1467 } else { |
1468 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1468 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1469 } |
1469 } |
1470 } |
1470 } |
1471 } |
1471 } |
1472 if (create == 0) { |
1472 if (create == 0) { |
1473 // argumentError = @symbol(missingCreateMode); |
1473 // argumentError = @symbol(missingCreateMode); |
1474 goto badArgument; |
1474 goto badArgument; |
1475 } |
1475 } |
1476 if (attr == 0) { |
1476 if (attr == 0) { |
1477 attr = FILE_ATTRIBUTE_NORMAL; |
1477 attr = FILE_ATTRIBUTE_NORMAL; |
1478 } |
1478 } |
1479 |
1479 |
1480 /* |
1480 /* |
1481 * create security attributes - make handle inheritable by subprocesses |
1481 * create security attributes - make handle inheritable by subprocesses |
1482 */ |
1482 */ |
1483 memset(&sa, 0, sizeof (sa)); |
1483 memset(&sa, 0, sizeof (sa)); |
1484 sa.nLength = sizeof( sa ); |
1484 sa.nLength = sizeof( sa ); |
1485 sa.bInheritHandle = TRUE; |
1485 // sa.bInheritHandle = TRUE; |
1486 |
1486 sa.bInheritHandle = FALSE; |
1487 if (__isStringLike(pathName)) { |
1487 |
1488 char _aPathName[MAXPATHLEN]; |
1488 if (__isStringLike(pathName)) { |
1489 |
1489 char _aPathName[MAXPATHLEN]; |
1490 strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
1490 |
1491 do { |
1491 strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
1492 __threadErrno = 0; |
1492 do { |
1493 handle = STX_API_NOINT_CALL7( "CreateFileA", CreateFileA, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1493 __threadErrno = 0; |
1494 if (__threadErrno == EINTR) { |
1494 handle = STX_API_NOINT_CALL7( "CreateFileA", CreateFileA, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1495 handle = INVALID_HANDLE_VALUE; |
1495 if (__threadErrno == EINTR) { |
1496 } |
1496 handle = INVALID_HANDLE_VALUE; |
1497 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1497 } |
1498 } else if (__isUnicode16String(pathName)) { |
1498 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1499 wchar_t _aPathName[MAXPATHLEN+1]; |
1499 } else if (__isUnicode16String(pathName)) { |
1500 int i, l; |
1500 wchar_t _aPathName[MAXPATHLEN+1]; |
1501 |
1501 int i, l; |
1502 l = __unicode16StringSize(pathName); |
1502 |
1503 if (l > MAXPATHLEN) l = MAXPATHLEN; |
1503 l = __unicode16StringSize(pathName); |
1504 for (i=0; i<l; i++) { |
1504 if (l > MAXPATHLEN) l = MAXPATHLEN; |
1505 _aPathName[i] = __unicode16StringVal(pathName)[i]; |
1505 for (i=0; i<l; i++) { |
1506 } |
1506 _aPathName[i] = __unicode16StringVal(pathName)[i]; |
1507 _aPathName[i] = 0; |
1507 } |
1508 |
1508 _aPathName[i] = 0; |
1509 do { |
1509 |
1510 __threadErrno = 0; |
1510 do { |
1511 handle = STX_API_NOINT_CALL7( "CreateFileW", CreateFileW, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1511 __threadErrno = 0; |
1512 if (__threadErrno == EINTR) { |
1512 handle = STX_API_NOINT_CALL7( "CreateFileW", CreateFileW, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1513 handle = INVALID_HANDLE_VALUE; |
1513 if (__threadErrno == EINTR) { |
1514 } |
1514 handle = INVALID_HANDLE_VALUE; |
1515 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1515 } |
1516 } |
1516 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1517 if (handle != INVALID_HANDLE_VALUE) { |
1517 } |
1518 int fd; |
1518 if (handle != INVALID_HANDLE_VALUE) { |
1519 extern void __stxWrapApiEnterCritical(), __stxWrapApiLeaveCritical(); |
1519 int fd; |
1520 |
1520 extern void __stxWrapApiEnterCritical(), __stxWrapApiLeaveCritical(); |
1521 __stxWrapApiEnterCritical(); |
1521 |
1522 fd = _open_osfhandle((long)handle, O_BINARY); |
1522 __stxWrapApiEnterCritical(); |
1523 if (fd < 0) { |
1523 fd = _open_osfhandle((long)handle, O_BINARY); |
1524 if (__threadErrno == 0) { |
1524 if (fd < 0) { |
1525 // no more file descriptors |
1525 if (__threadErrno == 0) { |
1526 __threadErrno = EMFILE; |
1526 // no more file descriptors |
1527 } |
1527 __threadErrno = EMFILE; |
1528 CloseHandle(handle); |
1528 } |
1529 } else { |
1529 CloseHandle(handle); |
1530 f = fdopen(fd, __openmode); |
1530 } else { |
1531 } |
1531 f = fdopen(fd, __openmode); |
1532 __stxWrapApiLeaveCritical(); |
1532 } |
1533 } else { |
1533 __stxWrapApiLeaveCritical(); |
1534 __threadErrno = __WIN32_ERR(GetLastError()); |
1534 } else { |
1535 } |
1535 __threadErrno = __WIN32_ERR(GetLastError()); |
|
1536 } |
1536 } |
1537 } |
1537 # else /* not WIN32 */ |
1538 # else /* not WIN32 */ |
1538 |
1539 |
1539 if (__isStringLike(encodedPathName)) { |
1540 if (__isStringLike(encodedPathName)) { |
1540 int accessMode = 0666; // default access mode of fopen(), relies on umask() |
1541 int accessMode = 0666; // default access mode of fopen(), relies on umask() |
1541 int flags = 0; |
1542 int flags = 0; |
1542 int fd; |
1543 int fd; |
1543 char * __openmode; |
1544 char * __openmode; |
1544 |
1545 |
1545 if (__isStringLike(openmode)) { |
1546 if (__isStringLike(openmode)) { |
1546 __openmode = __stringVal(openmode); |
1547 __openmode = __stringVal(openmode); |
1547 if (strcmp(__openmode, "r") == 0) { |
1548 if (strcmp(__openmode, "r") == 0) { |
1548 flags = O_RDONLY; |
1549 flags = O_RDONLY; |
1549 } else if (strcmp(__openmode, "r+") == 0) { |
1550 } else if (strcmp(__openmode, "r+") == 0) { |
1550 flags = O_RDWR; |
1551 flags = O_RDWR; |
1551 } else if (strcmp(__openmode, "w") == 0) { |
1552 } else if (strcmp(__openmode, "w") == 0) { |
1552 flags = O_WRONLY | O_CREAT | O_TRUNC; |
1553 flags = O_WRONLY | O_CREAT | O_TRUNC; |
1553 } else if (strcmp(__openmode, "w+") == 0) { |
1554 } else if (strcmp(__openmode, "w+") == 0) { |
1554 flags = O_RDWR | O_CREAT | O_TRUNC; |
1555 flags = O_RDWR | O_CREAT | O_TRUNC; |
1555 } else if (strcmp(__openmode, "a") == 0) { |
1556 } else if (strcmp(__openmode, "a") == 0) { |
1556 flags = O_WRONLY | O_CREAT | O_APPEND; |
1557 flags = O_WRONLY | O_CREAT | O_APPEND; |
1557 } else if (strcmp(__openmode, "a+") == 0) { |
1558 } else if (strcmp(__openmode, "a+") == 0) { |
1558 flags = O_RDWR | O_CREAT| O_APPEND; |
1559 flags = O_RDWR | O_CREAT| O_APPEND; |
1559 } else { |
1560 } else { |
1560 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1561 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1561 } |
1562 } |
1562 } else if (__isArrayLike(openmode)) { |
1563 } else if (__isArrayLike(openmode)) { |
1563 OBJ *ap = __arrayVal(openmode); |
1564 OBJ *ap = __arrayVal(openmode); |
1564 int numAttrib = __arraySize(openmode); |
1565 int numAttrib = __arraySize(openmode); |
1565 int i; |
1566 int i; |
1566 |
1567 |
1567 __openmode = "r+"; |
1568 __openmode = "r+"; |
1568 |
1569 |
1569 for (i=0; i<numAttrib; i++) { |
1570 for (i=0; i<numAttrib; i++) { |
1570 OBJ attrSym = ap[i]; |
1571 OBJ attrSym = ap[i]; |
1571 |
1572 |
1572 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1573 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1573 // ignore |
1574 // ignore |
1574 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1575 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1575 // ignore |
1576 // ignore |
1576 } else if (attrSym == @symbol(GENERIC_READ)) { |
1577 } else if (attrSym == @symbol(GENERIC_READ)) { |
1577 flags |= O_RDONLY; |
1578 flags |= O_RDONLY; |
1578 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1579 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1579 flags |= O_WRONLY; |
1580 flags |= O_WRONLY; |
1580 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1581 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1581 flags |= O_RDWR; |
1582 flags |= O_RDWR; |
1582 |
1583 |
1583 } else if (attrSym == @symbol(CREATE_NEW)) { |
1584 } else if (attrSym == @symbol(CREATE_NEW)) { |
1584 flags |= O_CREAT|O_EXCL; |
1585 flags |= O_CREAT|O_EXCL; |
1585 accessMode = 0600; // simulate mkstemp() |
1586 accessMode = 0600; // simulate mkstemp() |
1586 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1587 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1587 flags |= O_CREAT|O_TRUNC; |
1588 flags |= O_CREAT|O_TRUNC; |
1588 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1589 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1589 // nothing to be set |
1590 // nothing to be set |
1590 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1591 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1591 flags |= O_CREAT; |
1592 flags |= O_CREAT; |
1592 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1593 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1593 flags |= O_TRUNC; |
1594 flags |= O_TRUNC; |
1594 |
1595 |
1595 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1596 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1596 // ignore |
1597 // ignore |
1597 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1598 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1598 accessMode &= 0444; |
1599 accessMode &= 0444; |
1599 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1600 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1600 #ifdef O_DIRECT |
1601 #ifdef O_DIRECT |
1601 flags |= O_DIRECT; |
1602 flags |= O_DIRECT; |
1602 #endif |
1603 #endif |
1603 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1604 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1604 // ignore |
1605 // ignore |
1605 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1606 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1606 // ignore; |
1607 // ignore; |
1607 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1608 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1608 __openmode = __stringVal(attrSym); |
1609 __openmode = __stringVal(attrSym); |
1609 } else { |
1610 } else { |
1610 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1611 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1611 } |
1612 } |
1612 } |
1613 } |
1613 } |
1614 } |
1614 do { |
1615 do { |
1615 __BEGIN_INTERRUPTABLE__ |
1616 __BEGIN_INTERRUPTABLE__ |
1616 fd = open((char *) __stringVal(encodedPathName), flags, accessMode); |
1617 fd = open((char *) __stringVal(encodedPathName), flags, accessMode); |
1617 __END_INTERRUPTABLE__ |
1618 __END_INTERRUPTABLE__ |
1618 } while ((fd < 0) && (__threadErrno == EINTR)); |
1619 } while ((fd < 0) && (__threadErrno == EINTR)); |
1619 |
1620 |
1620 if (fd >= 0) { |
1621 if (fd >= 0) { |
1621 __threadErrno = 0; |
1622 __threadErrno = 0; |
1622 f = fdopen(fd, __openmode); |
1623 f = fdopen(fd, __openmode); |
1623 if (f == NULL) { |
1624 if (f == NULL) { |
1624 close(fd); // fdopen failed, close before retry. |
1625 close(fd); // fdopen failed, close before retry. |
1625 } |
1626 } |
1626 } |
1627 } |
1627 } |
1628 } |
1628 |
1629 |
1629 # endif /* not WIN32 */ |
1630 # endif /* not WIN32 */ |
1630 #endif /* not VMS */ |
1631 #endif /* not VMS */ |
1631 |
1632 |
1632 |
1633 |
1633 if (f == NULL) { |
1634 if (f == NULL) { |
1634 /* |
1635 /* |
1635 * If no filedescriptors available, try to finalize |
1636 * If no filedescriptors available, try to finalize |
1636 * possibly collected fd's and try again. |
1637 * possibly collected fd's and try again. |
1637 */ |
1638 */ |
1638 if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) { |
1639 if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) { |
1639 pass = 1; |
1640 pass = 1; |
1640 __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); |
1641 __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); |
1641 __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); |
1642 __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); |
1642 goto retry; |
1643 goto retry; |
1643 } |
1644 } |
1644 badArgument: |
1645 badArgument: |
1645 getOutOfHere: |
1646 getOutOfHere: |
1646 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
1647 __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); |
1647 __INST(position) = nil; |
1648 __INST(position) = nil; |
1648 } else { |
1649 } else { |
1649 #ifdef __VMS__ |
1650 #ifdef __VMS__ |
1650 /* |
1651 /* |
1651 * check to see if this is positionable ... |
1652 * check to see if this is positionable ... |
1652 */ |
1653 */ |
1653 __INST(canPosition) = false; |
1654 __INST(canPosition) = false; |
1654 # ifndef _POSIX_C_SOURCE |
1655 # ifndef _POSIX_C_SOURCE |
1655 { |
1656 { |
1656 struct stat statBuffer; |
1657 struct stat statBuffer; |
1657 |
1658 |
1658 if (fstat(fileno(f), &statBuffer) >= 0) { |
1659 if (fstat(fileno(f), &statBuffer) >= 0) { |
1659 switch (statBuffer.st_fab_rfm) { |
1660 switch (statBuffer.st_fab_rfm) { |
1660 case FAB$C_UDF: /* undefined (also stream binary) */ |
1661 case FAB$C_UDF: /* undefined (also stream binary) */ |
1661 case FAB$C_VAR: /* variable length records */ |
1662 case FAB$C_VAR: /* variable length records */ |
1662 case FAB$C_VFC: /* variable fixed control */ |
1663 case FAB$C_VFC: /* variable fixed control */ |
1663 case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */ |
1664 case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */ |
1664 default: |
1665 default: |
1665 __INST(canPosition) = false; |
1666 __INST(canPosition) = false; |
1666 break; |
1667 break; |
1667 |
1668 |
1668 case FAB$C_FIX: /* fixed length records */ |
1669 case FAB$C_FIX: /* fixed length records */ |
1669 case FAB$C_STMLF: /* LF stream (valid only for sequential) */ |
1670 case FAB$C_STMLF: /* LF stream (valid only for sequential) */ |
1670 case FAB$C_STMCR: /* CR stream (valid only for sequential) */ |
1671 case FAB$C_STMCR: /* CR stream (valid only for sequential) */ |
1671 __INST(canPosition) = true; |
1672 __INST(canPosition) = true; |
1672 break; |
1673 break; |
1673 } |
1674 } |
1674 } |
1675 } |
1675 } |
1676 } |
1676 # endif |
1677 # endif |
1677 #else /* not VMS */ |
1678 #else /* not VMS */ |
1678 __INST(canPosition) = true; |
1679 __INST(canPosition) = true; |
1679 #endif /* not VMS */ |
1680 #endif /* not VMS */ |
1680 |
1681 |
1681 if (@global(FileOpenTrace) == true) { |
1682 if (@global(FileOpenTrace) == true) { |
1682 console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f); |
1683 console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f); |
1683 } |
1684 } |
1684 if (f != NULL) { |
1685 if (f != NULL) { |
1685 OBJ fp; |
1686 OBJ fp; |
1686 |
1687 |
1687 wasBlocked = __BLOCKINTERRUPTS(); |
1688 wasBlocked = __BLOCKINTERRUPTS(); |
1688 #if 0 |
1689 #if 0 |
1689 // The original code was: |
1690 // The original code was: |
1690 __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp); |
1691 __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp); |
1691 // but for that, gcc generates wrong code, which loads self (volatile) into |
1692 // but for that, gcc generates wrong code, which loads self (volatile) into |
1692 // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp. |
1693 // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp. |
1693 // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old |
1694 // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old |
1694 // object. |
1695 // object. |
1695 #else |
1696 #else |
1696 fp = __MKEXTERNALADDRESS(f); |
1697 fp = __MKEXTERNALADDRESS(f); |
1697 __INST(handle) = fp; |
1698 __INST(handle) = fp; |
1698 __STORE(self, fp); |
1699 __STORE(self, fp); |
1699 #endif |
1700 #endif |
1700 } |
1701 } |
1701 } |
1702 } |
1702 %}. |
1703 %}. |
1703 handle notNil ifTrue:[ |
1704 handle notNil ifTrue:[ |
1704 position := 0. |
1705 position := 0. |
1705 handleType := #filePointer. |
1706 handleType := #filePointer. |
1706 Lobby register:self. |
1707 Lobby register:self. |
1707 wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts]. |
1708 wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts]. |
1708 ]. |
1709 ]. |
1709 ^ handle |
1710 ^ handle |
1710 ! |
1711 ! |
1711 |
1712 |
1712 openForAppending |
1713 openForAppending |