What header files should I include to use the flock function? - c

What header files should I include to use the flock function in C?
Errors I get during compilation:
[Error] 'LOCK_EX' was not declared in this scope
[Error] 'LOCK_NB' was not declared in this scope
[Error] 'flock' was not declared in this scope
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
int fd;
if (argc < 2) {
printf("Kullanım: %s dosya_adi\n", argv[0]);
return 1;
}
fd = open(argv[1], O_WRONLY);
if (fd == -1) {
perror("Dosya açma hatası");
return 1;
}
if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
perror("Dosya kilidi hatası");
return 1;
}
printf("Dosya kilitlendi\n");
return 0;
}

On Linux you want to:
#include <sys/file.h>

Related

named mmap without Disk IO

I wanted to use the POSIX standard mmap as if shmat had an id, they share the same shared memory.
mmap seems to normally use fd=-1 when using MAP_ANON, and in this case it is said to be valid when inheriting from a child process.
I wanted to ensure the same behavior in the spawn method. Then I can use named shared memory, but I wish it didn't do DISK IO at all.
I think MAP_ANON is essential because I want to always guarantee the speed of RAM without leaving any files on the DISK in case of an unexpected shutdown.
So is it reasonable to provide fd!=-1 while being MAP_ANON|MAP_SHARED?
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
int main (int argc, char *argv[])
{
struct stat sb;
char *p;
int fd;
fd = shm_open("test", O_RDWR | O_CREAT, 0600);
if (fd == -1) {
perror("open");
return 1;
}
size_t len = 128;
if (ftruncate(fd, len) == -1) {
perror("ftruncate");
return 1;
}
p = (char*)mmap(0, len, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, fd, 0);
if (p == MAP_FAILED){
perror("mmap");
return 1;
}
if (close(fd)==-1) {
perror("close");
return 1;
}
for (int i = 0; i < len; i++) {
putchar(p[i]);
}
if (munmap(p, len) == -1) {
perror("munmap");
return 1;
}
if(shm_unlink("test")) {
perror("unlink");
return 1;
}
fprintf(stderr,"\n");
return 0;
}

Reading a line and removing Spaces from matrix in a file

