1360 %{ |
1360 %{ |
1361 HFILE f = NULL; |
1361 HFILE f = NULL; |
1362 int pass = 0; |
1362 int pass = 0; |
1363 |
1363 |
1364 if (!__isNonNilObject(encodedPathName) |
1364 if (!__isNonNilObject(encodedPathName) |
1365 || !(__isStringLike(openmode) || __isArrayLike(openmode))) |
1365 || !(__isStringLike(openmode) || __isArrayLike(openmode))) |
1366 goto badArgument; |
1366 goto badArgument; |
1367 |
1367 |
1368 retry: |
1368 retry: |
1369 #ifdef __VMS__ |
1369 #ifdef __VMS__ |
1370 if (__isStringLike(encodedPathName)) { |
1370 if (__isStringLike(encodedPathName)) { |
1371 do { |
1371 do { |
1372 /* |
1372 /* |
1373 * allow passing additional RMS arguments. |
1373 * allow passing additional RMS arguments. |
1374 * stupid: DEC does not seem to offer an interface for passing a char **. |
1374 * stupid: DEC does not seem to offer an interface for passing a char **. |
1375 */ |
1375 */ |
1376 __threadErrno = 0; |
1376 __threadErrno = 0; |
1377 |
1377 |
1378 { |
1378 { |
1379 if (__isArray(attributeSpec)) { |
1379 if (__isArray(attributeSpec)) { |
1380 OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; |
1380 OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; |
1381 int numAttrib = 0; |
1381 int numAttrib = 0; |
1382 int i; |
1382 int i; |
1383 |
1383 |
1384 numAttrib = __arraySize(attributeSpec); |
1384 numAttrib = __arraySize(attributeSpec); |
1385 for (i=0; i<numAttrib;i++) { |
1385 for (i=0; i<numAttrib;i++) { |
1386 if (! __isStringLike(ap[i])) { |
1386 if (! __isStringLike(ap[i])) { |
1387 __threadErrno = EINVAL; /* invalid argument */ |
1387 __threadErrno = EINVAL; /* invalid argument */ |
1388 goto getOutOfHere; |
1388 goto getOutOfHere; |
1389 } |
1389 } |
1390 } |
1390 } |
1391 switch (numAttrib) { |
1391 switch (numAttrib) { |
1392 case 0: |
1392 case 0: |
1393 __BEGIN_INTERRUPTABLE__ |
1393 __BEGIN_INTERRUPTABLE__ |
1394 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode)); |
1394 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode)); |
1395 __END_INTERRUPTABLE__ |
1395 __END_INTERRUPTABLE__ |
1396 break; |
1396 break; |
1397 case 1: |
1397 case 1: |
1398 __BEGIN_INTERRUPTABLE__ |
1398 __BEGIN_INTERRUPTABLE__ |
1399 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1399 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1400 __stringVal(ap[0])); |
1400 __stringVal(ap[0])); |
1401 __END_INTERRUPTABLE__ |
1401 __END_INTERRUPTABLE__ |
1402 break; |
1402 break; |
1403 case 2: |
1403 case 2: |
1404 __BEGIN_INTERRUPTABLE__ |
1404 __BEGIN_INTERRUPTABLE__ |
1405 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1405 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1406 __stringVal(ap[0]), __stringVal(ap[1])); |
1406 __stringVal(ap[0]), __stringVal(ap[1])); |
1407 __END_INTERRUPTABLE__ |
1407 __END_INTERRUPTABLE__ |
1408 break; |
1408 break; |
1409 case 3: |
1409 case 3: |
1410 __BEGIN_INTERRUPTABLE__ |
1410 __BEGIN_INTERRUPTABLE__ |
1411 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1411 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1412 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2])); |
1412 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2])); |
1413 __END_INTERRUPTABLE__ |
1413 __END_INTERRUPTABLE__ |
1414 break; |
1414 break; |
1415 case 4: |
1415 case 4: |
1416 __BEGIN_INTERRUPTABLE__ |
1416 __BEGIN_INTERRUPTABLE__ |
1417 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1417 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1418 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1418 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1419 __stringVal(ap[3])); |
1419 __stringVal(ap[3])); |
1420 __END_INTERRUPTABLE__ |
1420 __END_INTERRUPTABLE__ |
1421 break; |
1421 break; |
1422 case 5: |
1422 case 5: |
1423 __BEGIN_INTERRUPTABLE__ |
1423 __BEGIN_INTERRUPTABLE__ |
1424 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1424 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1425 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1425 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1426 __stringVal(ap[3]), __stringVal(ap[4])); |
1426 __stringVal(ap[3]), __stringVal(ap[4])); |
1427 __END_INTERRUPTABLE__ |
1427 __END_INTERRUPTABLE__ |
1428 break; |
1428 break; |
1429 case 6: |
1429 case 6: |
1430 __BEGIN_INTERRUPTABLE__ |
1430 __BEGIN_INTERRUPTABLE__ |
1431 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1431 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1432 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1432 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1433 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5])); |
1433 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5])); |
1434 __END_INTERRUPTABLE__ |
1434 __END_INTERRUPTABLE__ |
1435 break; |
1435 break; |
1436 case 7: |
1436 case 7: |
1437 __BEGIN_INTERRUPTABLE__ |
1437 __BEGIN_INTERRUPTABLE__ |
1438 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1438 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1439 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1439 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1440 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1440 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1441 __stringVal(ap[6])); |
1441 __stringVal(ap[6])); |
1442 __END_INTERRUPTABLE__ |
1442 __END_INTERRUPTABLE__ |
1443 break; |
1443 break; |
1444 case 8: |
1444 case 8: |
1445 __BEGIN_INTERRUPTABLE__ |
1445 __BEGIN_INTERRUPTABLE__ |
1446 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1446 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1447 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1447 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1448 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1448 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1449 __stringVal(ap[6]), __stringVal(ap[7])); |
1449 __stringVal(ap[6]), __stringVal(ap[7])); |
1450 __END_INTERRUPTABLE__ |
1450 __END_INTERRUPTABLE__ |
1451 break; |
1451 break; |
1452 case 9: |
1452 case 9: |
1453 __BEGIN_INTERRUPTABLE__ |
1453 __BEGIN_INTERRUPTABLE__ |
1454 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1454 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1455 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1455 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1456 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1456 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1457 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8])); |
1457 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8])); |
1458 __END_INTERRUPTABLE__ |
1458 __END_INTERRUPTABLE__ |
1459 break; |
1459 break; |
1460 case 10: |
1460 case 10: |
1461 __BEGIN_INTERRUPTABLE__ |
1461 __BEGIN_INTERRUPTABLE__ |
1462 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1462 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), |
1463 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1463 __stringVal(ap[0]), __stringVal(ap[1]), __stringVal(ap[2]), |
1464 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1464 __stringVal(ap[3]), __stringVal(ap[4]), __stringVal(ap[5]), |
1465 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]), |
1465 __stringVal(ap[6]), __stringVal(ap[7]), __stringVal(ap[8]), |
1466 __stringVal(ap[9])); |
1466 __stringVal(ap[9])); |
1467 __END_INTERRUPTABLE__ |
1467 __END_INTERRUPTABLE__ |
1468 break; |
1468 break; |
1469 default: |
1469 default: |
1470 __threadErrno = E2BIG; /* too many args */ |
1470 __threadErrno = E2BIG; /* too many args */ |
1471 goto getOutOfHere; |
1471 goto getOutOfHere; |
1472 } |
1472 } |
1473 } else if (attributeSpec != nil) { |
1473 } else if (attributeSpec != nil) { |
1474 __threadErrno = EINVAL; /* invalid argument */ |
1474 __threadErrno = EINVAL; /* invalid argument */ |
1475 goto getOutOfHere; |
1475 goto getOutOfHere; |
1476 } else { |
1476 } else { |
1477 /* |
1477 /* |
1478 * create file as sequential streamLF by default. |
1478 * create file as sequential streamLF by default. |
1479 */ |
1479 */ |
1480 __BEGIN_INTERRUPTABLE__ |
1480 __BEGIN_INTERRUPTABLE__ |
1481 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf"); |
1481 f = fopen((char *)__stringVal(pathName), (char *)__stringVal(openmode), "rfm=stmlf"); |
1482 __END_INTERRUPTABLE__ |
1482 __END_INTERRUPTABLE__ |
1483 } |
1483 } |
1484 } |
1484 } |
1485 } while ((f == NULL) && (__threadErrno == EINTR)); |
1485 } while ((f == NULL) && (__threadErrno == EINTR)); |
1486 } |
1486 } |
1487 #else /* not VMS */ |
1487 #else /* not VMS */ |
1488 |
1488 |
1489 # ifdef WIN32 |
1489 # ifdef WIN32 |
1490 { |
1490 { |
1491 DWORD share = 0, access = 0, create = 0, attr = 0; |
1491 DWORD share = 0, access = 0, create = 0, attr = 0; |
1492 char * __openmode; |
1492 char * __openmode; |
1493 HANDLE handle; |
1493 HANDLE handle; |
1494 SECURITY_ATTRIBUTES sa; |
1494 SECURITY_ATTRIBUTES sa; |
1495 |
1495 |
1496 if (__isStringLike(openmode)) { |
1496 if (__isStringLike(openmode)) { |
1497 share = FILE_SHARE_READ|FILE_SHARE_WRITE; |
1497 share = FILE_SHARE_READ|FILE_SHARE_WRITE; |
1498 __openmode = __stringVal(openmode); |
1498 __openmode = __stringVal(openmode); |
1499 if (strcmp(__openmode, "rb") == 0) { |
1499 if (strcmp(__openmode, "rb") == 0) { |
1500 access = GENERIC_READ; |
1500 access = GENERIC_READ; |
1501 create = OPEN_EXISTING; |
1501 create = OPEN_EXISTING; |
1502 } else if (strcmp(__openmode, "rb+") == 0) { |
1502 } else if (strcmp(__openmode, "rb+") == 0) { |
1503 access = GENERIC_READ | GENERIC_WRITE; |
1503 access = GENERIC_READ | GENERIC_WRITE; |
1504 create = OPEN_EXISTING; |
1504 create = OPEN_EXISTING; |
1505 } else if (strcmp(__openmode, "wb") == 0) { |
1505 } else if (strcmp(__openmode, "wb") == 0) { |
1506 access = GENERIC_WRITE; |
1506 access = GENERIC_WRITE; |
1507 create = CREATE_ALWAYS; |
1507 create = CREATE_ALWAYS; |
1508 } else if (strcmp(__openmode, "wb+") == 0) { |
1508 } else if (strcmp(__openmode, "wb+") == 0) { |
1509 access = GENERIC_READ | GENERIC_WRITE; |
1509 access = GENERIC_READ | GENERIC_WRITE; |
1510 create = CREATE_ALWAYS; |
1510 create = CREATE_ALWAYS; |
1511 } else if (strcmp(__openmode, "ab") == 0) { |
1511 } else if (strcmp(__openmode, "ab") == 0) { |
1512 access = FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1512 access = FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1513 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1513 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1514 create = OPEN_ALWAYS; |
1514 create = OPEN_ALWAYS; |
1515 } else if (strcmp(__openmode, "ab+") == 0) { |
1515 } else if (strcmp(__openmode, "ab+") == 0) { |
1516 access = GENERIC_READ |FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1516 access = GENERIC_READ |FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA| |
1517 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1517 STANDARD_RIGHTS_WRITE|SYNCHRONIZE; |
1518 create = OPEN_ALWAYS; |
1518 create = OPEN_ALWAYS; |
1519 } else { |
1519 } else { |
1520 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1520 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1521 } |
1521 } |
1522 } else if (__isArrayLike(openmode)) { |
1522 } else if (__isArrayLike(openmode)) { |
1523 OBJ *ap = __arrayVal(openmode); |
1523 OBJ *ap = __arrayVal(openmode); |
1524 int numAttrib = __arraySize(openmode); |
1524 int numAttrib = __arraySize(openmode); |
1525 int i; |
1525 int i; |
1526 |
1526 |
1527 __openmode = "rb+"; |
1527 __openmode = "rb+"; |
1528 |
1528 |
1529 for (i=0; i<numAttrib; i++) { |
1529 for (i=0; i<numAttrib; i++) { |
1530 OBJ attrSym = ap[i]; |
1530 OBJ attrSym = ap[i]; |
1531 |
1531 |
1532 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1532 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1533 share |= FILE_SHARE_READ; |
1533 share |= FILE_SHARE_READ; |
1534 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1534 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1535 share |= FILE_SHARE_WRITE; |
1535 share |= FILE_SHARE_WRITE; |
1536 |
1536 |
1537 } else if (attrSym == @symbol(GENERIC_READ)) { |
1537 } else if (attrSym == @symbol(GENERIC_READ)) { |
1538 access |= GENERIC_READ; |
1538 access |= GENERIC_READ; |
1539 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1539 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1540 access |= GENERIC_WRITE; |
1540 access |= GENERIC_WRITE; |
1541 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1541 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1542 access |= GENERIC_READ|GENERIC_WRITE; |
1542 access |= GENERIC_READ|GENERIC_WRITE; |
1543 |
1543 |
1544 } else if (attrSym == @symbol(CREATE_NEW)) { |
1544 } else if (attrSym == @symbol(CREATE_NEW)) { |
1545 create |= CREATE_NEW; |
1545 create |= CREATE_NEW; |
1546 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1546 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1547 create |= CREATE_ALWAYS; |
1547 create |= CREATE_ALWAYS; |
1548 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1548 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1549 create |= OPEN_EXISTING; |
1549 create |= OPEN_EXISTING; |
1550 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1550 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1551 create |= OPEN_ALWAYS; |
1551 create |= OPEN_ALWAYS; |
1552 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1552 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1553 create |= TRUNCATE_EXISTING; |
1553 create |= TRUNCATE_EXISTING; |
1554 |
1554 |
1555 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1555 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1556 attr |= FILE_ATTRIBUTE_HIDDEN; |
1556 attr |= FILE_ATTRIBUTE_HIDDEN; |
1557 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1557 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1558 attr |= FILE_ATTRIBUTE_READONLY; |
1558 attr |= FILE_ATTRIBUTE_READONLY; |
1559 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1559 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1560 attr |= FILE_FLAG_WRITE_THROUGH; |
1560 attr |= FILE_FLAG_WRITE_THROUGH; |
1561 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1561 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1562 attr |= FILE_FLAG_SEQUENTIAL_SCAN; |
1562 attr |= FILE_FLAG_SEQUENTIAL_SCAN; |
1563 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1563 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1564 attr |= FILE_FLAG_DELETE_ON_CLOSE; |
1564 attr |= FILE_FLAG_DELETE_ON_CLOSE; |
1565 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1565 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1566 __openmode = __stringVal(attrSym); |
1566 __openmode = __stringVal(attrSym); |
1567 } else { |
1567 } else { |
1568 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1568 console_fprintf(stderr, "Win32OS [warning]: unsupported open mode\n"); |
1569 } |
1569 } |
1570 } |
1570 } |
1571 } |
1571 } |
1572 if (create == 0) { |
1572 if (create == 0) { |
1573 // argumentError = @symbol(missingCreateMode); |
1573 // argumentError = @symbol(missingCreateMode); |
1574 goto badArgument; |
1574 goto badArgument; |
1575 } |
1575 } |
1576 if (attr == 0) { |
1576 if (attr == 0) { |
1577 attr = FILE_ATTRIBUTE_NORMAL; |
1577 attr = FILE_ATTRIBUTE_NORMAL; |
1578 } |
1578 } |
1579 |
1579 |
1580 /* |
1580 /* |
1581 * create security attributes - make handle inheritable by subprocesses |
1581 * create security attributes - make handle inheritable by subprocesses |
1582 */ |
1582 */ |
1583 memset(&sa, 0, sizeof (sa)); |
1583 memset(&sa, 0, sizeof (sa)); |
1584 sa.nLength = sizeof( sa ); |
1584 sa.nLength = sizeof( sa ); |
1585 // sa.bInheritHandle = TRUE; |
1585 // sa.bInheritHandle = TRUE; |
1586 sa.bInheritHandle = FALSE; |
1586 sa.bInheritHandle = FALSE; |
1587 |
1587 |
1588 if (__isStringLike(pathName)) { |
1588 if (__isStringLike(pathName)) { |
1589 char _aPathName[MAXPATHLEN]; |
1589 char _aPathName[MAXPATHLEN]; |
1590 |
1590 |
1591 strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
1591 strncpy(_aPathName, __stringVal(pathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
1592 do { |
1592 do { |
1593 __threadErrno = 0; |
1593 __threadErrno = 0; |
1594 handle = STX_API_NOINT_CALL7( "CreateFileA", CreateFileA, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1594 handle = STX_API_NOINT_CALL7( "CreateFileA", CreateFileA, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1595 if (__threadErrno == EINTR) { |
1595 if (__threadErrno == EINTR) { |
1596 handle = INVALID_HANDLE_VALUE; |
1596 handle = INVALID_HANDLE_VALUE; |
1597 } |
1597 } |
1598 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1598 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1599 } else if (__isUnicode16String(pathName)) { |
1599 } else if (__isUnicode16String(pathName)) { |
1600 wchar_t _aPathName[MAXPATHLEN+1]; |
1600 wchar_t _aPathName[MAXPATHLEN+1]; |
1601 int i, l; |
1601 int i, l; |
1602 |
1602 |
1603 l = __unicode16StringSize(pathName); |
1603 l = __unicode16StringSize(pathName); |
1604 if (l > MAXPATHLEN) l = MAXPATHLEN; |
1604 if (l > MAXPATHLEN) l = MAXPATHLEN; |
1605 for (i=0; i<l; i++) { |
1605 for (i=0; i<l; i++) { |
1606 _aPathName[i] = __unicode16StringVal(pathName)[i]; |
1606 _aPathName[i] = __unicode16StringVal(pathName)[i]; |
1607 } |
1607 } |
1608 _aPathName[i] = 0; |
1608 _aPathName[i] = 0; |
1609 |
1609 |
1610 do { |
1610 do { |
1611 __threadErrno = 0; |
1611 __threadErrno = 0; |
1612 handle = STX_API_NOINT_CALL7( "CreateFileW", CreateFileW, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1612 handle = STX_API_NOINT_CALL7( "CreateFileW", CreateFileW, _aPathName, access, share, &sa, create, attr, 0 /* hTempl */); |
1613 if (__threadErrno == EINTR) { |
1613 if (__threadErrno == EINTR) { |
1614 handle = INVALID_HANDLE_VALUE; |
1614 handle = INVALID_HANDLE_VALUE; |
1615 } |
1615 } |
1616 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1616 } while ((handle == INVALID_HANDLE_VALUE) && (__threadErrno == EINTR)); |
1617 } |
1617 } |
1618 if (handle != INVALID_HANDLE_VALUE) { |
1618 if (handle != INVALID_HANDLE_VALUE) { |
1619 int fd; |
1619 int fd; |
1620 extern void __stxWrapApiEnterCritical(), __stxWrapApiLeaveCritical(); |
1620 extern void __stxWrapApiEnterCritical(), __stxWrapApiLeaveCritical(); |
1621 |
1621 |
1622 __stxWrapApiEnterCritical(); |
1622 __stxWrapApiEnterCritical(); |
1623 fd = _open_osfhandle((long)handle, O_BINARY); |
1623 fd = _open_osfhandle((long)handle, O_BINARY); |
1624 if (fd < 0) { |
1624 if (fd < 0) { |
1625 if (__threadErrno == 0) { |
1625 if (__threadErrno == 0) { |
1626 // no more file descriptors |
1626 // no more file descriptors |
1627 __threadErrno = EMFILE; |
1627 __threadErrno = EMFILE; |
1628 } |
1628 } |
1629 CloseHandle(handle); |
1629 CloseHandle(handle); |
1630 } else { |
1630 } else { |
1631 f = fdopen(fd, __openmode); |
1631 f = fdopen(fd, __openmode); |
1632 } |
1632 } |
1633 __stxWrapApiLeaveCritical(); |
1633 __stxWrapApiLeaveCritical(); |
1634 } else { |
1634 } else { |
1635 __threadErrno = __WIN32_ERR(GetLastError()); |
1635 __threadErrno = __WIN32_ERR(GetLastError()); |
1636 } |
1636 } |
1637 } |
1637 } |
1638 # else /* not WIN32 */ |
1638 # else /* not WIN32 */ |
1639 |
1639 |
1640 if (__isStringLike(encodedPathName)) { |
1640 if (__isStringLike(encodedPathName)) { |
1641 int accessMode = 0666; // default access mode of fopen(), relies on umask() |
1641 int accessMode = 0666; // default access mode of fopen(), relies on umask() |
1642 int flags = 0; |
1642 int flags = 0; |
1643 int fd; |
1643 int fd; |
1644 char * __openmode; |
1644 char * __openmode; |
1645 |
1645 |
1646 if (__isStringLike(openmode)) { |
1646 if (__isStringLike(openmode)) { |
1647 __openmode = __stringVal(openmode); |
1647 __openmode = __stringVal(openmode); |
1648 if (strcmp(__openmode, "r") == 0) { |
1648 if (strcmp(__openmode, "r") == 0) { |
1649 flags = O_RDONLY; |
1649 flags = O_RDONLY; |
1650 } else if (strcmp(__openmode, "r+") == 0) { |
1650 } else if (strcmp(__openmode, "r+") == 0) { |
1651 flags = O_RDWR; |
1651 flags = O_RDWR; |
1652 } else if (strcmp(__openmode, "w") == 0) { |
1652 } else if (strcmp(__openmode, "w") == 0) { |
1653 flags = O_WRONLY | O_CREAT | O_TRUNC; |
1653 flags = O_WRONLY | O_CREAT | O_TRUNC; |
1654 } else if (strcmp(__openmode, "w+") == 0) { |
1654 } else if (strcmp(__openmode, "w+") == 0) { |
1655 flags = O_RDWR | O_CREAT | O_TRUNC; |
1655 flags = O_RDWR | O_CREAT | O_TRUNC; |
1656 } else if (strcmp(__openmode, "a") == 0) { |
1656 } else if (strcmp(__openmode, "a") == 0) { |
1657 flags = O_WRONLY | O_CREAT | O_APPEND; |
1657 flags = O_WRONLY | O_CREAT | O_APPEND; |
1658 } else if (strcmp(__openmode, "a+") == 0) { |
1658 } else if (strcmp(__openmode, "a+") == 0) { |
1659 flags = O_RDWR | O_CREAT| O_APPEND; |
1659 flags = O_RDWR | O_CREAT| O_APPEND; |
1660 } else { |
1660 } else { |
1661 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1661 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1662 } |
1662 } |
1663 } else if (__isArrayLike(openmode)) { |
1663 } else if (__isArrayLike(openmode)) { |
1664 OBJ *ap = __arrayVal(openmode); |
1664 OBJ *ap = __arrayVal(openmode); |
1665 int numAttrib = __arraySize(openmode); |
1665 int numAttrib = __arraySize(openmode); |
1666 int i; |
1666 int i; |
1667 |
1667 |
1668 __openmode = "r+"; |
1668 __openmode = "r+"; |
1669 |
1669 |
1670 for (i=0; i<numAttrib; i++) { |
1670 for (i=0; i<numAttrib; i++) { |
1671 OBJ attrSym = ap[i]; |
1671 OBJ attrSym = ap[i]; |
1672 |
1672 |
1673 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1673 if (attrSym == @symbol(FILE_SHARE_READ)) { |
1674 // ignore |
1674 // ignore |
1675 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1675 } else if (attrSym == @symbol(FILE_SHARE_WRITE)) { |
1676 // ignore |
1676 // ignore |
1677 } else if (attrSym == @symbol(GENERIC_READ)) { |
1677 } else if (attrSym == @symbol(GENERIC_READ)) { |
1678 flags |= O_RDONLY; |
1678 flags |= O_RDONLY; |
1679 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1679 } else if (attrSym == @symbol(GENERIC_WRITE)) { |
1680 flags |= O_WRONLY; |
1680 flags |= O_WRONLY; |
1681 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1681 } else if (attrSym == @symbol(GENERIC_READ_WRITE)) { |
1682 flags |= O_RDWR; |
1682 flags |= O_RDWR; |
1683 |
1683 |
1684 } else if (attrSym == @symbol(CREATE_NEW)) { |
1684 } else if (attrSym == @symbol(CREATE_NEW)) { |
1685 flags |= O_CREAT|O_EXCL; |
1685 flags |= O_CREAT|O_EXCL; |
1686 accessMode = 0600; // simulate mkstemp() |
1686 accessMode = 0600; // simulate mkstemp() |
1687 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1687 } else if (attrSym == @symbol(CREATE_ALWAYS)) { |
1688 flags |= O_CREAT|O_TRUNC; |
1688 flags |= O_CREAT|O_TRUNC; |
1689 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1689 } else if (attrSym == @symbol(OPEN_EXISTING)) { |
1690 // nothing to be set |
1690 // nothing to be set |
1691 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1691 } else if (attrSym == @symbol(OPEN_ALWAYS)) { |
1692 flags |= O_CREAT; |
1692 flags |= O_CREAT; |
1693 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1693 } else if (attrSym == @symbol(TRUNCATE_EXISTING)) { |
1694 flags |= O_TRUNC; |
1694 flags |= O_TRUNC; |
1695 |
1695 |
1696 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1696 } else if (attrSym == @symbol(FILE_ATTRIBUTE_HIDDEN)) { |
1697 // ignore |
1697 // ignore |
1698 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1698 } else if (attrSym == @symbol(FILE_ATTRIBUTE_READONLY)) { |
1699 accessMode &= 0444; |
1699 accessMode &= 0444; |
1700 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1700 } else if (attrSym == @symbol(FILE_FLAG_WRITE_THROUGH)) { |
1701 #ifdef O_DIRECT |
1701 #ifdef O_DIRECT |
1702 flags |= O_DIRECT; |
1702 flags |= O_DIRECT; |
1703 #endif |
1703 #endif |
1704 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1704 } else if (attrSym == @symbol(FILE_FLAG_SEQUENTIAL_SCAN)) { |
1705 // ignore |
1705 // ignore |
1706 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1706 } else if (attrSym == @symbol(FILE_FLAG_DELETE_ON_CLOSE)) { |
1707 // ignore; |
1707 // ignore; |
1708 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1708 } else if (!__isSymbol(attrSym) && __isStringLike(attrSym)) { |
1709 __openmode = __stringVal(attrSym); |
1709 __openmode = __stringVal(attrSym); |
1710 } else { |
1710 } else { |
1711 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1711 console_fprintf(stderr, "UNIXOS [warning]: unsupported open mode\n"); |
1712 } |
1712 } |
1713 } |
1713 } |
1714 } |
1714 } |
1715 do { |
1715 do { |
1716 __BEGIN_INTERRUPTABLE__ |
1716 __BEGIN_INTERRUPTABLE__ |
1717 fd = open((char *) __stringVal(encodedPathName), flags, accessMode); |
1717 fd = open((char *) __stringVal(encodedPathName), flags, accessMode); |
1718 __END_INTERRUPTABLE__ |
1718 __END_INTERRUPTABLE__ |
1719 } while ((fd < 0) && (__threadErrno == EINTR)); |
1719 } while ((fd < 0) && (__threadErrno == EINTR)); |
1720 |
1720 |
1721 if (fd >= 0) { |
1721 if (fd >= 0) { |
1722 __threadErrno = 0; |
1722 __threadErrno = 0; |
1723 f = fdopen(fd, __openmode); |
1723 f = fdopen(fd, __openmode); |
1724 if (f == NULL) { |
1724 if (f == NULL) { |
1725 close(fd); // fdopen failed, close before retry. |
1725 close(fd); // fdopen failed, close before retry. |
1726 } |
1726 } |
1727 } |
1727 } |
1728 } |
1728 } |
1729 |
1729 |
1730 # endif /* not WIN32 */ |
1730 # endif /* not WIN32 */ |
1731 #endif /* not VMS */ |
1731 #endif /* not VMS */ |
1732 |
1732 |
1733 |
1733 |
1734 if (f == NULL) { |
1734 if (f == NULL) { |
1735 /* |
1735 /* |
1736 * If no filedescriptors available, try to finalize |
1736 * If no filedescriptors available, try to finalize |
1737 * possibly collected fd's and try again. |
1737 * possibly collected fd's and try again. |
1738 */ |
1738 */ |
1739 if ((__threadErrno == ENFILE || __threadErrno == EMFILE) && pass == 0) { |
1739 if ((__threadErrno == ENFILE || __threadErrno == EMFILE) && pass == 0) { |
1740 pass = 1; |
1740 pass = 1; |
1741 __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); |
1741 __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); |
1742 __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); |
1742 __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); |
1743 goto retry; |
1743 goto retry; |
1744 } |
1744 } |
1745 badArgument: |
1745 badArgument: |
1746 getOutOfHere: |
1746 getOutOfHere: |
1747 error = __mkSmallInteger(__threadErrno); |
1747 error = __mkSmallInteger(__threadErrno); |
1748 __INST(position) = nil; |
1748 __INST(position) = nil; |
1749 } else { |
1749 } else { |
1750 #ifdef __VMS__ |
1750 #ifdef __VMS__ |
1751 /* |
1751 /* |
1752 * check to see if this is positionable ... |
1752 * check to see if this is positionable ... |
1753 */ |
1753 */ |
1754 __INST(canPosition) = false; |
1754 __INST(canPosition) = false; |
1755 # ifndef _POSIX_C_SOURCE |
1755 # ifndef _POSIX_C_SOURCE |
1756 { |
1756 { |
1757 struct stat statBuffer; |
1757 struct stat statBuffer; |
1758 |
1758 |
1759 if (fstat(fileno(f), &statBuffer) >= 0) { |
1759 if (fstat(fileno(f), &statBuffer) >= 0) { |
1760 switch (statBuffer.st_fab_rfm) { |
1760 switch (statBuffer.st_fab_rfm) { |
1761 case FAB$C_UDF: /* undefined (also stream binary) */ |
1761 case FAB$C_UDF: /* undefined (also stream binary) */ |
1762 case FAB$C_VAR: /* variable length records */ |
1762 case FAB$C_VAR: /* variable length records */ |
1763 case FAB$C_VFC: /* variable fixed control */ |
1763 case FAB$C_VFC: /* variable fixed control */ |
1764 case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */ |
1764 case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */ |
1765 default: |
1765 default: |
1766 __INST(canPosition) = false; |
1766 __INST(canPosition) = false; |
1767 break; |
1767 break; |
1768 |
1768 |
1769 case FAB$C_FIX: /* fixed length records */ |
1769 case FAB$C_FIX: /* fixed length records */ |
1770 case FAB$C_STMLF: /* LF stream (valid only for sequential) */ |
1770 case FAB$C_STMLF: /* LF stream (valid only for sequential) */ |
1771 case FAB$C_STMCR: /* CR stream (valid only for sequential) */ |
1771 case FAB$C_STMCR: /* CR stream (valid only for sequential) */ |
1772 __INST(canPosition) = true; |
1772 __INST(canPosition) = true; |
1773 break; |
1773 break; |
1774 } |
1774 } |
1775 } |
1775 } |
1776 } |
1776 } |
1777 # endif |
1777 # endif |
1778 #else /* not VMS */ |
1778 #else /* not VMS */ |
1779 __INST(canPosition) = true; |
1779 __INST(canPosition) = true; |
1780 #endif /* not VMS */ |
1780 #endif /* not VMS */ |
1781 |
1781 |
1782 if (@global(FileOpenTrace) == true) { |
1782 if (@global(FileOpenTrace) == true) { |
1783 console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f); |
1783 console_fprintf(stderr, "fopen %s [FileStream] -> %"_lx_"\n", __stringVal(pathName), (INT)f); |
1784 } |
1784 } |
1785 if (f != NULL) { |
1785 if (f != NULL) { |
1786 OBJ fp; |
1786 OBJ fp; |
1787 |
1787 |
1788 wasBlocked = __BLOCKINTERRUPTS(); |
1788 wasBlocked = __BLOCKINTERRUPTS(); |
1789 #if 0 |
1789 #if 0 |
1790 // The original code was: |
1790 // The original code was: |
1791 __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp); |
1791 __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp); |
1792 // but for that, gcc generates wrong code, which loads self (volatile) into |
1792 // but for that, gcc generates wrong code, which loads self (volatile) into |
1793 // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp. |
1793 // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp. |
1794 // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old |
1794 // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old |
1795 // object. |
1795 // object. |
1796 #else |
1796 #else |
1797 fp = __MKEXTERNALADDRESS(f); |
1797 fp = __MKEXTERNALADDRESS(f); |
1798 __INST(handle) = fp; |
1798 __INST(handle) = fp; |
1799 __STORE(self, fp); |
1799 __STORE(self, fp); |
1800 #endif |
1800 #endif |
1801 } |
1801 } |
1802 } |
1802 } |
1803 %}. |
1803 %}. |
1804 error notNil ifTrue:[ |
1804 error notNil ifTrue:[ |
1805 lastErrorNumber := error. |
1805 lastErrorNumber := error. |
1806 ^ self openError:error. |
1806 ^ self openError:error. |
1807 ]. |
1807 ]. |
1808 handle isNil ifTrue:[ |
1808 handle isNil ifTrue:[ |
1809 ^ self openError:0. |
1809 ^ self openError:0. |
1810 ]. |
1810 ]. |
1811 |
1811 |
1812 position := 0. |
1812 position := 0. |
1813 handleType := #filePointer. |
1813 handleType := #filePointer. |
1814 Lobby register:self. |
1814 Lobby register:self. |