Cách sử dụng hook linux

HƯỚNG DẪN HOOK MỘT SYSTEM CALL Tạo system call: pname (processs name) Syscall này có tác dụng trả về PID cho terminal khi gọi syscall này. Đầu tiên chúng ta tạo thư mục pname và cd vào nó: mkdir pname cd pname nano pname.c Nội dung cho file pname.c như sau: #include <linux/syscalls.h> #include <linux/kernel.h> #include <linux/sched.> #include <linux/init.h> #include <linux/tty.h> #include <linux/string.h> #include "pname.h" asmlinkage long sys_process_name(char* process_name){ /*tasklist struct to use*/ struct task_struct *task; /*tty struct*/ struct tty_struct *my_tty; /*get current tty*/ my_tty = get_current_tty(); /*placeholder to print full string to tty*/ char name[32]; /*<sched.h> library method that iterates through list of processes from task_struct defined above*/ for_each_process(task){ /*compares the current process name (defined in task->comm) to the passed in name*/ if(strcmp(task->comm,process_name) == 0){ /*convert to string and put into name[]*/ sprintf(name, "PID = %ld\n", (long)task_pid_nr(task)); /*show result to user that called the syscall*/ (my_tty->driver->ops->write) (my_tty, name, strlen(name)+1); } } return 0; }

1. Mở đầu

Trong vòng vài năm gần đây hooks đang được rất ưa chuộng trong đội ngũ reactjs, một trong những lý do chính đó là sự thuận tiện, ngắn gọn tuyệt vời mà nó mang lại. Hơn thế nữa chúng ta hoàn toàn có thể có thêm lựa chọn để chia code một cách tường minh. Một trong số cách tuyệt vời đó là custom hooks.

2, Custom Hooks là gì và ví dụ:

Có thể hiểu đơn giản custom hooks là một cách chia code dẽ dàng và hiệu quả.

Ok trong một dự án các bạn sẽ thấy có một file .eslintrc, file này sẽ quy định các quy tắc viết code của bạn, thường để đảm bảo tính tường minh và dễ bảo trì thì độ dài của một file sẽ vào khoảng 200 dòng. Nó đảm bảo bạn sẽ chia các đoạn code theo từng tác vụ mà nó thực hiện, nếu bạn chỉ đơn giản viết tách ra một componenter và import vào thì đơn giản nhưng bạn sẽ phải lặp lại đoạn import thư viện, defaul value vv... khá là nhiều công việc phải lặp lại đúng không nào. Thay vì đó bạn có thể tạo ra một custorm hooks và viết tất cả chúng vào, khi nào cần chỉ cần useNameHook đó vào là song.

Để thấy rõ vấn đề này chúng ta sẽ cùng đi vào một số ví dụ để thấy được sự thú vị của hàm này nhé.

Đầu tiên mình muốn vẽ một table, chúng ta sẽ có một đoạn code như sau:

const Table = ({
    Data, paginate, delete,
    fetch, search, id, authUser,
    updateStatus, userProject, roleUser
}) => {
    const {Option} = Select;

    function renderTagSeverity(severity) {
        switch (severity) {
        case 'critical':
            return '#991aff';
        case 'high':
            return '#f80000';
        case 'medium':
            return '#fb9900';
        case 'low':
            return 'rgb(195, 195, 32)';
        default:
            return 'red';
        }
    }

    function checkShowStatus(status) {
        switch (status) {
        case PROCESS:
            return PROCESS;
        case APPROVED:
            return APPROVED;
        case REJECT:
            return REJECT;
        default:
            return PROCESS;
        }
    }

    function getColumn() {
        const columns = [
            {
                title: 'Name',
                dataIndex: 'name',
                width: '12%'
            },
            {
                title: 'Severity',
                dataIndex: 'severity',
                width: '12%'
            },
            {
                title: 'Score',
                dataIndex: 'score',
                width: '12%'
            },
            {
                title: 'Impact',
                dataIndex: 'impact',
                width: '12%'
            },
            {
                title: 'Owner',
                dataIndex: 'username',
                width: '16%'
            },
            {
                title: 'Status',
                dataIndex: 'status',
                width: '15%',
                render: (text, record) => (
                    showSelectWithRole(text, record)
                )
            },
            {
                title: 'Action',
                dataIndex: 'action',
                width: '14%'
            }
        ];
        return columns;
    }

    function handleChange(record, value) {
        updateStatus({
            id: record.key,
            status: value,
            userId: authUser.get('id')
        });
    }

    function handlePageChange(page) {
        fetch({id, search: {...search, page}});
    }

    function confirm(id) {
        delete(id);
    }

    function showSelectWithRole(text, record) {
        const userCreateId = record(['user_id', 'id']);
        if (roleUser === ADMIN || userProject === PM || userCreateId === authUser.get('id')) {
            return (
                <Select
                    name='status'
                    defaultValue={checkShowStatus(record.('status'))}
                    style={{width: 140}}
                    onChange={value => handleChange(record, value)}
                >
                    <Option value={PROCESS}>PROCESS</Option>
                    <Option value={APPROVED}>APPROVED</Option>
                    <Option value={REJECT}>REJECT</Option>
                </Select>
            );
        }
        return (
            <Select
                name='status'
                defaultValue={checkShowStatus(record.get('status'))}
                onChange={value => handleChange(record, value)}
                disabled
                showArrow={false}
            >
                <Option value={PROCESS}>PROCESS</Option>
                <Option value={APPROVED}>APPROVED</Option>
                <Option value={REJECT}>REJECT</Option>
            </Select>
        );
    }

    function checkRole(userId, id, idProject) {
        if (userId === authUser.get('id')) {
            return (
                <div>
                    <Tooltip title='Edit' placement='top'>
                        <Link to={`/project/${idProject}/edit/${id}`}>
                            <Button>
                                <EditOutlined />
                            </Button>
                        </Link>
                    </Tooltip>
                    <Popconfirm
                        title='Are you sure delete this security vulnerability?'
                        onConfirm={() => confirm(id)}
                        okText='Yes'
                        cancelText='No'
                    >
                        <Tooltip title='Delete' placement='top'>
                            <Button danger>
                                <DeleteOutlined />
                            </Button>
                        </Tooltip>
                    </Popconfirm>
                </div>
            );
        }
        return '';
    }

    const dataTable = [];
    Data.map((data) => {
        dataTable.push({
            key: data.getIn(['id']),
            name: data.getIn(['name']),
            severity: (
                <span>
                    <Tag
                        color={renderTagSeverity(data.getIn(['severity']))}
                    >
                        {data.getIn(['severity'])}
                    </Tag>
                </span>
            ),
            score: (
                <span>
                    <a
                        style={{color: '#01a9ac'}}
                        href={data.getIn(['score'])}
                        target='__blank'
                    >
                        {data.getIn(['score'])}
                    </a>
                </span>
            ),
            impact: (
                <span>
                    {data.getIn(['impact'])}
                </span>
            ),
            username: (
                <span>
                    {data.getIn(['user_id', 'name'])}
                </span>
            ),
            status: (
                <span>
                    {data}
                </span>
            ),
            action: (
                checkRole(data.getIn(['user_id', 'id']), data.get('id'), id)
            )
        });
        return dataTable;
    });
    const columns = getColumn();
    return (
        <>
            <Table
                dataSource={dataTable}
                columns={columns}
                scroll={{y: '55vh'}}
                pagination={
                    {
                        defaultPageSize: pagination.pageSize,
                        pageSize: paginate.get('perPage'),
                        defaultCurrent: pagination.currentPage,
                        current: paginate.get('currentPage'),
                        total: paginate.get('total'),
                        showSizeChanger: false,
                        onChange: page => handlePageChange(page)
                    }
                }
            />
        </>
    );
};