OK so I manage to write to the file char by char but it writes twice the numbers and it it still write it with spaces. Any advice and solution?
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
extern int errno;
#define MAX_LEN 18
int main(int argc, char *argv[]) {
int fd[2], des, bytes, target;
char buffer[161];
int fdr, fdw; // file descriptors
char c;
fdr = open(argv[1], O_RDONLY); // open files
fdw = open("gg.txt", O_WRONLY | O_CREAT);
if (fdr < 0 || fdw < 0) {
perror("failed to open input or output files");
exit(EXIT_FAILURE);
}
while (read(fdr, &c, 1)) { // read/write a single char from/to the files
if (c != ' ' && c != EOF) {
if (write(fdw, &c, 1) != 1) {
perror("write() failed");
exit(EXIT_FAILURE);
}
} // echo char to stdout
}
close(fdr); // close the files
close(fdw);
exit(EXIT_SUCCESS);
}
EDIT SECTION
hey again,
i managed to read the file and write it to new one without spaces but i'm trying to insert the values to matrix but im getting an error trying to open the new file.
i have changed the permissions
fdw = open("gg.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
the function
void removeSpaces(int matrix[SIZE][SIZE],int fdr, int fdw) {
char c;
char matBuffer={0};
while (read(fdr, &c, 1)) // read/write a single char
{ // from/to the files
if (c != ' ') {
if (write(fdw, &c, 1) != 1) {
perror("write() failed");
exit(EXIT_FAILURE);
}
}
}
int i;
int j;
int k=0;
while(read(fdw, &matBuffer, 1))
{
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
matrix[i][j]=matBuffer-'0';
k++;
}
k=0;
}
}
}
The whole program
// C program to illustrate
// open system call
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#define MAX_LEN 18
#define SIZE 9
void removeSpaces(int matrix[SIZE][SIZE],int fdr, int fdw) {
char c;
char matBuffer={0};
while (read(fdr, &c, 1)) // read/write a single char
{ // from/to the files
if (c != ' ') {
if (write(fdw, &c, 1) != 1) {
perror("write() failed");
exit(EXIT_FAILURE);
}
}
}
int i;
int j;
int k=0;
while(read(fdw, &matBuffer, 1))
{
for(i=0;i<SIZE;i++)
{
for(j=0;j<SIZE;j++)
{
matrix[i][j]=matBuffer-'0';
k++;
}
k=0;
}
}
}
int is_safe(int matrix[9][9],int n, int r, int c)
{
int i,j;
//checking in row
for(i=0;i<9;i++)
{
//there is a cell with same value
if(matrix[r][i] == n)
return 0;
}
//checking column
for(i=0;i<SIZE;i++)
{
//there is a cell with the value equal to i
if(matrix[i][c] == n)
return 0;
}
//checking sub matrix
int row_start = (r/3)*3;
int col_start = (c/3)*3;
for(i=row_start;i<row_start+3;i++)
{
for(j=col_start;j<col_start+3;j++)
{
if(matrix[i][j]==n)
return 0;
}
}
return 1;
}
int main(int argc, char * argv[]) {
int pipe_descs[2];
int matrix[SIZE][SIZE];
int fdr, fdw; // file descriptors
int i,j;
/* if (pipe(pipe_descs) == -1) {
fprintf(stderr, "cannot open");
exit(1);
}
pid_t status = fork();
if(status ==0 )
{
}*/
fdr = open(argv[1], O_RDONLY); // open files
fdw = open("gg.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fdr < 0 || fdw < 0) { //validation for error
perror("failed to open input or output files");
exit(EXIT_FAILURE);
}
removeSpaces(matrix,fdr, fdw);
for(i=0; i<9; i++){ /* Iterate of each row */
for(j=0; j<9; j++){ /* In each row, go over each col element */
printf("%c ",matrix[i][j]); /* Print each row element */
}
printf("\n"); /* Finish a row, start a new line */
}
close(fdr); // close the files
close(fdw);
exit(EXIT_SUCCESS);
}
There are multiple problems in the code:
you do not test for read errors, read can return -1 for error, which would not stop the while loop.
testing c != EOF is meaningless. EOF is returned by getc() to indicate end of stream or input error, read indicates these conditions in its return value, c is always a byte value if read succeeded and returned 1.
gg.txt is not truncated by open with the given flags. Chances are you are overwriting the beginning of the file and for some reason the file is longer from previous attempts and still contains previously written data. You must also pass the mode bits for the file creation as the third argument to open. Use this:
// open the file for writing, truncate if it exists or create with
// read/write permission for user, read permission for group and others
fdw = open("gg.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
the comment // echo char to stdout does not seem to refer to any code.
Here is a corrected version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int fdr, fdw; // file descriptors
char c;
fdr = open(argv[1], O_RDONLY); // open files
if (fdr < 0) {
fprintf(stderr, "failed to open input file %s: %s\n", argv[1], strerror(errno));
return EXIT_FAILURE;
}
// open the output file for writing, truncate if it exists or create with
// read/write permission for user, read permission for group and others
fdw = open("gg.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fdw < 0) {
fprintf(stderr, "failed to open output file %s: %s\n", "gg.txt", strerror(errno));
return EXIT_FAILURE;
}
// read/write a single char from/to the files
while (read(fdr, &c, 1) == 1) {
if (c != ' ') {
if (write(fdw, &c, 1) != 1) {
perror("write() failed");
return EXIT_FAILURE;
}
}
}
close(fdr); // close the files
close(fdw);
return EXIT_SUCCESS;
}

ioctl failed: Operation not permitted - block layout of my files

