설명

dev 로 지정하는 주번호와 부번호를 이용하여 mode 에 지정하는 디바이스 파일 종류와 접근 허가 속성을 가진 pathname 의 디바이스 파일을 만든다.

접근 허가 속성은 프로세스의 umask 와 AND 연산 ( mode & ~umask ) 의 결과값이 최종 생성되는 디바이스 파일의 접근 허가 속성이 된다.

이름 mknod - 저수준 함수
분류 저수준 파일 함수
타입 함수
커널 -
GPL -
헤더 #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
형태 int mknod(const char *pathname, mode_t mode, dev_t dev);
인수
pathname 생성할 디바이스 파일명 문자열 주소
mode

접근 허가 속성과 디바이스 타입의 비트 OR 값

디바이스 파일 종류

S_IFCHR : 문자 디바이스
S_IFBLK : 블록 디바이스

접근 허가

S_IRWXU : 사용자는 읽기 쓰기 권한이 있다.
S_IRWXG : 그룹은 읽기 쓰기 권한이 있다.

dev 주번호 와 부번호를 지정하는 디바이스 구조체
반환
0 함수 수행이 성공한 것이다.
-1 함수 수행 실패. error 값을 참조
에러
EACCES 디바이스 파일이 생성될 디렉토리가 이 함수를 수행하는 프로세스에게 쓰기가 허가되지 않았다. 또는 디렉토리가 없다.
EEXIST 이미 해당 파일은 존재한다.
EFAULT 패스명을 지정하는 문자열 포인터의 주소가 프로세스 접근 주소 공간을 벗어났다.
EINVAL mode 변수에 지정된 값이 적절치 않다.
ELOOP 패스며에 연결된 심볼릭 링크수가 너무 많다.
ENAMETOOLONG 패스명이 너무 길다.
ENOENT 패스명에 포함된 디렉토리가 존재하지 않거나 심볼링크이다.
ENOMEM 디파이스 파일을 생성하기 위한 커널 메모리가 부족하다.
ENOSPC 디파이스 파일을 생성하기 위한 노드가 없다.
ENOTDIR 패스명에 포함된 디렉토리는 디렉토리가 아니다.
EPERM mode 값으로 지정한 것은 규정된 파일 형식이 아니다.
EROFS 패스명이 생성될 위치가 읽기 전용 파일 시스템이다.
연관 mknod 유틸, dev_t, MAJOR, MINOR, MKDEV
주의 이 함수를 동작 시키는 프로그램은 root 권한을 가지고 있어야 한다.
버그 -
작성 유영창

예제

// 이 함수는 chk_driver_name 이 지정하는 디바이스 드라이버의 주번호를 획득하고
// make_minor가 지정하는 부번호와 조합하여 임시적인 디바이스 파일을 만들고
// 해당 디바이스 파일을 연다. 이때 unlink 함수를 사용하여 프로세스가 종료되면
// 자동으로 파일이 삭제되도록 한다. 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int device_open( char *chk_driver_name, int make_minor )
{

    FILE *fp;
    int   dev_fd;
    char  linebuff[128];
    char  tmp_driver_name[32];
    int   major;
    
    dev_fd = -1;

    fp = fopen("/proc/devices", "r");
    if(fp == NULL) return -1;   

    while(1) 
    {
        if( fgets(linebuff, sizeof( linebuff) , fp ) == NULL ) break;
        if( sscanf(linebuff, "%d %s", &major, tmp_driver_name) == 2 )
        {
            if (strcmp( tmp_driver_name, chk_driver_name ) == 0)
            {
                fclose( fp );

                sprintf( linebuff, "%s%s-%d", "./", 
                                              chk_driver_name,
                                              getpid() );

                mknod(linebuff, (S_IRWXU¦S_IRWXG¦S_IFCHR), MKDEV(major,make_minor) );
                
                dev_fd = open(linebuff, O_RDWR );
                if( dev_fd < 0 ) return dev_fd;
                unlink(linebuff);

                return dev_fd;
            } 
        }
    }
    fclose( fp );
    
    return dev_fd;
}