You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: readdir_unix.go
    path of file: ./repos/teller/vendor/github.com/karrick/godirwalk
    
    the code of the file until where you have to start completion: // +build !windows

package godirwalk

import (
	"os"
	"syscall"
	"unsafe"
)

// MinimumScratchBufferSize specifies the minimum size of the scratch buffer
// that ReadDirents, ReadDirnames, Scanner, and Walk will use w
    
func readDirnames(osDirname string, scratchBuffer []byte) ([]string, error) {
	var entries []string
	var workBuffer []byte
	var sde *syscall.Dirent

	dh, err := os.Open(osDirname)
	if err != nil {
		return nil, err
	}
	fd := int(dh.Fd())

	if len(scratchBuffer) < MinimumScratchBufferSize {
		scratchBuffer = newScratchBuffer()
	}

	for {
		if len(workBuffer) == 0 {
			n, err := syscall.ReadDirent(fd, scratchBuffer)
			// n, err := unix.ReadDirent(fd, scratchBuffer)
			if err != nil {
				if err == syscall.EINTR /* || err == unix.EINTR */ {
					continue
				}
				_ = dh.Close()
				return nil, err
			}
			if n <= 0 { // end of directory: normal exit
				if err = dh.Close(); err != nil {
					return nil, err
				}
				return entries, nil
			}
			workBuffer = scratchBuffer[:n] // trim work buffer to number of bytes read
		}

		sde = (*syscall.Dirent)(unsafe.Pointer(&workBuffer[0])) // point entry to first syscall.Dirent in buffer
		// Handle first entry in the work buffer.
		workBuffer = workBuffer[reclen(sde):] // advance buffer for next iteration through loop

		if inoFromDirent(sde) == 0 {
			continue // inode set to 0 indicates an entry that was marked as deleted
		}

		nameSlice := nameFromDirent(sde)
		nameLength := len(nameSlice)

		if nameLength == 0 || (nameSlice[0] == '.' && (nameLength == 1 || (nameLength == 2 && nameSlice[1] == '.'))) {
			continue
		}

		entries = append(entries, string(nameSlice))
	}
}