// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT. //go:build (linux && amd64) || (linux && ppc64le) || (linux && s390x) package sqlite3 import ( "unsafe" "modernc.org/libc" ) type Tblksize_t = int64 // C documentation // // /* // ** This function is called to handle the SQLITE_FCNTL_SIZE_HINT // ** file-control operation. Enlarge the database to nBytes in size // ** (rounded up to the next chunk-size). If the database is already // ** nBytes or larger, this routine is a no-op. // */ func _fcntlSizeHint(tls *libc.TLS, pFile uintptr, nByte Ti64) (r int32) { bp := tls.Alloc(144) defer tls.Free(144) var iWrite, nSize Ti64 var nBlk, nWrite, rc int32 var _ /* buf at bp+0 */ Tstat _, _, _, _, _ = iWrite, nBlk, nSize, nWrite, rc if (*TunixFile)(unsafe.Pointer(pFile)).FszChunk > 0 { /* Used to hold return values of fstat() */ if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, bp) != 0 { return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)< int64((**(**Tstat)(__ccgo_up(bp))).Fst_size) { /* If the OS does not have posix_fallocate(), fake it. Write a ** single byte to the last byte in each block that falls entirely ** within the extended region. Then, if required, a single byte ** at offset (nSize-1), to set the size of the file correctly. ** This is a similar technique to that used by glibc on systems ** that do not have a real fallocate() call. */ nBlk = int32((**(**Tstat)(__ccgo_up(bp))).Fst_blksize) /* File-system block size */ nWrite = 0 /* Next offset to write to */ iWrite = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size/int64(nBlk)*int64(nBlk) + int64(nBlk) - int64(1)) for { if !(iWrite < nSize+int64(nBlk)-int64(1)) { break } if iWrite >= nSize { iWrite = nSize - int64(1) } nWrite = _seekAndWrite(tls, pFile, iWrite, __ccgo_ts+1704, int32(1)) if nWrite != int32(1) { return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(3)< 0 && nByte > (*TunixFile)(unsafe.Pointer(pFile)).FmmapSize { if (*TunixFile)(unsafe.Pointer(pFile)).FszChunk <= 0 { if _robust_ftruncate(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, nByte) != 0 { _storeLastErrno(tls, pFile, **(**int32)(__ccgo_up(libc.X__errno_location(tls)))) return _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(6)< 0 { return SQLITE_OK } if nMap < 0 { /* Low-level file information */ if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFd)).Fh, bp) != 0 { return libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)< (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax { nMap = (*TunixFile)(unsafe.Pointer(pFd)).FmmapSizeMax } if nMap != (*TunixFile)(unsafe.Pointer(pFd)).FmmapSize { _unixRemapfile(tls, pFd, nMap) } return SQLITE_OK } // C documentation // // /* // ** Open a shared-memory area associated with open database file pDbFd. // ** This particular implementation uses mmapped files. // ** // ** The file used to implement shared-memory is in the same directory // ** as the open database file and has the same name as the open database // ** file with the "-shm" suffix added. For example, if the database file // ** is "/home/user1/config.db" then the file that is created and mmapped // ** for shared memory will be called "/home/user1/config.db-shm". // ** // ** Another approach to is to use files in /dev/shm or /dev/tmp or an // ** some other tmpfs mount. But if a file in a different directory // ** from the database file is used, then differing access permissions // ** or a chroot() might cause two different processes on the same // ** database to end up using different files for shared memory - // ** meaning that their memory would not really be shared - resulting // ** in database corruption. Nevertheless, this tmpfs file usage // ** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" // ** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time // ** option results in an incompatible build of SQLite; builds of SQLite // ** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the // ** same database file at the same time, database corruption will likely // ** result. The SQLITE_SHM_DIRECTORY compile-time option is considered // ** "unsupported" and may go away in a future SQLite release. // ** // ** When opening a new shared-memory file, if no other instances of that // ** file are currently open, in this process or in other processes, then // ** the file must be truncated to zero length or have its header cleared. // ** // ** If the original database file (pDbFd) is using the "unix-excl" VFS // ** that means that an exclusive lock is held on the database file and // ** that no other processes are able to read or write the database. In // ** that case, we do not really need shared memory. No shared memory // ** file is created. The shared memory will be simulated with heap memory. // */ func _unixOpenSharedMemory(tls *libc.TLS, pDbFd uintptr) (r int32) { bp := tls.Alloc(160) defer tls.Free(160) var nShmFilename, rc int32 var p, pInode, pShmNode, zBasePath, zShm, v1 uintptr var _ /* sStat at bp+0 */ Tstat _, _, _, _, _, _, _, _ = nShmFilename, p, pInode, pShmNode, rc, zBasePath, zShm, v1 p = uintptr(0) /* The underlying mmapped file */ rc = SQLITE_OK /* Size of the SHM filename in bytes */ /* Allocate space for the new unixShm object. */ p = Xsqlite3_malloc64(tls, uint64(24)) if p == uintptr(0) { return int32(SQLITE_NOMEM) } libc.Xmemset(tls, p, 0, uint64(24)) /* Check to see if a unixShmNode object already exists. Reuse an existing ** one if present. Create a new one if necessary. */ _unixEnterMutex(tls) pInode = (*TunixFile)(unsafe.Pointer(pDbFd)).FpInode pShmNode = (*TunixInodeInfo)(unsafe.Pointer(pInode)).FpShmNode if pShmNode == uintptr(0) { /* fstat() info for database file */ zBasePath = (*TunixFile)(unsafe.Pointer(pDbFd)).FzPath /* Call fstat() to figure out the permissions on the database file. If ** a new *-shm file is created, an attempt will be made to create it ** with the same permissions. */ if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pDbFd)).Fh, bp) != 0 { rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(7)<pFirst. This must be done while holding the ** pShmNode->pShmMutex. */ Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex) (*TunixShm)(unsafe.Pointer(p)).FpNext = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpFirst (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpFirst = p Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex) return rc /* Jump here on any error */ goto shm_open_err shm_open_err: ; _unixShmPurge(tls, pDbFd) /* This call frees pShmNode if required */ Xsqlite3_free(tls, p) _unixLeaveMutex(tls) return rc } // C documentation // // /* // ** This function is called to obtain a pointer to region iRegion of the // ** shared-memory associated with the database file fd. Shared-memory regions // ** are numbered starting from zero. Each shared-memory region is szRegion // ** bytes in size. // ** // ** If an error occurs, an error code is returned and *pp is set to NULL. // ** // ** Otherwise, if the bExtend parameter is 0 and the requested shared-memory // ** region has not been allocated (by any client, including one running in a // ** separate process), then *pp is set to NULL and SQLITE_OK returned. If // ** bExtend is non-zero and the requested shared-memory region has not yet // ** been allocated, it is allocated by this function. // ** // ** If the shared-memory region has already been allocated or is allocated by // ** this call as described above, then it is mapped into this processes // ** address space (if it is not already), *pp is set to point to the mapped // ** memory and SQLITE_OK returned. // */ func _unixShmMap(tls *libc.TLS, fd uintptr, iRegion int32, szRegion int32, bExtend int32, pp uintptr) (r int32) { bp := tls.Alloc(160) defer tls.Free(160) var apNew, p, pDbFd, pMem, pShmNode, zFile, v4 uintptr var i, iPg, nByte, nMap Ti64 var nReqRegion, nShmPerMap, rc, v2 int32 var _ /* sStat at bp+0 */ Tstat var _ /* x at bp+144 */ int32 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = apNew, i, iPg, nByte, nMap, nReqRegion, nShmPerMap, p, pDbFd, pMem, pShmNode, rc, zFile, v2, v4 pDbFd = fd rc = SQLITE_OK nShmPerMap = _unixShmRegionPerMap(tls) /* If the shared-memory file has not yet been opened, open it now. */ if (*TunixFile)(unsafe.Pointer(pDbFd)).FpShm == uintptr(0) { rc = _unixOpenSharedMemory(tls, pDbFd) if rc != SQLITE_OK { return rc } } p = (*TunixFile)(unsafe.Pointer(pDbFd)).FpShm pShmNode = (*TunixShm)(unsafe.Pointer(p)).FpShmNode Xsqlite3_mutex_enter(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex) if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisUnlocked != 0 { rc = _unixLockSharedMemory(tls, pDbFd, pShmNode) if rc != SQLITE_OK { goto shmpage_out } (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisUnlocked = uint8(0) } /* Minimum number of regions required to be mapped. */ nReqRegion = (iRegion + nShmPerMap) / nShmPerMap * nShmPerMap if libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) < nReqRegion { /* New apRegion[] array */ nByte = int64(nReqRegion) * int64(szRegion) /* Used by fstat() */ (*TunixShmNode)(unsafe.Pointer(pShmNode)).FszRegion = szRegion if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm >= 0 { /* The requested region is not mapped into this processes address space. ** Check to see if it has been allocated (i.e. if the wal-index file is ** large enough to contain the requested region). */ if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, bp) != 0 { rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(19)<= 0 { if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly != 0 { v2 = int32(PROT_READ) } else { v2 = libc.Int32FromInt32(PROT_READ) | libc.Int32FromInt32(PROT_WRITE) } pMem = (*(*func(*libc.TLS, uintptr, Tsize_t, int32, int32, int32, Toff_t) uintptr)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(22)].FpCurrent})))(tls, uintptr(0), libc.Uint64FromInt64(nMap), v2, int32(MAP_SHARED), (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, int64(int64(szRegion)*libc.Int64FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion))) if pMem == uintptr(-libc.Int32FromInt32(1)) { rc = _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(21)< iRegion { **(**uintptr)(__ccgo_up(pp)) = **(**uintptr)(__ccgo_up((*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion + uintptr(iRegion)*8)) } else { **(**uintptr)(__ccgo_up(pp)) = uintptr(0) } if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly != 0 && rc == SQLITE_OK { rc = int32(SQLITE_READONLY) } Xsqlite3_mutex_leave(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex) return rc } // C documentation // // /* // ** Return the name of a directory in which to put temporary files. // ** If no suitable temporary file directory can be found, return NULL. // */ func _unixTempFileDir(tls *libc.TLS) (r uintptr) { bp := tls.Alloc(144) defer tls.Free(144) var i, v1 uint32 var zDir uintptr var _ /* buf at bp+0 */ Tstat _, _, _ = i, zDir, v1 i = uint32(0) zDir = Xsqlite3_temp_directory for int32(1) != 0 { if zDir != uintptr(0) && (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(4)].FpCurrent})))(tls, zDir, bp) == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(S_IFMT) == uint32(S_IFDIR) && (*(*func(*libc.TLS, uintptr, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(2)].FpCurrent})))(tls, zDir, int32(03)) == 0 { return zDir } if uint64(i) >= libc.Uint64FromInt64(48)/libc.Uint64FromInt64(8) { break } v1 = i i = i + 1 zDir = _azTempDirs[v1] } return uintptr(0) } // C documentation // // /* // ** Check a unixFile that is a database. Verify the following: // ** // ** (1) There is exactly one hard link on the file // ** (2) The file is not a symbolic link // ** (3) The file has not been renamed or unlinked // ** // ** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. // */ func _verifyDbFile(tls *libc.TLS, pFile uintptr) { bp := tls.Alloc(160) defer tls.Free(160) var rc int32 var _ /* buf at bp+0 */ Tstat _ = rc /* These verifications occurs for the main database only */ if libc.Int32FromUint16((*TunixFile)(unsafe.Pointer(pFile)).FctrlFlags)&int32(UNIXFILE_NOLOCK) != 0 { return } rc = (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, (*TunixFile)(unsafe.Pointer(pFile)).Fh, bp) if rc != 0 { Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3836, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath)) return } if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink == uint64(0) { Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3860, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath)) return } if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink > uint64(1) { Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3889, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath)) return } if _fileHasMoved(tls, pFile) != 0 { Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3916, libc.VaList(bp+152, (*TunixFile)(unsafe.Pointer(pFile)).FzPath)) return } }