Unix_Linux Operating System - Note Day4

Day4

lseek

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

off_t lseek(int fd, off_t offset, int whence);

  • Setting File Position Pointer
  • The location function of the return value file pointer is similar to ftell

Exercise 1: Implementing a function for calculating file size on a Linux system using system calls
homework
Exercise 2: Implement a cp command with coverage check
homework

dup/dup2

#include <unistd.h>

int dup(int oldfd);

  • Copy the file descriptor, and the operating system will select a small return from the unused file descriptor
  • oldfd Copied File Descriptor

int dup2(int oldfd, int newfd);

  • Copy the specified file descriptor, and if newfd is already in use, close it before copying it
  • oldfd
  • newfd
  • Return
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
void init(void){
    int fd = open("log.txt",O_RDWR|O_CREAT|O_APPEND,0644);
    dup2(fd,1);//If it is 0, you can read a line from the log using gets
}

int main(){
    init();//After init, printf() prints directly to log.txt
    int fd = dup(2);//When fd = 1/2 (STDOUT/STDERR), the data written to fd will be printed directly.
    write(fd,"hello",5);
}

Comparison of Standard IO and System IO

Exercise 3 uses standard IO and system IO to write 100,000 integers to files randomly. Which method is faster and why? homework

Standard IO uses buffer technology, and every time the system IO is invoked, the user state and the kernel state are switched.

File synchronization

sync/fsync/fdatasync

There are usually some buffers on the hard disk to improve the efficiency of data writing. In fact, the data written by the operating system is only written to the buffer, and it is not queued to write to the hard disk until the buffer is full.

This operation reduces the number of writes, but increases the latency of data writes, resulting in data in the buffer not synchronizing with the contents of the disk.

Note that all the buffers mentioned here refer to hard disk caching

void sync(void);

  • Synchronize all data in all buffers to disk
  • Note that commands that synchronize data to disk are not returned after execution, but immediately after the command is issued.

int fsync(int fd);

  • Buffer data of specified df file is synchronized to disk, only for one file. Data is synchronized to disk before returning.

int fdatasync(int fd);

  • Specifies that the buffer data of the df file is synchronized to disk, but only the data of the file is not synchronized with the properties of the file

fcntl

int fcntl(int fd,int cmd,.../* arg */);

  • cmd operation instructions, different operation instructions determine the number and type of subsequent parameters
  • Note that this is a function of variable length parameters.

int fcntl(int fd,int cmd, long newfd);

  • cmd F_DUPFD
  • Copy the file descriptor to operate on the same file as fd
  • Return value returns newfd if newfd is not used; if nrefd is occupied, return a file descriptor no less than newfd

Exercise 1: Using fcntl to realize the function of DUP and dup2
homework

int fcntl(int fd, int cmd, void/long);

  • Setting or Getting File Descriptor Flags

  • cmd

    • F_GETFD
    • F_SETFD

    At present, only FD_CLOEXEC flag can be set.

  • Return value 0. The new process remains open, and 1. Close the file descriptor in the new process.

int fcntl(int fd, int cmd, void/long);

  • Get the file status flag (the permission to open the current file and how to open it)
  • cmd:
    • F_GETFL void
      • O_CREAT,O_EXCL,O_NOCTTY,O_TRUNC are not available
    • The return value has an int type state with a file status flag, which needs to be associated with each flag.
    • F_SETFL long
      • Only O_APPEND,O_ASYNC,O_DIRECT,O_NOATIME,O_NONBLOCK can be set.
    • Return Value Success 0 Failure-1
#include <...>
void file_flags(int fd){
    struct Flags{
        int flag;
        char* name;
    }flags[] = {
        {O_RDONLY,"O_RDONLY"},
        {O_WRONLY,"O_WRONLY"},
        {O_RDWR,"O_RDWR"},
        {O_APPEND,"O_APPEND"},
        {O_ASYNC,"O_ASYNC"},
        {O_CLOEXEC,"O_CLOEXEC"},
        {O_SYNC,"O_SYNC"}
    };
    int flags = fcntl(fd,F_GETFL);
    for(int i=0;i<sizeof(flags)/sizeof(flags[0]);i++){
        if(flags[i].flag&flag)
            printf("%s\n",flags[i].name);
    }
}
int main(){
    int fd = open("A.TXT",O_WRONLY|O_RDONLY|O_SYNC|O_CLOEXEC);
    fcntl(fd,F_SETFL,O_ASYNC);
    file_flags(fd);
    close(fd);
}

int fcntl(int fd, int cmd, struct* flock);

  • Lock the file, so that the whole file, or part of it, can be accessed.
  • cmd
    • F_GETLK Gets Lock Information
    • F_SETLK Setting Lock
    • F_SETLKW Test Lock
  • Read lock and read lock do not conflict, read lock and write lock conflict, write lock and write lock conflict
  • Locking does not make other processes unable to open files or operate, but users must abide by the lock agreement to ensure that the files are not mixed (warning lock)
struct flock {
               ...
               short l_type;    /* Type of lock: F_RDLCK,
                                   F_WRLCK, F_UNLCK */
               short l_whence;  /* How to interpret l_start:
                                   SEEK_SET, SEEK_CUR, SEEK_END */
               off_t l_start;   /* Starting offset for lock */
               off_t l_len;     /* Number of bytes to lock */
               pid_t l_pid;     /* PID of process blocking our lock
                                   (set by F_GETLK and F_OFD_GETLK) */
               ...
           };
#include <...>

int rlock(int fd){
    struct flock lock = {F_RDLOCK,SEEK_SET,0,0,-1};
    return fcntl(fd,f_SETLK,&lock);
}

int wlock(int fd){
    struct flock lock = {F_WRLOCK,SEEK_SET,0,0,-1};
    return fcntl(fd,f_SETLK,&lock);
}

void show_lock(int fd){
    struct flock lock = {};
    printf("Acquisition locks%s\n",fcntl(fd,F_GETLK,&lock)?"fail":"Success");
    if(lock.l_type == F_UNLCK){
        printf("No lock\n");
    }else{
        printf("Locking process:%d\n",lock.l_pid);
        printf("Lock type:%s\n",lock.l_type == F_RDLOCK?"Read lock":"Write lock");
        printf("From documents");
        switch(lock.l_whence){
            case SEEK_SET:printf("Start with the document");break;
            case SEEK_CUR:printf("From the current position");break;
            case SEEK_END:printf("From the end of the document");break;
        }
        if(lock.l_start > 0){
            printf("Right shift%lu Begin with a byte",lock.l_start);
        }else if(lock.l_start < 0){
            printf("Left shift%lu Begin with a byte",lock.l_start);
        }

        if(lock.len){
            printf("Lock up%lu Bytes\n",lock.l_len);
        }
        else{
            printf("Lock to the end of the file\n");
        }
    }
}

int main(){
    int fd = open("a.txt",O_RDWR);
    printf("%d\n",rlock(fd));
    printf("%d\n",getpid());
    getchar();

}

Keywords: Linux less

Added by kikidonc on Sat, 27 Jul 2019 10:21:34 +0300