github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/cmds/core/mknod/mknod_linux.go (about)

     1  // Copyright 2017 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"errors"
     9  	"flag"
    10  	"fmt"
    11  	"strconv"
    12  
    13  	"golang.org/x/sys/unix"
    14  )
    15  
    16  const defaultPerms = 0660
    17  
    18  func parseDevices(args []string, devtype string) (int, error) {
    19  	if len(args) != 4 {
    20  		return 0, fmt.Errorf("device type %v requires a major and minor number", devtype)
    21  	}
    22  	major, err := strconv.ParseUint(args[2], 10, 12)
    23  	if err != nil {
    24  		return 0, err
    25  	}
    26  	minor, err := strconv.ParseUint(args[3], 10, 20)
    27  	if err != nil {
    28  		return 0, err
    29  	}
    30  	return int(unix.Mkdev(uint32(major), uint32(minor))), nil
    31  }
    32  
    33  func mknod() error {
    34  	flag.Parse()
    35  	a := flag.Args()
    36  	if len(a) != 2 && len(a) != 4 {
    37  		return errors.New("usage: mknod path type [major minor]")
    38  	}
    39  	path := a[0]
    40  	devtype := a[1]
    41  
    42  	var err error
    43  	var mode uint32
    44  
    45  	mode = defaultPerms
    46  	var dev int
    47  
    48  	switch devtype {
    49  	case "b":
    50  		// This is a block device. A major/minor number is needed.
    51  		mode |= unix.S_IFBLK
    52  		dev, err = parseDevices(a, devtype)
    53  		if err != nil {
    54  			return err
    55  		}
    56  	case "c", "u":
    57  		// This is a character/unbuffered device. A major/minor number is needed.
    58  		mode |= unix.S_IFCHR
    59  		dev, err = parseDevices(a, devtype)
    60  		if err != nil {
    61  			return err
    62  		}
    63  	case "p":
    64  		// This is a pipe. A major and minor number must not be supplied
    65  		mode |= unix.S_IFIFO
    66  		if len(a) != 2 {
    67  			return fmt.Errorf("device type %v requires no other arguments", devtype)
    68  		}
    69  	default:
    70  		return fmt.Errorf("device type not recognized: %v", devtype)
    71  	}
    72  
    73  	if err := unix.Mknod(path, mode, dev); err != nil {
    74  		return fmt.Errorf("%q: mode %x: %v", path, mode, err)
    75  	}
    76  	return nil
    77  }