Deje que el programa tenga solo una instancia ejecutándose en lenguaje C

#include<stdio.h>   //standard buffered input/output
#include<fcntl.h>   //file control options
#include<stdlib.h>  //standard library definitions
#include<errno.h>   //system error numbers
#include<unistd.h>  //standard symbolic constants and types
#include<string.h>  //string operations
 
#define LOCKFILE ".lock"
 
using namespace std;
 
int lockfile(int fd)
{
    struct flock fl;
    //#include<fcntl.h>
    //The structure flock describes a file lock. 
    //It shall include the following numbers:
    //  short  l_type    Type of lock; F_RDLCK, F_WRLCK, F_UNLCK
    //  short  l_whence  Flag for starting offset
    //  off_t  l_start   Relative offset in bytes
    //  off_t  l_len     Size; if 0 then until EOF
    //  pid_t  l_pid     Process ID of the process holding the lock
    
    fl.l_type = F_WRLCK;
    fl.l_start = 0;
    fl.l_whence = SEEK_SET;
    fl.l_len = 0;
 
    return fcntl(fd, F_SETLK, &fl);
    //#include<unistd.h>
    //#include<fcntl.h>
    //int fcntl(int fd, int cmd, ... /* arg */ );
    //0.fcntl() performs one of the operations described below on the open file 
    //  descriptor [fd]. The operation is determined by [cmd].
    //1.fcntl() can take an optional third argument. Whether or not this argument 
    //  is required is determined by [cmd]. The required argument type is indicated
    //  in parentheses after each [cmd] name, or [void] is specified if the argument
    //  is not required.
}
 
int already_running(void)
{
    int fd;
    char buf[16];
 
    fd = open(LOCKFILE, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    //#include<sys/types.h>
    //#include<sys/stat.h>
    //#include<fcntl.h>
    //int open(const char *pathname, int flags, mode_t mode);
    //0.Given a [pathname] for a file, open() returns a file descriptor, a small, 
    //  non-negative integer for use in subsequent system calls. The file descriptor
    //  returned by a successful cal will be the lowest-numbered file descriptor
    //  not currently open for the process
    //1.The argument [flags] must include one of the following access modes:
    //  O_RDONLY, OWRONLY, or O_RDWR. These request opening the file read-only,
    //  write-only, or read/write, respectively
    //2.[mode] specifies the permissions to use in case a new file is created.
    //  This argument must be supplied when O_CREAT is specified in [flags]; if
    //  O_CREAT is not sepcified the [mode] is ignored
    //  0) S_IRUSR 00400 user has read permission
    //  1) S_IWUSR 00200 user has write permission
    //  2) S_IRGRP 00040 group has read permission
    //  3) S_IROTH 00004 others have read permission
 
    if(fd < 0)
    {
        fprintf(stderr, "FAILED TO OPEN FILE" LOCKFILE);
        exit(1);
    }
 
    if(lockfile(fd) < 0)
    {
        //errno: number of last error
        //#include<errno.h>
        //0.EACCES: Permission denied (POSIX.1)
        //1.EAGAIN: Resource temporarily unavailable (POSIX.1)
        if(EACCES == errno || EAGAIN == errno)
        {
            close(fd);
            return 1;
        }
 
        fprintf(stderr, "FAILED TO LOCK FILE" LOCKFILE);
        exit(1);
    }
 
    ftruncate(fd, 0);
    //truncate a file to a specified length
    //#include<unistd.h>
    //#include<sys/types.h>
    //int ftruncate(int fd, off_t length);
    //0.The truncate() and ftruncate() functions cause the regular file named by [path]
    //  or referenced by [fd] to be truncated to a size of precisely [length] bytes.
    //1.If the file previously was larger than this size, the extra data is lost.
    //  If the file previously was shorter, it is extended and the extended part reads
    //  as null bytes ('\0').
 
    sprintf(buf, "%ld", (long)getpid());
    write(fd, buf, strlen(buf) + 1);
    return 0;
}
 
int main()
{
    if(already_running())
    {
        fprintf(stderr, "PROGRAM ALREADY RUNNING...\n");
        //stdin, stdout, stderr: standard I/O streams
        //#include<stdio.h>
        //extern FILE *stdin;
        //extern FILE *stdout;
        //extern FILE *stderr;
        //0.Under normal circumstances every Unix program has three streams opened for
        //  it when it starts up, one for input, one for output, and one for printing
        //  diagnostic or error messages. These are typically attached to the user's
        //  terminal.
        exit(0);
    }
 
    while(true)
    {
        printf("INPUT CTRL+C TO KILL ME!\n");
    }
    
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/star871016/article/details/108549614
Recomendado
Clasificación