I want to view the contents of a file at block level.
Given a file, i want to know how many blocks it has and what is the size if each one.
my problem is when i run it i get this error:
FIBMAP ioctl failed: Operation not permitted
Also when i'm comliling i get the following warning:
warning: implicit declaration of function ‘ioctl’ [-Wimplicit-function-declaration]
if (ioctl(fd, FIGETBSZ, &blocksize)) {
I am using the following code.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <assert.h>
#include <linux/fs.h>
int main(int argc, char **argv)
{
int fd, i, block, blocksize, blkcnt;
struct stat st;
assert(argv[1] != NULL);
fd = open(argv[1], O_RDONLY);
if (fd <= 0) {
perror("error opening file");
exit(EXIT_FAILURE);
}
if (ioctl(fd, FIGETBSZ, &blocksize)) {
perror("FIBMAP ioctl failed");
exit(EXIT_FAILURE);
}
if (fstat(fd, &st)) {
perror("fstat error");
exit(EXIT_FAILURE);
}
blkcnt = (st.st_size + blocksize - 1) / blocksize;
for (i = 0; i < blkcnt; i++) {
block = i;
if (ioctl(fd, FIBMAP, &block)) {
perror("FIBMAP ioctl failed");
}
printf("%3d %10d\n", i, block);
}
close(fd);
return 0;
}
Can anyone please explain me what is the problem in this code.
You should run that program as root.
ioctl(FIBMAP) needs the CAP_SYS_RAWIO capability.

Confused with the st_ino?

#include "stdio.h"
#include <sys/stat.h>
int
main(int argc, char *argv[]) {
struct stat buf;
//int fd = open("./fstatat.c", "r");
//int fd2 = fstatat(fd, "a.txt", &buf, 0);
//printf("%d\n", buf.st_ino);
stat("./fstatat.c", &buf);
printf("%d\n", buf.st_ino);
return 0;
}
if i use the function stat to get a struct stat, the st_ino is the same as the i-node number with the ls -i.
1305609
[inmove#localhost chapter-four]$ ls -i
1305607 a.txt 1305606 fstatat.bin 1305609 fstatat.c 1305605 tmp.txt
buf if i use the function fstat, the st_ino is always the 4195126.
anyone can tell me why this happen?
The problem is that you are not using open correctly and don't check the return values for errors. So you are then calling fstat on the invalid file descriptor value -1 returned by open on error, which will also fail and not touch buf at all, so the uninitialized garbage in the struct is still there (4195126, hex 0x400336 smells a lot like a return address of a previous function call still being on the stack or something like this.)
As davmac already pointed out, the second parameter to open must be a list of flags, which are numeric. Check the docs.
So, the correct code would be:
#include "stdio.h"
#include <sys/stat.h>
#include <sys/fcntl.h> // for the O_RDONLY constant
#include <errno.h> // for error output
int main(int argc, char *argv[]) {
struct stat buf;
int fd = open("./fstatat.c", O_RDONLY);
if(fd == -1) {
printf("Error calling open: %s\n", strerror(errno));
} else {
if(fstat(fd, &buf) == -1) {
printf("Error calling fstat: %s\n", strerror(errno));
} else {
printf("%d\n", buf.st_ino);
if(close(fd) == -1) {
printf("Error calling close: %s\n", strerror(errno));
}
}
}
return 0;
}

How to distinguish a file pointer points to a file or a directory?

When I do:
FILE * fp = fopen("filename", "r");`
How can I know the file pointer fp points to a file or a directory? Because I think both cases the fp won't be null. What can I do?
The environment is UNIX.
i've found this near by:
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
int main (int argc, char *argv[]) {
int status;
struct stat st_buf;
status = stat ("your path", &st_buf);
if (status != 0) {
printf ("Error, errno = %d\n", errno);
return 1;
}
// Tell us what it is then exit.
if (S_ISREG (st_buf.st_mode)) {
printf ("%s is a regular file.\n", argv[1]);
}
if (S_ISDIR (st_buf.st_mode)) {
printf ("%s is a directory.\n", argv[1]);
}
}
You could use fileno() to get the file discriptor for the already opened file, and then use fstat() on the file descriptor to have a struct stat returned.
It's member st_mode carries info on the file.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
FILE * pf = fopen("filename", "r");
if (NULL == pf)
{
perror("fopen() failed");
exit(1);
}
{
int fd = fileno(pf);
struct stat ss = {0};
if (-1 == fstat(fd, &ss))
{
perror("fstat() failed");
exit(1);
}
if (S_ISREG (ss.st_mode))
{
printf ("Is's a file.\n");
}
else if (S_ISDIR (ss.st_mode))
{
printf ("It's a directory.\n");
}
}
return 0;
}
On Windows, Call GetFileAttributes, and check for the FILE_ATTRIBUTE_DIRECTORY attribute.
Check this and this.

Resources