Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

Section 20.8 Source Code 773


532 /*
533 * Position the index file and record the offset.
534 */
535 if ((db->idxoff = lseek(db->idxfd, offset, whence)) == -1)
536 err_dump("_db_writeidx: lseek error");

537 iov[0].iov_base=asciiptrlen;
538 iov[0].iov_len =PTR_SZ + IDXLEN_SZ;
539 iov[1].iov_base=db->idxbuf;
540 iov[1].iov_len =len;
541 if (writev(db->idxfd, &iov[0], 2) != PTR_SZ + IDXLEN_SZ + len)
542 err_dump("_db_writeidx: writev error of index record");
543 if (whence == SEEK_END)
544 if (un_lock(db->idxfd, ((db->nhash+1)*PTR_SZ)+1,
545 SEEK_SET, 0) < 0)
546 err_dump("_db_writeidx: un_lock error");
547 }
548 /*
549 * Write a chain ptr field somewhere in the index file:
550 * the free list, the hash table, or in an index record.
551 */
552 static void
553 _db_writeptr(DB *db, off_t offset, off_t ptrval)
554 {
555 char asciiptr[PTR_SZ + 1];
556 if (ptrval < 0 || ptrval > PTR_MAX)
557 err_quit("_db_writeptr: invalid ptr: %d", ptrval);
558 sprintf(asciiptr, "%*lld", PTR_SZ, (long long)ptrval);
559 if (lseek(db->idxfd, offset, SEEK_SET) == -1)
560 err_dump("_db_writeptr: lseek error to ptr field");
561 if (write(db->idxfd, asciiptr, PTR_SZ) != PTR_SZ)
562 err_dump("_db_writeptr: write error of ptr field");
563 }

[532 – 547] We seek to the location where we want to write the index recordand save
this offset in theidxofffield of theDBstructure. Since we built the index
record in two separate buffers, we usewritevto storeit in the index file. If
we wereappending to the file, we release the lock we acquired before
seeking. This makes the seek and the write an atomic operation from the
perspective of concurrently running processes appending new records to the
same database.
[548 – 563] _db_writeptris used to write a chain pointer to the index file. We
validate that the chain pointer is within bounds, then convert it to an ASCII
string. Weseek to the specified offset in the index file and write the pointer.
Free download pdf