linuxの下のCプログラム:自分で一回しか開けられないようにします
1つのCプログラムは、自分が1回しか開くことができず、2つのプログラムで同じファイルを同時に操作することができない.ロック実装
プログラムコードは以下の通り(コンパイル環境,RedHat,G++)
END
プログラムコードは以下の通り(コンパイル環境,RedHat,G++)
#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...
");
//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!
");
}
return 0;
}
END