From adfb9b0501e005d10aaec727fa56ed5beff0d7d0 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Mon, 17 Sep 2007 07:02:56 +0000 Subject: [PATCH] Add a parameter to specify the size of the output buffer passed to xGetTempname() and xFullPathname(). This, and the previous commit, are changes to the public vfs API introduced in 3.5.0. (CVS 4433) FossilOrigin-Name: 8b29f5fbfc723cdf67cf3410cd01f7c17ea39a4b --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/btree.c | 7 ++++--- src/os.c | 13 +++++++++---- src/os.h | 4 ++-- src/os_unix.c | 10 ++++++++-- src/os_win.c | 9 +++++---- src/pager.c | 9 +++++---- src/sqlite.h.in | 13 +++++++++---- src/test6.c | 13 +++++++++---- src/test_async.c | 7 ++++--- src/test_onefile.c | 17 +++++++++++------ 12 files changed, 82 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index a385e33a9b..ff62c83ded 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\snames\sof\sxGetTempName\sand\ssqlite3OsGetTempName\sto\sxGetTempname.\sTo\sbe\sconsistent\swith\sxFullPathname\sand\ssqlite3OsFullPathname.\s(CVS\s4432) -D 2007-09-17T06:06:39 +C Add\sa\sparameter\sto\sspecify\sthe\ssize\sof\sthe\soutput\sbuffer\spassed\sto\sxGetTempname()\sand\sxFullPathname().\sThis,\sand\sthe\sprevious\scommit,\sare\schanges\sto\sthe\spublic\svfs\sAPI\sintroduced\sin\s3.5.0.\s(CVS\s4433) +D 2007-09-17T07:02:57 F Makefile.in cbfb898945536a8f9ea8b897e1586dd1fdbcc5db F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -81,7 +81,7 @@ F src/analyze.c 49b4bd45eb286d833793ed6bf72355a5c1974865 F src/attach.c 02fd8779270b1df1c63e7ba6e6655b960fa0f3d5 F src/auth.c d41c34f3150b3b8248d364770ef922bbcefbff82 F src/btmutex.c 442be6f068d77ca9ffd69899cf0a3943c244548c -F src/btree.c ac94b8a9b0fb042b0284c0db5575740d27872558 +F src/btree.c ed7c4825b0d30a8a77c43b468009cfa8a31c967a F src/btree.h d0736ebca4b6eafbdd823c46a8de574cea078211 F src/btreeInt.h 4330c19b8314545fdb209cc77e2a57f6a5290e9c F src/build.c 94d0d6dfd1e706c480903fbdda2e77466f21b898 @@ -109,18 +109,18 @@ F src/mutex.h 079fa6fe9da18ceb89e79012c010594c6672addb F src/mutex_os2.c d47e9bd495583dd31263d8fe55160a31eb600a3c F src/mutex_unix.c ff77650261a245035b79c5c8a174f4e05d3cae8a F src/mutex_w32.c d2c56fb81aca10af1577bdae2a4083eb2505f8ee -F src/os.c 521a698a82f1fbd4f3717a8da72db6d819ff0a0c -F src/os.h 143d122c04ef6cb0c914b97749a6aadd91a18a73 +F src/os.c 3b66834a5853ddaa83dfd6c146be9e4fc1864b98 +F src/os.h 4c880cf67437f323cd0c3ab2154f1d76babc12d3 F src/os_common.h 98862f120ca6bf7a48ce8b16f158b77d00bc9d2f F src/os_os2.c 5b5f42180c5961b9d207748fda8f9aa0e70569c8 F src/os_os2.h c3f7d0af7e3453d1d7aa81b06c0a56f5a226530b F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 -F src/os_unix.c 2c6a5507cd2c6522db9e70ca83db1ac72816ffd4 +F src/os_unix.c 8d4f5e952adcbd04276aa07bf8fc9865f3ba3bd3 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e -F src/os_win.c 697dd7ad0fcfca7911542ab0bc5a1834c705a9e4 +F src/os_win.c e638300494c492a460c76561a345dae1671c30f0 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c f38ad4de4dcc1b4083de1f9fd494173f5e8afadc +F src/pager.c d246d888bbdbb97321238f5f71d2f6727b2cc9d8 F src/pager.h d783e7f184afdc33adff37ba58d4e029bd8793b3 F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590 F src/pragma.c 363e548dafb52327face8d99757ab56a7b1c1b26 @@ -130,7 +130,7 @@ F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da F src/select.c 4706a6115da1bdc09a2be5991168a6cc2c0df267 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 82089379833e361ba8a2ae65316a2173785300c0 -F src/sqlite.h.in 1b651cd409f3aed2e78e47f551b4a92f47dd57f4 +F src/sqlite.h.in 26b53ebd71d051bdefb6ba326f6742747c188cb7 F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb F src/sqliteInt.h bb126b074352ef0ee20399883172161baf5eead2 F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12 @@ -141,11 +141,11 @@ F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789 F src/test3.c 73c1fd55d1ece61f295a6b9204fd97a139de86ae F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071 F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4 -F src/test6.c 0f3894c2fd13d03e9903a88820d318123dbeb536 +F src/test6.c a9fc983d32d6f262eab300d742e49ff239b0bdbd F src/test7.c ae24ba989ecc2dc600d93c6311191b5d0c596f2b F src/test8.c f113aa3723a52113d0fa7c28155ecd37e7e04077 F src/test9.c b46c8fe02ac7cca1a7316436d8d38d50c66f4b2f -F src/test_async.c 70eb7a4366c3410f558745f4a19b38bcfb9992a8 +F src/test_async.c c5ea222c2bb0c3c33ab910d1b82622655dd50684 F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436 F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c F src/test_config.c 6fb459214b27952b143f45e35200d94096d54cc6 @@ -153,7 +153,7 @@ F src/test_hexio.c 94a1efec4b19311eb7c4dc40e8496a3d8eadf18a F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8 F src/test_malloc.c c34e7696dc4a5150c82452be28b87c7e38ba15ad F src/test_md5.c 34599caee5b1c73dcf86ca31f55846fab8c19ef7 -F src/test_onefile.c 22260e8de36d050f263088ad33bba107191d9e16 +F src/test_onefile.c d877baba46837587345933376c00c656f58d6fb6 F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f F src/test_server.c a6ece6c835e7eae835054124e09e947e422b1ac5 F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59 @@ -580,7 +580,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 8cc51e0a817115c4eb667f7257a3f5a4a39d0a4a -R b3d078ae916fc494191428062b49abff +P ad3687b16e9420d8bbaa3a645aaf803813b36061 +R 47f0785310596c6f237d4e202feaacc9 U danielk1977 -Z dc8a2b824ad51bca0b771b0a8a2897ba +Z 83729562c61099b61142e11a997b9c6e diff --git a/manifest.uuid b/manifest.uuid index 68f710d845..a79e929c5d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad3687b16e9420d8bbaa3a645aaf803813b36061 \ No newline at end of file +8b29f5fbfc723cdf67cf3410cd01f7c17ea39a4b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4c38882ea2..99147fb84d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.426 2007/09/12 17:01:45 danielk1977 Exp $ +** $Id: btree.c,v 1.427 2007/09/17 07:02:57 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -1158,7 +1158,8 @@ int sqlite3BtreeOpen( && zFilename && zFilename[0] ){ if( sqlite3SharedCacheEnabled ){ - char *zFullPathname = (char *)sqlite3_malloc(pVfs->mxPathname); + int nFullPathname = pVfs->mxPathname+1; + char *zFullPathname = (char *)sqlite3_malloc(nFullPathname); sqlite3_mutex *mutexShared; p->sharable = 1; if( pSqlite ){ @@ -1168,7 +1169,7 @@ int sqlite3BtreeOpen( sqlite3_free(p); return SQLITE_NOMEM; } - sqlite3OsFullPathname(pVfs, zFilename, zFullPathname); + sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutexShared); for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){ diff --git a/src/os.c b/src/os.c index bfc7e99bbc..28de37da01 100644 --- a/src/os.c +++ b/src/os.c @@ -107,11 +107,16 @@ int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ return pVfs->xAccess(pVfs, zPath, flags); } -int sqlite3OsGetTempname(sqlite3_vfs *pVfs, char *zBufOut){ - return pVfs->xGetTempname(pVfs, zBufOut); +int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){ + return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); } -int sqlite3OsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zPathOut){ - return pVfs->xFullPathname(pVfs, zPath, zPathOut); +int sqlite3OsFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nPathOut, + char *zPathOut +){ + return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); } void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ return pVfs->xDlOpen(pVfs, zPath); diff --git a/src/os.h b/src/os.h index d5edcaef8d..554952df00 100644 --- a/src/os.h +++ b/src/os.h @@ -250,8 +250,8 @@ int sqlite3OsDeviceCharacteristics(sqlite3_file *id); int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); int sqlite3OsDelete(sqlite3_vfs *, const char *, int); int sqlite3OsAccess(sqlite3_vfs *, const char *, int); -int sqlite3OsGetTempname(sqlite3_vfs *, char *); -int sqlite3OsFullPathname(sqlite3_vfs *, const char *, char *); +int sqlite3OsGetTempname(sqlite3_vfs *, int, char *); +int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); void sqlite3OsDlError(sqlite3_vfs *, int, char *); void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *); diff --git a/src/os_unix.c b/src/os_unix.c index 30e2cbb26f..2732f58e90 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2474,7 +2474,7 @@ static int unixAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ ** by the calling process and must be big enough to hold at least ** pVfs->mxPathname bytes. */ -static int unixGetTempname(sqlite3_vfs *pVfs, char *zBuf){ +static int unixGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ static const char *azDirs[] = { 0, "/var/tmp", @@ -2507,6 +2507,7 @@ static int unixGetTempname(sqlite3_vfs *pVfs, char *zBuf){ } do{ assert( pVfs->mxPathname==MAX_PATHNAME ); + assert( nBuf>=MAX_PATHNAME ); sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); sqlite3Randomness(15, &zBuf[j]); @@ -2528,7 +2529,12 @@ static int unixGetTempname(sqlite3_vfs *pVfs, char *zBuf){ ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ -static int unixFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zOut){ +static int unixFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zPath, /* Possibly relative input path */ + int nOut, /* Size of output buffer in bytes */ + char *zOut /* Output buffer */ +){ /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this diff --git a/src/os_win.c b/src/os_win.c index f140054f3d..4eac10b867 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1267,7 +1267,7 @@ static int winAccess( ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at pVfs->mxPathname characters. */ -static int winGetTempname(sqlite3_vfs *pVfs, char *zBuf){ +static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -1319,9 +1319,10 @@ static int winGetTempname(sqlite3_vfs *pVfs, char *zBuf){ ** bytes in size. */ static int winFullPathname( - sqlite3_vfs *pVfs, - const char *zRelative, - char *zFull + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ ){ #if defined(__CYGWIN__) diff --git a/src/pager.c b/src/pager.c index ddd9236917..c442365e4b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.389 2007/09/17 06:06:39 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.390 2007/09/17 07:02:57 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -2039,7 +2039,8 @@ int sqlite3PagerOpen( *ppPager = 0; /* Compute the full pathname */ - zPathname = sqlite3_malloc(pVfs->mxPathname+1); + nPathname = pVfs->mxPathname+1; + zPathname = sqlite3_malloc(nPathname); if( zPathname==0 ){ return SQLITE_NOMEM; } @@ -2051,10 +2052,10 @@ int sqlite3PagerOpen( }else #endif { - rc = sqlite3OsFullPathname(pVfs, zFilename, zPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); } }else{ - rc = sqlite3OsGetTempname(pVfs, zPathname); + rc = sqlite3OsGetTempname(pVfs, nPathname, zPathname); } if( rc!=SQLITE_OK ){ sqlite3_free(zPathname); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b9d96c231d..175dbfdc77 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -30,7 +30,7 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.260 2007/09/17 06:06:39 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.261 2007/09/17 07:02:57 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -662,7 +662,12 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** directory. ** ** SQLite will always allocate at least mxPathname+1 byte for -** the output buffers for xGetTempname and xFullPathname. +** the output buffers for xGetTempname and xFullPathname. The exact +** size of the output buffer is also passed as a parameter to both +** methods. If the output buffer is not large enough, SQLITE_CANTOPEN +** should be returned. As this is handled as a fatal error by SQLite, +** vfs implementations should endevour to prevent this by setting +** mxPathname to a sufficiently large value. ** ** The xRandomness(), xSleep(), and xCurrentTime() interfaces ** are not strictly a part of the filesystem, but they are @@ -687,8 +692,8 @@ struct sqlite3_vfs { int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); - int (*xGetTempname)(sqlite3_vfs*, char *zOut); - int (*xFullPathname)(sqlite3_vfs*, const char *zName, char *zOut); + int (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); diff --git a/src/test6.c b/src/test6.c index 4251fc9322..c0456ca865 100644 --- a/src/test6.c +++ b/src/test6.c @@ -568,13 +568,18 @@ static int cfAccess(sqlite3_vfs *pCfVfs, const char *zPath, int flags){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xAccess(pVfs, zPath, flags); } -static int cfGetTempname(sqlite3_vfs *pCfVfs, char *zBufOut){ +static int cfGetTempname(sqlite3_vfs *pCfVfs, int nBufOut, char *zBufOut){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; - return pVfs->xGetTempname(pVfs, zBufOut); + return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); } -static int cfFullPathname(sqlite3_vfs *pCfVfs, const char *zPath, char *zPathOut){ +static int cfFullPathname( + sqlite3_vfs *pCfVfs, + const char *zPath, + int nPathOut, + char *zPathOut +){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; - return pVfs->xFullPathname(pVfs, zPath, zPathOut); + return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); } static void *cfDlOpen(sqlite3_vfs *pCfVfs, const char *zPath){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; diff --git a/src/test_async.c b/src/test_async.c index ee8d80c952..b01822371a 100644 --- a/src/test_async.c +++ b/src/test_async.c @@ -990,9 +990,9 @@ static int asyncAccess(sqlite3_vfs *pAsyncVfs, const char *zName, int flags){ return ret; } -static int asyncGetTempname(sqlite3_vfs *pAsyncVfs, char *zBufOut){ +static int asyncGetTempname(sqlite3_vfs *pAsyncVfs, int nBufOut, char *zBufOut){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - return pVfs->xGetTempname(pVfs, zBufOut); + return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); } /* @@ -1001,11 +1001,12 @@ static int asyncGetTempname(sqlite3_vfs *pAsyncVfs, char *zBufOut){ static int asyncFullPathname( sqlite3_vfs *pAsyncVfs, const char *zPath, + int nPathOut, char *zPathOut ){ int rc; sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - rc = sqlite3OsFullPathname(pVfs, zPath, zPathOut); + rc = sqlite3OsFullPathname(pVfs, zPath, nPathOut, zPathOut); /* Because of the way intra-process file locking works, this backend ** needs to return a canonical path. The following block assumes the diff --git a/src/test_onefile.c b/src/test_onefile.c index 700dfcd354..d7e19de64d 100644 --- a/src/test_onefile.c +++ b/src/test_onefile.c @@ -163,8 +163,8 @@ static int tmpDeviceCharacteristics(sqlite3_file*); static int fsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); static int fsDelete(sqlite3_vfs*, const char *zName, int syncDir); static int fsAccess(sqlite3_vfs*, const char *zName, int flags); -static int fsGetTempname(sqlite3_vfs*, char *zOut); -static int fsFullPathname(sqlite3_vfs*, const char *zName, char *zOut); +static int fsGetTempname(sqlite3_vfs*, int nOut, char *zOut); +static int fsFullPathname(sqlite3_vfs*, const char *zName, int nOut,char *zOut); static void *fsDlOpen(sqlite3_vfs*, const char *zFilename); static void fsDlError(sqlite3_vfs*, int nByte, char *zErrMsg); static void *fsDlSym(sqlite3_vfs*,void*, const char *zSymbol); @@ -726,9 +726,9 @@ static int fsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ ** temporary file. zBufOut is guaranteed to point to a buffer of ** at least (FS_MAX_PATHNAME+1) bytes. */ -static int fsGetTempname(sqlite3_vfs *pVfs, char *zBufOut){ +static int fsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){ sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; - return pParent->xGetTempname(pParent, zBufOut); + return pParent->xGetTempname(pParent, nBufOut, zBufOut); } /* @@ -736,9 +736,14 @@ static int fsGetTempname(sqlite3_vfs *pVfs, char *zBufOut){ ** to the pathname in zPath. zOut is guaranteed to point to a buffer ** of at least (FS_MAX_PATHNAME+1) bytes. */ -static int fsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zOut){ +static int fsFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zPath, /* Possibly relative input path */ + int nOut, /* Size of output buffer in bytes */ + char *zOut /* Output buffer */ +){ sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; - return pParent->xFullPathname(pParent, zPath, zOut); + return pParent->xFullPathname(pParent, zPath, nOut, zOut); } /*