với Data là dữ liệu mình muốn render ra, paginate là phân trang, và các hàm delete, fetch, search, id, authUser, updateStatus, userProject, roleUser là các hàm sử lý của mình. Các bạn không cần quá quan tâm xem nó thực hiện các tác vụ gì, mà thực ra từ cái tên các bạn đã dễ dàng nhận ra nó để làm gì rồi

Cách sử dụng hook linux
. Vấn đề mình muốn nói tới ở đây dù mình đã đặt tên khá tường mình nhưng thật khó để các bạn heo dõi luồng xử lý logic của mình.

thay vì đó mình sẽ tách các một số hàm trên thành một file đặt tên là: useSupportHook.js các bạn chú ý lên đặt tên có phần use đằng trước nhé. Và mình có đoạn nột dung như sau:

import {PROCESS, APPROVED, REJECT} from '~/utils/status';

const renderTagSeverity = (severity) => {
    switch (severity) {
    case 'critical':
        return '#991aff';
    case 'high':
        return '#f80000';
    case 'medium':
        return '#fb9900';
    case 'low':
        return 'rgb(195, 195, 32)';
    default:
        return 'red';
    }
};

const checkShowStatus = (status) => {
    switch (status) {
    case PROCESS:
        return PROCESS;
    case APPROVED:
        return APPROVED;
    case REJECT:
        return REJECT;
    default:
        return PROCESS;
    }
};


const useSupportHook = (showSelectWithRole) => {
    function getColumn() {
        const columns = [
            {
                title: 'Name',
                dataIndex: 'name',
                width: '12%'
            },
            {
                title: 'Severity',
                dataIndex: 'severity',
                width: '12%'
            },
            {
                title: 'Score',
                dataIndex: 'score',
                width: '12%'
            },
            {
                title: 'Impact',
                dataIndex: 'impact',
                width: '12%'
            },
            {
                title: 'Owner',
                dataIndex: 'username',
                width: '16%'
            },
            {
                title: 'Status',
                dataIndex: 'status',
                width: '15%',
                render: (text, record) => (
                    showSelectWithRole(text, record)
                )
            },
            {
                title: 'Action',
                dataIndex: 'action',
                width: '14%'
            }
        ];
        return columns;
    }

    return [
        renderTagSeverity,
        checkShowStatus,
        getColumn
    ];
};
export default useSupportHook;

và bên file mình sẽ import vào import useSupportHook from './useSupportHook'; và use vào:

const [renderTagSeverity, checkShowStatus, getColumn] = useSupportHook(showSelectWithRole);

và bây giời mình chỉ việc sử dụng chúng thôi

Cách sử dụng hook linux
thật ngắn gọn và tường mình đúng không nào.

3, Kết luận:

Đọc tới đây chắc các bạn cũng đã hình dung được custom hook là gì cũng như cách sử dụng, hoạt động của nó rồi đúng không ạ

Cách sử dụng hook linux
. Tương tự với cách sử dụng như vậy, bạn có thể tạo ra nhiều các biến thể khác nhau cho phù hợp với mục đích sử dụng. Các ơn các bạn đã theo dõi.

Cách sử dụng hook linux