Diff
Not logged in

Differences From Artifact [44d0315cac]:

To Artifact [274dafda2d]:


1509
1510
1511
1512
1513
1514
1515
1516

1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531

1532
1533

1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551


1552
1553
1554
1555
1556
1557
1558
1509
1510
1511
1512
1513
1514
1515

1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530

1531
1532

1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549


1550
1551
1552
1553
1554
1555
1556
1557
1558







-
+














-
+

-
+
















-
-
+
+







	}
	return mode;

    error:
	*modeFlagsPtr = 0;
	if (interp != NULL) {
	    TclPrintfResult(interp, "illegal access mode \"%s\"", modeString);
	    Tcl_SetErrorCode(interp, "TCL", "OPENMODE", "INVALID", (char *)NULL);
	    TclSetErrorCode(interp, "TCL", "OPENMODE", "INVALID");
	}
	return -1;
    }

    /*
     * The access modes are specified as a list of POSIX modes like O_CREAT.
     *
     * Tcl_SplitList must work correctly when interp is NULL.
     */

    if (Tcl_SplitList(interp, modeString, &modeArgc, &modeArgv) != TCL_OK) {
    invAccessMode:
	if (interp != NULL) {
	    TclAppendPrintfToErrorInfo(interp,
		    "\n    while processing open access modes \"%s\"",
		    "\n    (while processing open access modes \"%s\")",
		    modeString);
	    Tcl_SetErrorCode(interp, "TCL", "OPENMODE", "INVALID", (char *)NULL);
	    TclSetErrorCode(interp, "TCL", "OPENMODE", "INVALID");
	}
	if (modeArgv) {
	    Tcl_Free((void *)modeArgv);
	}
	return -1;
    }

    gotRW = 0;
    for (i = 0; i < modeArgc; i++) {
	flag = modeArgv[i];
	c = flag[0];
	if ((c == 'R') && (strcmp(flag, "RDONLY") == 0)) {
	    if (gotRW) {
	    invRW:
		if (interp != NULL) {
		    TclPrintfResult(interp,
				"invalid access mode \"%s\": modes RDONLY, "
				"RDWR, and WRONLY cannot be combined", flag);
			    "invalid access mode \"%s\": modes RDONLY, "
			    "RDWR, and WRONLY cannot be combined", flag);
		}
		goto invAccessMode;
	    }
	    mode = (mode & ~O_ACCMODE) | O_RDONLY;
	    gotRW = 1;
	} else if ((c == 'W') && (strcmp(flag, "WRONLY") == 0)) {
	    if (gotRW) {
1566
1567
1568
1569
1570
1571
1572
1573
1574


1575
1576
1577
1578
1579
1580
1581
1566
1567
1568
1569
1570
1571
1572


1573
1574
1575
1576
1577
1578
1579
1580
1581







-
-
+
+







	    }
	    mode = (mode & ~O_ACCMODE) | O_RDWR;
	    gotRW = 1;
	} else if ((c == 'A') && (strcmp(flag, "APPEND") == 0)) {
	    if (mode & O_APPEND) {
	    accessFlagRepeated:
		if (interp) {
		    TclPrintfResult(interp,
			    "access mode \"%s\" repeated", flag);
		    TclPrintfResult(interp, "access mode \"%s\" repeated",
			    flag);
		}
		goto invAccessMode;
	    }
	    mode |= O_APPEND;
	    *modeFlagsPtr |= 1;
	} else if ((c == 'C') && (strcmp(flag, "CREAT") == 0)) {
	    if (mode & O_CREAT) {
1702
1703
1704
1705
1706
1707
1708
1709

1710
1711
1712
1713
1714
1715
1716

1717
1718
1719
1720
1721
1722
1723
1724
1702
1703
1704
1705
1706
1707
1708

1709

1710
1711
1712
1713
1714

1715

1716
1717
1718
1719
1720
1721
1722







-
+
-





-
+
-








    if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) {
	return result;
    }

    if (Tcl_FSStat(pathPtr, &statBuf) == -1) {
	Tcl_SetErrno(errno);
	TclPrintfResult(interp,
	TclPrintfResult(interp, "couldn't read file \"%s\": %s",
		"couldn't read file \"%s\": %s",
		TclGetString(pathPtr), Tcl_PosixError(interp));
	return result;
    }
    chan = Tcl_FSOpenFileChannel(interp, pathPtr, "r", 0644);
    if (chan == NULL) {
	TclPrintfResult(interp,
	TclPrintfResult(interp, "couldn't read file \"%s\": %s",
		"couldn't read file \"%s\": %s",
		TclGetString(pathPtr), Tcl_PosixError(interp));
	return result;
    }

    /*
     * The eof character is \x1A (^Z). Tcl uses it on every platform to allow
     * for scripted documents. [Bug: 2040]
1745
1746
1747
1748
1749
1750
1751
1752

1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767

1768
1769
1770
1771
1772
1773
1774
1775
1743
1744
1745
1746
1747
1748
1749

1750

1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763

1764

1765
1766
1767
1768
1769
1770
1771







-
+
-













-
+
-








    /*
     * Read first character of stream to check for utf-8 BOM
     */

    if (Tcl_ReadChars(chan, objPtr, 1, 0) == TCL_IO_FAILURE) {
	Tcl_CloseEx(interp, chan, 0);
	TclPrintfResult(interp,
	TclPrintfResult(interp, "couldn't read file \"%s\": %s",
		"couldn't read file \"%s\": %s",
		TclGetString(pathPtr), Tcl_PosixError(interp));
	goto end;
    }
    string = TclGetString(objPtr);

    /*
     * If first character is not a BOM, append the remaining characters.
     * Otherwise, replace them. [Bug 3466099]
     */

    if (Tcl_ReadChars(chan, objPtr, TCL_INDEX_NONE,
	    memcmp(string, "\xEF\xBB\xBF", 3)) == TCL_IO_FAILURE) {
	Tcl_CloseEx(interp, chan, 0);
	TclPrintfResult(interp,
	TclPrintfResult(interp, "couldn't read file \"%s\": %s",
		"couldn't read file \"%s\": %s",
		TclGetString(pathPtr), Tcl_PosixError(interp));
	goto end;
    }

    if (Tcl_CloseEx(interp, chan, 0) != TCL_OK) {
	goto end;
    }
1805
1806
1807
1808
1809
1810
1811
1812

1813
1814
1815
1816
1817
1818
1819
1820
1801
1802
1803
1804
1805
1806
1807

1808

1809
1810
1811
1812
1813
1814
1815







-
+
-







	 * Record information about where the error occurred.
	 */

	const char *pathString = TclGetStringFromObj(pathPtr, &length);
	int limit = 150;
	int overflow = (length > limit);

	TclAppendPrintfToErrorInfo(interp,
	TclAppendPrintfToErrorInfo(interp, "\n    (file \"%.*s%s\" line %d)",
		"\n    (file \"%.*s%s\" line %d)",
		(overflow ? limit : (int)length), pathString,
		(overflow ? "..." : ""), Tcl_GetErrorLine(interp));
    }

  end:
    Tcl_DecrRefCount(objPtr);
    return result;
2048
2049
2050
2051
2052
2053
2054
2055

2056
2057
2058
2059
2060
2061
2062
2043
2044
2045
2046
2047
2048
2049

2050
2051
2052
2053
2054
2055
2056
2057







-
+







    Tcl_Interp *interp)		/* Interpreter to set the errorCode of */
{
    const char *id, *msg;

    msg = Tcl_ErrnoMsg(errno);
    id = Tcl_ErrnoId();
    if (interp) {
	Tcl_SetErrorCode(interp, "POSIX", id, msg, (char *)NULL);
	TclSetErrorCode(interp, "POSIX", id, msg);
    }
    return msg;
}

/*
 *----------------------------------------------------------------------
 *
3198
3199
3200
3201
3202
3203
3204
3205

3206
3207
3208
3209
3210
3211
3212
3213
3193
3194
3195
3196
3197
3198
3199

3200

3201
3202
3203
3204
3205
3206
3207







-
+
-








    /*
     * Make sure the file is accessible.
     */

    if (Tcl_FSAccess(pathPtr, R_OK) != 0) {
	if (interp) {
	    TclPrintfResult(interp,
	    TclPrintfResult(interp, "couldn't load library \"%s\": %s",
		    "couldn't load library \"%s\": %s",
		    TclGetString(pathPtr), Tcl_PosixError(interp));
	}
	return TCL_ERROR;
    }

#ifdef TCL_LOAD_FROM_MEMORY
    /*
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531


4532
4533
4534
4535
4536
4537
4538
4509
4510
4511
4512
4513
4514
4515

4516
4517
4518
4519
4520
4521



4522
4523
4524
4525
4526
4527
4528
4529
4530







-






-
-
-
+
+







 *---------------------------------------------------------------------------
 */

Tcl_Obj *
Tcl_FSFileSystemInfo(
    Tcl_Obj *pathPtr)
{
    Tcl_Obj *resPtr;
    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);

    if (fsPtr == NULL) {
	return NULL;
    }

    resPtr = Tcl_NewListObj(0, NULL);
    Tcl_ListObjAppendElement(NULL, resPtr,
	    Tcl_NewStringObj(fsPtr->typeName, -1));
    Tcl_Obj *namePtr = Tcl_NewStringObj(fsPtr->typeName, -1);
    Tcl_Obj *resPtr = Tcl_NewListObj(1, &namePtr);

    if (fsPtr->filesystemPathTypeProc != NULL) {
	Tcl_Obj *typePtr = fsPtr->filesystemPathTypeProc(pathPtr);

	if (typePtr != NULL) {
	    Tcl_ListObjAppendElement(NULL, resPtr, typePtr);
	}