storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/os-dirent_namelen_linux.go (about)

     1  //go:build linux && !appengine
     2  // +build linux,!appengine
     3  
     4  /*
     5   * MinIO Cloud Storage, (C) 2019 MinIO, Inc.
     6   *
     7   * Licensed under the Apache License, Version 2.0 (the "License");
     8   * you may not use this file except in compliance with the License.
     9   * You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19  
    20  package cmd
    21  
    22  import (
    23  	"bytes"
    24  	"fmt"
    25  	"syscall"
    26  	"unsafe"
    27  )
    28  
    29  func direntNamlen(dirent *syscall.Dirent) (uint64, error) {
    30  	const fixedHdr = uint16(unsafe.Offsetof(syscall.Dirent{}.Name))
    31  	nameBuf := (*[unsafe.Sizeof(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]))
    32  	const nameBufLen = uint16(len(nameBuf))
    33  	limit := dirent.Reclen - fixedHdr
    34  	if limit > nameBufLen {
    35  		limit = nameBufLen
    36  	}
    37  	// Avoid bugs in long file names
    38  	// https://github.com/golang/tools/commit/5f9a5413737ba4b4f692214aebee582b47c8be74
    39  	nameLen := bytes.IndexByte(nameBuf[:limit], 0)
    40  	if nameLen < 0 {
    41  		return 0, fmt.Errorf("failed to find terminating 0 byte in dirent")
    42  	}
    43  	return uint64(nameLen), nil
    44  }