6c92f85d10
Bring the Nexus/Praxis/Hexis integration in line with MAVEN_ECOSYSTEM_ARCHITECTURE.md: - Praxis over HTTP: drop the in-process praxis.db open (praxisstore/ praxistools) and call praxisd's /api/v1/tools/* API via a new praxisClient. Honors the "no component reads another's DB" invariant (AC#12). PraxisConfig.DBPath -> URL. - Hexis confirmation gate: mutating capabilities (ReadOnly=false) now park a bound pendingHexis confirmation and require a spoken "да" before executing; read-only run immediately (AC#7, no auto attention->action). - Capability safety: >1 verb match is ambiguous -> ask instead of firing the first; ambiguous Nexus resolution asks for clarification (AC#2). - Correlation IDs on Hexis execute, recorded in the cross-service trace. - Bug: importance arrives as JSON float64 over HTTP, not int. - Tests: confirm-gate, decline, read-only, and ambiguity paths. Build: vendor/ bakes in the hexis client (replace-directed at a sibling repo outside the Docker context); Dockerfile builds from vendor and no longer `go mod download`s the unreachable replace paths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
541 lines
24 KiB
Go
541 lines
24 KiB
Go
// Code generated by modernc.org/undup from the per-target sqlite_*.go files; DO NOT EDIT.
|
|
|
|
//go:build (linux && arm64) || (linux && riscv64)
|
|
|
|
package sqlite3
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"modernc.org/libc"
|
|
)
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Append a single path element to the DbPath under construction
|
|
// */
|
|
func _appendOnePathElement(tls *libc.TLS, pPath uintptr, zName uintptr, nName int32) {
|
|
bp := tls.Alloc(4240)
|
|
defer tls.Free(4240)
|
|
var got Tssize_t
|
|
var zIn, v2 uintptr
|
|
var v1 int32
|
|
var _ /* buf at bp+0 */ Tstat
|
|
var _ /* zLnk at bp+128 */ [4098]uint8
|
|
_, _, _, _ = got, zIn, v1, v2
|
|
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zName))) == int32('.') {
|
|
if nName == int32(1) {
|
|
return
|
|
}
|
|
if libc.Int32FromUint8(**(**uint8)(__ccgo_up(zName + 1))) == int32('.') && nName == int32(2) {
|
|
if (*TDbPath)(unsafe.Pointer(pPath)).FnUsed > int32(1) {
|
|
for {
|
|
v2 = pPath + 20
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) - 1
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
if !(libc.Int32FromUint8(**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr(v1)))) != int32('/')) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
}
|
|
if (*TDbPath)(unsafe.Pointer(pPath)).FnUsed+nName+int32(2) >= (*TDbPath)(unsafe.Pointer(pPath)).FnOut {
|
|
(*TDbPath)(unsafe.Pointer(pPath)).Frc = int32(SQLITE_ERROR)
|
|
return
|
|
}
|
|
v2 = pPath + 20
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr(v1))) = uint8('/')
|
|
libc.Xmemcpy(tls, (*TDbPath)(unsafe.Pointer(pPath)).FzOut+uintptr((*TDbPath)(unsafe.Pointer(pPath)).FnUsed), zName, libc.Uint64FromInt32(nName))
|
|
**(**int32)(__ccgo_up(pPath + 20)) += nName
|
|
if (*TDbPath)(unsafe.Pointer(pPath)).Frc == SQLITE_OK {
|
|
**(**uint8)(__ccgo_up((*TDbPath)(unsafe.Pointer(pPath)).FzOut + uintptr((*TDbPath)(unsafe.Pointer(pPath)).FnUsed))) = uint8(0)
|
|
zIn = (*TDbPath)(unsafe.Pointer(pPath)).FzOut
|
|
if (*(*func(*libc.TLS, uintptr, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(27)].FpCurrent})))(tls, zIn, bp) != 0 {
|
|
if **(**int32)(__ccgo_up(libc.X__errno_location(tls))) != int32(ENOENT) {
|
|
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47152)), __ccgo_ts+3740, zIn, int32(47152))
|
|
}
|
|
} else {
|
|
if (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(S_IFMT) == uint32(S_IFLNK) {
|
|
v2 = pPath + 4
|
|
v1 = *(*int32)(unsafe.Pointer(v2))
|
|
*(*int32)(unsafe.Pointer(v2)) = *(*int32)(unsafe.Pointer(v2)) + 1
|
|
if v1 > int32(SQLITE_MAX_SYMLINK) {
|
|
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _sqlite3CantopenError(tls, int32(47158))
|
|
return
|
|
}
|
|
got = (*(*func(*libc.TLS, uintptr, uintptr, Tsize_t) Tssize_t)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(26)].FpCurrent})))(tls, zIn, bp+128, libc.Uint64FromInt64(4098)-libc.Uint64FromInt32(2))
|
|
if got <= 0 || got >= libc.Int64FromInt64(4098)-libc.Int64FromInt32(2) {
|
|
(*TDbPath)(unsafe.Pointer(pPath)).Frc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(47163)), __ccgo_ts+3731, zIn, int32(47163))
|
|
return
|
|
}
|
|
(**(**[4098]uint8)(__ccgo_up(bp + 128)))[got] = uint8(0)
|
|
if libc.Int32FromUint8((**(**[4098]uint8)(__ccgo_up(bp + 128)))[0]) == int32('/') {
|
|
(*TDbPath)(unsafe.Pointer(pPath)).FnUsed = 0
|
|
} else {
|
|
**(**int32)(__ccgo_up(pPath + 20)) -= nName + int32(1)
|
|
}
|
|
_appendAllPathElements(tls, pPath, bp+128)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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(128)
|
|
defer tls.Free(128)
|
|
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)<<libc.Int32FromInt32(8)
|
|
}
|
|
nSize = (nByte + int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk) - int64(1)) / int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk) * int64((*TunixFile)(unsafe.Pointer(pFile)).FszChunk)
|
|
if nSize > 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 = (**(**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)<<libc.Int32FromInt32(8)
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iWrite = iWrite + int64(nBlk)
|
|
}
|
|
}
|
|
}
|
|
if (*TunixFile)(unsafe.Pointer(pFile)).FmmapSizeMax > 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)<<libc.Int32FromInt32(8), __ccgo_ts+3578, (*TunixFile)(unsafe.Pointer(pFile)).FzPath, int32(44297))
|
|
}
|
|
}
|
|
rc = _unixMapfile(tls, pFile, nByte)
|
|
return rc
|
|
}
|
|
return SQLITE_OK
|
|
}
|
|
|
|
// C documentation
|
|
//
|
|
// /*
|
|
// ** Invoke open(). Do so multiple times, until it either succeeds or
|
|
// ** fails for some reason other than EINTR.
|
|
// **
|
|
// ** If the file creation mode "m" is 0 then set it to the default for
|
|
// ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
|
|
// ** 0644) as modified by the system umask. If m is not 0, then
|
|
// ** make the file creation mode be exactly m ignoring the umask.
|
|
// **
|
|
// ** The m parameter will be non-zero only when creating -wal, -journal,
|
|
// ** and -shm files. We want those files to have *exactly* the same
|
|
// ** permissions as their original database, unadulterated by the umask.
|
|
// ** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
|
|
// ** transaction crashes and leaves behind hot journals, then any
|
|
// ** process that is able to write to the database will also be able to
|
|
// ** recover the hot journals.
|
|
// */
|
|
func _robust_open(tls *libc.TLS, z uintptr, f int32, m Tmode_t) (r int32) {
|
|
bp := tls.Alloc(160)
|
|
defer tls.Free(160)
|
|
var fd int32
|
|
var m2 Tmode_t
|
|
var v1 uint32
|
|
var _ /* statbuf at bp+0 */ Tstat
|
|
_, _, _ = fd, m2, v1
|
|
if m != 0 {
|
|
v1 = m
|
|
} else {
|
|
v1 = uint32(SQLITE_DEFAULT_FILE_PERMISSIONS)
|
|
}
|
|
m2 = v1
|
|
for int32(1) != 0 {
|
|
fd = (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, z, f|int32(O_CLOEXEC), libc.Int32FromUint32(m2))
|
|
if fd < 0 {
|
|
if **(**int32)(__ccgo_up(libc.X__errno_location(tls))) == int32(EINTR) {
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
if fd >= int32(SQLITE_MINIMUM_FILE_DESCRIPTOR) {
|
|
break
|
|
}
|
|
if f&(libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT)) == libc.Int32FromInt32(O_EXCL)|libc.Int32FromInt32(O_CREAT) {
|
|
(*(*func(*libc.TLS, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(16)].FpCurrent})))(tls, z)
|
|
}
|
|
(*(*func(*libc.TLS, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(1)].FpCurrent})))(tls, fd)
|
|
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3752, libc.VaList(bp+136, z, fd))
|
|
fd = -int32(1)
|
|
if (*(*func(*libc.TLS, uintptr, int32, int32) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[0].FpCurrent})))(tls, __ccgo_ts+3795, O_RDONLY, libc.Int32FromUint32(m)) < 0 {
|
|
break
|
|
}
|
|
}
|
|
if fd >= 0 {
|
|
if m != uint32(0) {
|
|
if (*(*func(*libc.TLS, int32, uintptr) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(5)].FpCurrent})))(tls, fd, bp) == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_size == 0 && (**(**Tstat)(__ccgo_up(bp))).Fst_mode&uint32(0777) != m {
|
|
(*(*func(*libc.TLS, int32, Tmode_t) int32)(unsafe.Pointer(&struct{ uintptr }{_aSyscall[int32(14)].FpCurrent})))(tls, fd, m)
|
|
}
|
|
}
|
|
}
|
|
return fd
|
|
}
|
|
|
|
// 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(144)
|
|
defer tls.Free(144)
|
|
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)<<libc.Int32FromInt32(8)
|
|
goto shm_open_err
|
|
}
|
|
nShmFilename = int32(6) + libc.Int32FromUint64(libc.Xstrlen(tls, zBasePath))
|
|
pShmNode = Xsqlite3_malloc64(tls, uint64(uint64(96)+libc.Uint64FromInt32(nShmFilename)))
|
|
if pShmNode == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
goto shm_open_err
|
|
}
|
|
libc.Xmemset(tls, pShmNode, 0, uint64(96)+libc.Uint64FromInt32(nShmFilename))
|
|
v1 = pShmNode + 1*96
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename = v1
|
|
zShm = v1
|
|
Xsqlite3_snprintf(tls, nShmFilename, zShm, __ccgo_ts+3958, libc.VaList(bp+136, zBasePath))
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = -int32(1)
|
|
(*TunixInodeInfo)(unsafe.Pointer((*TunixFile)(unsafe.Pointer(pDbFd)).FpInode)).FpShmNode = pShmNode
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpInode = (*TunixFile)(unsafe.Pointer(pDbFd)).FpInode
|
|
if _sqlite3Config.FbCoreMutex != 0 {
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex = Xsqlite3_mutex_alloc(tls, SQLITE_MUTEX_FAST)
|
|
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FpShmMutex == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
goto shm_open_err
|
|
}
|
|
}
|
|
if libc.Int32FromUint8((*TunixInodeInfo)(unsafe.Pointer(pInode)).FbProcessLock) == 0 {
|
|
if 0 == Xsqlite3_uri_boolean(tls, (*TunixFile)(unsafe.Pointer(pDbFd)).FzPath, __ccgo_ts+3965, 0) {
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = _robust_open(tls, zShm, libc.Int32FromInt32(O_RDWR)|libc.Int32FromInt32(O_CREAT)|libc.Int32FromInt32(O_NOFOLLOW), (**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(0777))
|
|
}
|
|
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm < 0 {
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm = _robust_open(tls, zShm, libc.Int32FromInt32(O_RDONLY)|libc.Int32FromInt32(O_NOFOLLOW), (**(**Tstat)(__ccgo_up(bp))).Fst_mode&libc.Uint32FromInt32(0777))
|
|
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm < 0 {
|
|
rc = _unixLogErrorAtLine(tls, _sqlite3CantopenError(tls, int32(45237)), __ccgo_ts+3542, zShm, int32(45237))
|
|
goto shm_open_err
|
|
}
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FisReadonly = uint8(1)
|
|
}
|
|
/* If this process is running as root, make sure that the SHM file
|
|
** is owned by the same user that owns the original database. Otherwise,
|
|
** the original owner will not be able to connect.
|
|
*/
|
|
_robustFchown(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, (**(**Tstat)(__ccgo_up(bp))).Fst_uid, (**(**Tstat)(__ccgo_up(bp))).Fst_gid)
|
|
rc = _unixLockSharedMemory(tls, pDbFd, pShmNode)
|
|
if rc != SQLITE_OK && rc != libc.Int32FromInt32(SQLITE_READONLY)|libc.Int32FromInt32(5)<<libc.Int32FromInt32(8) {
|
|
goto shm_open_err
|
|
}
|
|
}
|
|
}
|
|
/* Make the new connection a child of the unixShmNode */
|
|
(*TunixShm)(unsafe.Pointer(p)).FpShmNode = pShmNode
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRef = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRef + 1
|
|
(*TunixFile)(unsafe.Pointer(pDbFd)).FpShm = p
|
|
_unixLeaveMutex(tls)
|
|
/* The reference count on pShmNode has already been incremented under
|
|
** the cover of the unixEnterMutex() mutex and the pointer from the
|
|
** new (struct unixShm) object to the pShmNode has been set. All that is
|
|
** left to do is to link the new object into the linked list starting
|
|
** at pShmNode->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(144)
|
|
defer tls.Free(144)
|
|
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+128 */ 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)<<libc.Int32FromInt32(8)
|
|
goto shmpage_out
|
|
}
|
|
if int64((**(**Tstat)(__ccgo_up(bp))).Fst_size) < nByte {
|
|
/* The requested memory region does not exist. If bExtend is set to
|
|
** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
|
|
*/
|
|
if !(bExtend != 0) {
|
|
goto shmpage_out
|
|
} else {
|
|
/* Write to the last byte of each newly allocated or extended page */
|
|
iPg = int64((**(**Tstat)(__ccgo_up(bp))).Fst_size / int64(_pgsz))
|
|
for {
|
|
if !(iPg < nByte/int64(_pgsz)) {
|
|
break
|
|
}
|
|
**(**int32)(__ccgo_up(bp + 128)) = 0
|
|
if _seekAndWriteFd(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm, iPg*int64(_pgsz)+int64(_pgsz)-int64(1), __ccgo_ts+1704, int32(1), bp+128) != int32(1) {
|
|
zFile = (*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename
|
|
rc = _unixLogErrorAtLine(tls, libc.Int32FromInt32(SQLITE_IOERR)|libc.Int32FromInt32(19)<<libc.Int32FromInt32(8), __ccgo_ts+3613, zFile, int32(45381))
|
|
goto shmpage_out
|
|
}
|
|
goto _1
|
|
_1:
|
|
;
|
|
iPg = iPg + 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* Map the requested memory region into this processes address space. */
|
|
apNew = Xsqlite3_realloc64(tls, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion, uint64(libc.Uint64FromInt32(nReqRegion)*uint64(8)))
|
|
if !(apNew != 0) {
|
|
rc = libc.Int32FromInt32(SQLITE_IOERR) | libc.Int32FromInt32(12)<<libc.Int32FromInt32(8)
|
|
goto shmpage_out
|
|
}
|
|
(*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion = apNew
|
|
for libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) < nReqRegion {
|
|
nMap = int64(szRegion) * int64(nShmPerMap)
|
|
if (*TunixShmNode)(unsafe.Pointer(pShmNode)).FhShm >= 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)<<libc.Int32FromInt32(8), __ccgo_ts+3700, (*TunixShmNode)(unsafe.Pointer(pShmNode)).FzFilename, int32(45408))
|
|
goto shmpage_out
|
|
}
|
|
} else {
|
|
pMem = Xsqlite3_malloc64(tls, libc.Uint64FromInt64(nMap))
|
|
if pMem == uintptr(0) {
|
|
rc = int32(SQLITE_NOMEM)
|
|
goto shmpage_out
|
|
}
|
|
libc.Xmemset(tls, pMem, 0, libc.Uint64FromInt64(nMap))
|
|
}
|
|
i = 0
|
|
for {
|
|
if !(i < int64(nShmPerMap)) {
|
|
break
|
|
}
|
|
**(**uintptr)(__ccgo_up((*TunixShmNode)(unsafe.Pointer(pShmNode)).FapRegion + uintptr(libc.Int64FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion)+i)*8)) = pMem + uintptr(int64(szRegion)*i)
|
|
goto _3
|
|
_3:
|
|
;
|
|
i = i + 1
|
|
}
|
|
v4 = pShmNode + 32
|
|
*(*Tu16)(unsafe.Pointer(v4)) = Tu16(int32(*(*Tu16)(unsafe.Pointer(v4))) + nShmPerMap)
|
|
}
|
|
}
|
|
goto shmpage_out
|
|
shmpage_out:
|
|
;
|
|
if libc.Int32FromUint16((*TunixShmNode)(unsafe.Pointer(pShmNode)).FnRegion) > 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
|
|
//
|
|
// /*
|
|
// ** 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(144)
|
|
defer tls.Free(144)
|
|
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+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
|
return
|
|
}
|
|
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink == uint32(0) {
|
|
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3860, libc.VaList(bp+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
|
return
|
|
}
|
|
if (**(**Tstat)(__ccgo_up(bp))).Fst_nlink > uint32(1) {
|
|
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3889, libc.VaList(bp+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
|
return
|
|
}
|
|
if _fileHasMoved(tls, pFile) != 0 {
|
|
Xsqlite3_log(tls, int32(SQLITE_WARNING), __ccgo_ts+3916, libc.VaList(bp+136, (*TunixFile)(unsafe.Pointer(pFile)).FzPath))
|
|
return
|
|
}
|
|
}
|