From 11849a320e4f522b97fcdf09ff0940496880475b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 20 Aug 2014 17:00:17 +0200 Subject: Use proper quotes everywhere --- src/libstore/local-store.cc | 128 ++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 64 deletions(-) (limited to 'src/libstore/local-store.cc') diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index ab5b60132e3f..f91a0889250a 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -212,10 +212,10 @@ void checkStoreNotSymlink() struct stat st; while (path != "/") { if (lstat(path.c_str(), &st)) - throw SysError(format("getting status of `%1%'") % path); + throw SysError(format("getting status of ‘%1%’") % path); if (S_ISLNK(st.st_mode)) throw Error(format( - "the path `%1%' is a symlink; " + "the path ‘%1%’ is a symlink; " "this is not allowed for the Nix store and its parent directories") % path); path = dirOf(path); @@ -254,22 +254,22 @@ LocalStore::LocalStore(bool reserveSpace) Path perUserDir = profilesDir + "/per-user"; createDirs(perUserDir); if (chmod(perUserDir.c_str(), 01777) == -1) - throw SysError(format("could not set permissions on `%1%' to 1777") % perUserDir); + throw SysError(format("could not set permissions on ‘%1%’ to 1777") % perUserDir); struct group * gr = getgrnam(settings.buildUsersGroup.c_str()); if (!gr) - throw Error(format("the group `%1%' specified in `build-users-group' does not exist") + throw Error(format("the group ‘%1%’ specified in ‘build-users-group’ does not exist") % settings.buildUsersGroup); struct stat st; if (stat(settings.nixStore.c_str(), &st)) - throw SysError(format("getting attributes of path `%1%'") % settings.nixStore); + throw SysError(format("getting attributes of path ‘%1%’") % settings.nixStore); if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != 01775) { if (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1) - throw SysError(format("changing ownership of path `%1%'") % settings.nixStore); + throw SysError(format("changing ownership of path ‘%1%’") % settings.nixStore); if (chmod(settings.nixStore.c_str(), 01775) == -1) - throw SysError(format("changing permissions on path `%1%'") % settings.nixStore); + throw SysError(format("changing permissions on path ‘%1%’") % settings.nixStore); } } @@ -372,7 +372,7 @@ int LocalStore::getSchema() if (pathExists(schemaPath)) { string s = readFile(schemaPath); if (!string2Int(s, curSchema)) - throw Error(format("`%1%' is corrupt") % schemaPath); + throw Error(format("‘%1%’ is corrupt") % schemaPath); } return curSchema; } @@ -381,13 +381,13 @@ int LocalStore::getSchema() void LocalStore::openDB(bool create) { if (access(settings.nixDBPath.c_str(), R_OK | W_OK)) - throw SysError(format("Nix database directory `%1%' is not writable") % settings.nixDBPath); + throw SysError(format("Nix database directory ‘%1%’ is not writable") % settings.nixDBPath); /* Open the Nix database. */ string dbPath = settings.nixDBPath + "/db.sqlite"; if (sqlite3_open_v2(dbPath.c_str(), &db.db, SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK) - throw Error(format("cannot open Nix database `%1%'") % dbPath); + throw Error(format("cannot open Nix database ‘%1%’") % dbPath); if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK) throwSQLiteError(db, "setting timeout"); @@ -511,7 +511,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct | 0444 | (st.st_mode & S_IXUSR ? 0111 : 0); if (chmod(path.c_str(), mode) == -1) - throw SysError(format("changing mode of `%1%' to %2$o") % path % mode); + throw SysError(format("changing mode of ‘%1%’ to %2$o") % path % mode); } } @@ -529,7 +529,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct #else if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1) #endif - throw SysError(format("changing modification time of `%1%'") % path); + throw SysError(format("changing modification time of ‘%1%’") % path); } } @@ -538,7 +538,7 @@ void canonicaliseTimestampAndPermissions(const Path & path) { struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path `%1%'") % path); + throw SysError(format("getting attributes of path ‘%1%’") % path); canonicaliseTimestampAndPermissions(path, st); } @@ -549,7 +549,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path `%1%'") % path); + throw SysError(format("getting attributes of path ‘%1%’") % path); /* Really make sure that the path is of a supported type. This has already been checked in dumpPath(). */ @@ -564,7 +564,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe if (fromUid != (uid_t) -1 && st.st_uid != fromUid) { assert(!S_ISDIR(st.st_mode)); if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end()) - throw BuildError(format("invalid ownership on file `%1%'") % path); + throw BuildError(format("invalid ownership on file ‘%1%’") % path); mode_t mode = st.st_mode & ~S_IFMT; assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore)); return; @@ -588,7 +588,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe if (!S_ISLNK(st.st_mode) && chown(path.c_str(), geteuid(), (gid_t) -1) == -1) #endif - throw SysError(format("changing owner of `%1%' to %2%") + throw SysError(format("changing owner of ‘%1%’ to %2%") % path % geteuid()); } @@ -608,11 +608,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino be a symlink, since we can't change its ownership. */ struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path `%1%'") % path); + throw SysError(format("getting attributes of path ‘%1%’") % path); if (st.st_uid != geteuid()) { assert(S_ISLNK(st.st_mode)); - throw Error(format("wrong ownership of top-level store path `%1%'") % path); + throw Error(format("wrong ownership of top-level store path ‘%1%’") % path); } } @@ -633,7 +633,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation & if (isFixedOutputDrv(drv)) { DerivationOutputs::const_iterator out = drv.outputs.find("out"); if (out == drv.outputs.end()) - throw Error(format("derivation `%1%' does not have an output named `out'") % drvPath); + throw Error(format("derivation ‘%1%’ does not have an output named ‘out’") % drvPath); bool recursive; HashType ht; Hash h; out->second.parseHashInfo(recursive, ht, h); @@ -641,7 +641,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation & StringPairs::const_iterator j = drv.env.find("out"); if (out->second.path != outPath || j == drv.env.end() || j->second != outPath) - throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'") + throw Error(format("derivation ‘%1%’ has incorrect output ‘%2%’, should be ‘%3%’") % drvPath % out->second.path % outPath); } @@ -658,7 +658,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation & Path outPath = makeOutputPath(i->first, h, drvName); StringPairs::const_iterator j = drv.env.find(i->first); if (i->second.path != outPath || j == drv.env.end() || j->second != outPath) - throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'") + throw Error(format("derivation ‘%1%’ has incorrect output ‘%2%’, should be ‘%3%’") % drvPath % i->second.path % outPath); } } @@ -680,7 +680,7 @@ unsigned long long LocalStore::addValidPath(const ValidPathInfo & info, bool che else stmtRegisterValidPath.bind(); // null if (sqlite3_step(stmtRegisterValidPath) != SQLITE_DONE) - throwSQLiteError(db, format("registering valid path `%1%' in database") % info.path); + throwSQLiteError(db, format("registering valid path ‘%1%’ in database") % info.path); unsigned long long id = sqlite3_last_insert_rowid(db); /* If this is a derivation, then store the derivation outputs in @@ -703,7 +703,7 @@ unsigned long long LocalStore::addValidPath(const ValidPathInfo & info, bool che stmtAddDerivationOutput.bind(i->first); stmtAddDerivationOutput.bind(i->second.path); if (sqlite3_step(stmtAddDerivationOutput) != SQLITE_DONE) - throwSQLiteError(db, format("adding derivation output for `%1%' in database") % info.path); + throwSQLiteError(db, format("adding derivation output for ‘%1%’ in database") % info.path); } } @@ -728,7 +728,7 @@ void LocalStore::registerFailedPath(const Path & path) stmtRegisterFailedPath.bind(path); stmtRegisterFailedPath.bind(time(0)); if (sqlite3_step(stmtRegisterFailedPath) != SQLITE_DONE) - throwSQLiteError(db, format("registering failed path `%1%'") % path); + throwSQLiteError(db, format("registering failed path ‘%1%’") % path); } end_retry_sqlite; } @@ -776,7 +776,7 @@ void LocalStore::clearFailedPaths(const PathSet & paths) SQLiteStmtUse use(stmtClearFailedPath); stmtClearFailedPath.bind(*i); if (sqlite3_step(stmtClearFailedPath) != SQLITE_DONE) - throwSQLiteError(db, format("clearing failed path `%1%' in database") % *i); + throwSQLiteError(db, format("clearing failed path ‘%1%’ in database") % *i); } txn.commit(); @@ -788,11 +788,11 @@ Hash parseHashField(const Path & path, const string & s) { string::size_type colon = s.find(':'); if (colon == string::npos) - throw Error(format("corrupt hash `%1%' in valid-path entry for `%2%'") + throw Error(format("corrupt hash ‘%1%’ in valid-path entry for ‘%2%’") % s % path); HashType ht = parseHashType(string(s, 0, colon)); if (ht == htUnknown) - throw Error(format("unknown hash type `%1%' in valid-path entry for `%2%'") + throw Error(format("unknown hash type ‘%1%’ in valid-path entry for ‘%2%’") % string(s, 0, colon) % path); return parseHash(ht, string(s, colon + 1)); } @@ -813,7 +813,7 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path) stmtQueryPathInfo.bind(path); int r = sqlite3_step(stmtQueryPathInfo); - if (r == SQLITE_DONE) throw Error(format("path `%1%' is not valid") % path); + if (r == SQLITE_DONE) throw Error(format("path ‘%1%’ is not valid") % path); if (r != SQLITE_ROW) throwSQLiteError(db, "querying path in database"); info.id = sqlite3_column_int(stmtQueryPathInfo, 0); @@ -842,7 +842,7 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path) } if (r != SQLITE_DONE) - throwSQLiteError(db, format("error getting references of `%1%'") % path); + throwSQLiteError(db, format("error getting references of ‘%1%’") % path); return info; } end_retry_sqlite; @@ -861,7 +861,7 @@ void LocalStore::updatePathInfo(const ValidPathInfo & info) stmtUpdatePathInfo.bind("sha256:" + printHash(info.hash)); stmtUpdatePathInfo.bind(info.path); if (sqlite3_step(stmtUpdatePathInfo) != SQLITE_DONE) - throwSQLiteError(db, format("updating info of path `%1%' in database") % info.path); + throwSQLiteError(db, format("updating info of path ‘%1%’ in database") % info.path); } @@ -871,7 +871,7 @@ unsigned long long LocalStore::queryValidPathId(const Path & path) stmtQueryPathInfo.bind(path); int res = sqlite3_step(stmtQueryPathInfo); if (res == SQLITE_ROW) return sqlite3_column_int(stmtQueryPathInfo, 0); - if (res == SQLITE_DONE) throw Error(format("path `%1%' is not valid") % path); + if (res == SQLITE_DONE) throw Error(format("path ‘%1%’ is not valid") % path); throwSQLiteError(db, "querying path in database"); } @@ -950,7 +950,7 @@ void LocalStore::queryReferrers_(const Path & path, PathSet & referrers) } if (r != SQLITE_DONE) - throwSQLiteError(db, format("error getting references of `%1%'") % path); + throwSQLiteError(db, format("error getting references of ‘%1%’") % path); } @@ -986,7 +986,7 @@ PathSet LocalStore::queryValidDerivers(const Path & path) } if (r != SQLITE_DONE) - throwSQLiteError(db, format("error getting valid derivers of `%1%'") % path); + throwSQLiteError(db, format("error getting valid derivers of ‘%1%’") % path); return derivers; } end_retry_sqlite; @@ -1008,7 +1008,7 @@ PathSet LocalStore::queryDerivationOutputs(const Path & path) } if (r != SQLITE_DONE) - throwSQLiteError(db, format("error getting outputs of `%1%'") % path); + throwSQLiteError(db, format("error getting outputs of ‘%1%’") % path); return outputs; } end_retry_sqlite; @@ -1030,7 +1030,7 @@ StringSet LocalStore::queryDerivationOutputNames(const Path & path) } if (r != SQLITE_DONE) - throwSQLiteError(db, format("error getting output names of `%1%'") % path); + throwSQLiteError(db, format("error getting output names of ‘%1%’") % path); return outputNames; } end_retry_sqlite; @@ -1073,7 +1073,7 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & { if (run.disabled || run.pid != -1) return; - debug(format("starting substituter program `%1%'") % substituter); + debug(format("starting substituter program ‘%1%’") % substituter); Pipe toPipe, fromPipe, errorPipe; @@ -1091,7 +1091,7 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & if (dup2(errorPipe.writeSide, STDERR_FILENO) == -1) throw SysError("dupping stderr"); execl(substituter.c_str(), substituter.c_str(), "--query", NULL); - throw SysError(format("executing `%1%'") % substituter); + throw SysError(format("executing ‘%1%’") % substituter); }); run.program = baseNameOf(substituter); @@ -1150,7 +1150,7 @@ string LocalStore::getLineFromSubstituter(RunningSubstituter & run) if (errno == EINTR) continue; throw SysError("reading from substituter's stderr"); } - if (n == 0) throw EndOfFile(format("substituter `%1%' died unexpectedly") % run.program); + if (n == 0) throw EndOfFile(format("substituter ‘%1%’ died unexpectedly") % run.program); err.append(buf, n); string::size_type p; while ((p = err.find('\n')) != string::npos) { @@ -1227,7 +1227,7 @@ void LocalStore::querySubstitutablePathInfos(const Path & substituter, Path path = getLineFromSubstituter(run); if (path == "") break; if (paths.find(path) == paths.end()) - throw Error(format("got unexpected path `%1%' from substituter") % path); + throw Error(format("got unexpected path ‘%1%’ from substituter") % path); paths.erase(path); SubstitutablePathInfo & info(infos[path]); info.deriver = getLineFromSubstituter(run); @@ -1321,7 +1321,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos) there are no referrers. */ void LocalStore::invalidatePath(const Path & path) { - debug(format("invalidating path `%1%'") % path); + debug(format("invalidating path ‘%1%’") % path); drvHashes.erase(path); @@ -1330,7 +1330,7 @@ void LocalStore::invalidatePath(const Path & path) stmtInvalidatePath.bind(path); if (sqlite3_step(stmtInvalidatePath) != SQLITE_DONE) - throwSQLiteError(db, format("invalidating path `%1%' in database") % path); + throwSQLiteError(db, format("invalidating path ‘%1%’ in database") % path); /* Note that the foreign key constraints on the Refs table take care of deleting the references entries for `path'. */ @@ -1396,7 +1396,7 @@ Path LocalStore::addToStore(const Path & _srcPath, bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) { Path srcPath(absPath(_srcPath)); - debug(format("adding `%1%' to the store") % srcPath); + debug(format("adding ‘%1%’ to the store") % srcPath); /* Read the whole path into memory. This is not a very scalable method for very large paths, but `copyPath' is mainly used for @@ -1475,9 +1475,9 @@ static void checkSecrecy(const Path & path) { struct stat st; if (stat(path.c_str(), &st)) - throw SysError(format("getting status of `%1%'") % path); + throw SysError(format("getting status of ‘%1%’") % path); if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) - throw Error(format("file `%1%' should be secret (inaccessible to everybody else)!") % path); + throw Error(format("file ‘%1%’ should be secret (inaccessible to everybody else)!") % path); } @@ -1486,10 +1486,10 @@ void LocalStore::exportPath(const Path & path, bool sign, { assertStorePath(path); - printMsg(lvlInfo, format("exporting path `%1%'") % path); + printMsg(lvlInfo, format("exporting path ‘%1%’") % path); if (!isValidPath(path)) - throw Error(format("path `%1%' is not valid") % path); + throw Error(format("path ‘%1%’ is not valid") % path); HashAndWriteSink hashAndWriteSink(sink); @@ -1501,7 +1501,7 @@ void LocalStore::exportPath(const Path & path, bool sign, Hash hash = hashAndWriteSink.currentHash(); Hash storedHash = queryPathHash(path); if (hash != storedHash && storedHash != Hash(storedHash.type)) - throw Error(format("hash of path `%1%' has changed from `%2%' to `%3%'!") % path + throw Error(format("hash of path ‘%1%’ has changed from ‘%2%’ to ‘%3%’!") % path % printHash(storedHash) % printHash(hash)); writeInt(EXPORT_MAGIC, hashAndWriteSink); @@ -1608,7 +1608,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source) bool haveSignature = readInt(hashAndReadSource) == 1; if (requireSignature && !haveSignature) - throw Error(format("imported archive of `%1%' lacks a signature") % dstPath); + throw Error(format("imported archive of ‘%1%’ lacks a signature") % dstPath); if (haveSignature) { string signature = readString(hashAndReadSource); @@ -1659,7 +1659,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source) if (pathExists(dstPath)) deletePath(dstPath); if (rename(unpacked.c_str(), dstPath.c_str()) == -1) - throw SysError(format("cannot move `%1%' to `%2%'") + throw SysError(format("cannot move ‘%1%’ to ‘%2%’") % unpacked % dstPath); canonicalisePathMetaData(dstPath, -1); @@ -1692,7 +1692,7 @@ Paths LocalStore::importPaths(bool requireSignature, Source & source) while (true) { unsigned long long n = readLongLong(source); if (n == 0) break; - if (n != 1) throw Error("input doesn't look like something created by `nix-store --export'"); + if (n != 1) throw Error("input doesn't look like something created by ‘nix-store --export’"); res.push_back(importPath(requireSignature, source)); } return res; @@ -1710,7 +1710,7 @@ void LocalStore::invalidatePathChecked(const Path & path) PathSet referrers; queryReferrers_(path, referrers); referrers.erase(path); /* ignore self-references */ if (!referrers.empty()) - throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%") + throw PathInUse(format("cannot delete path ‘%1%’ because it is in use by %2%") % path % showPaths(referrers)); invalidatePath(path); } @@ -1755,12 +1755,12 @@ bool LocalStore::verifyStore(bool checkContents, bool repair) ValidPathInfo info = queryPathInfo(*i); /* Check the content hash (optionally - slow). */ - printMsg(lvlTalkative, format("checking contents of `%1%'") % *i); + printMsg(lvlTalkative, format("checking contents of ‘%1%’") % *i); HashResult current = hashPath(info.hash.type, *i); if (info.hash != nullHash && info.hash != current.first) { - printMsg(lvlError, format("path `%1%' was modified! " - "expected hash `%2%', got `%3%'") + printMsg(lvlError, format("path ‘%1%’ was modified! " + "expected hash ‘%2%’, got ‘%3%’") % *i % printHash(info.hash) % printHash(current.first)); if (repair) repairPath(*i); else errors = true; } else { @@ -1769,14 +1769,14 @@ bool LocalStore::verifyStore(bool checkContents, bool repair) /* Fill in missing hashes. */ if (info.hash == nullHash) { - printMsg(lvlError, format("fixing missing hash on `%1%'") % *i); + printMsg(lvlError, format("fixing missing hash on ‘%1%’") % *i); info.hash = current.first; update = true; } /* Fill in missing narSize fields (from old stores). */ if (info.narSize == 0) { - printMsg(lvlError, format("updating size field on `%1%' to %2%") % *i % current.second); + printMsg(lvlError, format("updating size field on ‘%1%’ to %2%") % *i % current.second); info.narSize = current.second; update = true; } @@ -1810,7 +1810,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store, done.insert(path); if (!isStorePath(path)) { - printMsg(lvlError, format("path `%1%' is not in the Nix store") % path); + printMsg(lvlError, format("path ‘%1%’ is not in the Nix store") % path); invalidatePath(path); return; } @@ -1828,10 +1828,10 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store, } if (canInvalidate) { - printMsg(lvlError, format("path `%1%' disappeared, removing from database...") % path); + printMsg(lvlError, format("path ‘%1%’ disappeared, removing from database...") % path); invalidatePath(path); } else { - printMsg(lvlError, format("path `%1%' disappeared, but it still has valid referrers!") % path); + printMsg(lvlError, format("path ‘%1%’ disappeared, but it still has valid referrers!") % path); if (repair) try { repairPath(path); @@ -1853,7 +1853,7 @@ bool LocalStore::pathContentsGood(const Path & path) { std::map::iterator i = pathContentsGoodCache.find(path); if (i != pathContentsGoodCache.end()) return i->second; - printMsg(lvlInfo, format("checking path `%1%'...") % path); + printMsg(lvlInfo, format("checking path ‘%1%’...") % path); ValidPathInfo info = queryPathInfo(path); bool res; if (!pathExists(path)) @@ -1864,7 +1864,7 @@ bool LocalStore::pathContentsGood(const Path & path) res = info.hash == nullHash || info.hash == current.first; } pathContentsGoodCache[path] = res; - if (!res) printMsg(lvlError, format("path `%1%' is corrupted or missing!") % path); + if (!res) printMsg(lvlError, format("path ‘%1%’ is corrupted or missing!") % path); return res; } @@ -1895,7 +1895,7 @@ ValidPathInfo LocalStore::queryPathInfoOld(const Path & path) string baseName = baseNameOf(path); Path infoFile = (format("%1%/info/%2%") % settings.nixDBPath % baseName).str(); if (!pathExists(infoFile)) - throw Error(format("path `%1%' is not valid") % path); + throw Error(format("path ‘%1%’ is not valid") % path); string info = readFile(infoFile); /* Parse it. */ @@ -1904,7 +1904,7 @@ ValidPathInfo LocalStore::queryPathInfoOld(const Path & path) foreach (Strings::iterator, i, lines) { string::size_type p = i->find(':'); if (p == string::npos) - throw Error(format("corrupt line in `%1%': %2%") % infoFile % *i); + throw Error(format("corrupt line in ‘%1%’: %2%") % infoFile % *i); string name(*i, 0, p); string value(*i, p + 2); if (name == "References") { @@ -1978,7 +1978,7 @@ static void makeMutable(const Path & path) AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW); if (fd == -1) { if (errno == ELOOP) return; // it's a symlink - throw SysError(format("opening file `%1%'") % path); + throw SysError(format("opening file ‘%1%’") % path); } unsigned int flags = 0, old; -- cgit 1.4.1