#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #include <string.h> union semun{ int val; struct semid_ds* buf; unsigned short *array; struct seminfo *__buf; }; int main(int argc, char* argv[]) { if(argc != 2) { printf("no argument, for help %s -h\n", argv[0]); return -1; } if(strcmp(argv[1], "-h") == 0) { printf("To use, type in the file name as an argument\nExample: '%s file'\n",argv[0]); return -1; } FILE* file = fopen(argv[1], "w"); if(file == NULL) { printf("Can't create file\n"); return -1; } //открытие буфера if(close(open("./SHARED", O_RDWR, S_IRUSR | S_IWUSR))) { printf("Can't open SHARED\n"); return -1; } key_t buff_key = ftok("./SHARED", 1); int buff_id = shmget(buff_key, 1024, 0); char* buff = (char *)shmat(buff_id, NULL, 0); //открыте семафоров //0 - свободно сегментов; 1 - занято сегментов //2 - защита; 3 - конец файла; 4 - для записи без остатка if(close(open("./SEM", O_RDWR, S_IRUSR | S_IWUSR))) { printf("Can't open SEM\n"); return -1; } key_t sem_key = ftok("./SEM", 1); int sem_id = semget(sem_key, 0, 0); semun init; count =5; printf("count = %d", count); //заготовки структур для semop() sembuf sem_wait = {0, -1, 0}; sembuf sem_post = {0, 1, 0}; //запись в файл int last = 0; while(semctl(sem_id, 1, GETVAL) != 0 || semctl(sem_id, 3, GETVAL) != 0) { //дождемся наличия заполенных буферов и уменьшим на 1 sem_wait.sem_num = 1; semop(sem_id, &sem_wait, 1); //защита sem_wait.sem_num = 2; semop(sem_id, &sem_wait, 1); //увеличим число пустых буферов на 1 sem_post.sem_num = 0; semop(sem_id, &sem_post, 1); //запись нового блока в файл if(semctl(sem_id, 4, GETVAL) != 0 && semctl(sem_id, 3, GETVAL) == 0 && semctl(sem_id, 1, GETVAL) == 0) { } else if(semctl(sem_id, 4, GETVAL) != 0 && semctl(sem_id, 3, GETVAL) == 0 && semctl(sem_id, 1, GETVAL) == 1) { last = semctl(sem_id, 4, GETVAL); fwrite(buff, last, 1, file); } else { fwrite(buff, 128, 1, file); } //сдвиг буфера на влево memmove(buff, buff+128, 896); //защита sem_post.sem_num = 2; semop(sem_id, &sem_post, 1); } shmdt(buff); fclose(file); } 

From the administrator starts, so does not want. I can not understand where he climbs where it is not necessary .. I changed everything to tips. But the problem does not go away from this. Here I think right with the rights I create. Creates these files shared and sem another program like this:

 open("./SHARED", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR) 
  • What are the owner and rights of the SHARED and SEM files? - ߊߚߤߘ

2 answers 2

Your problem is mainly in the use of an ugly approach to error handling:

You are trying to look into the crystal ball:

 if(close(open("./SHARED", O_RDWR, S_IRUSR | S_IWUSR))) { printf("Can't open SHARED\n"); return -1; } 

After that, without any control of the return codes, you do your dirty deed:

 key_t buff_key = ftok("./SHARED", 1); 

Get rid of the crystal ball - analyze the return value of ftok and errorno according to the documentation

  • Hmm I do not understand a lot, well, I open shared write and read ... If not, it will go to error. Or do I need to control? If it went to -1, then also close and leave, and why then monitor ftok and check it? - Anrey
  • @Anrey - you need to check ftok, and not a hypothetical possibility to open something there. No one will guarantee that open works completely like ftok on all systems. No one will guarantee that the file will not be deleted between open and ftok calls. - gbg
  • @ changed everywhere now check. But it is just now control the error. But when you start it is still a segmentation error. corrected your question from below, please see - Anrey
  • @Anrey next step - make a debugging output (with stdout [fflush (stdout)] buffer flush) before each system call - localize the error. - gbg
 if(close(open("./SHARED", O_RDWR, S_IRUSR | S_IWUSR))) { printf("Can't open SHARED\n"); return -1; } 

Try to avoid similar constructions, such constructions often lead to unpredictable results, difficult search for errors and difficult to read.

  int rc; rc = open("./SHARED", O_RDWR, S_IRUSR | S_IWUSR); if(rc == -1){ printf("Can't open SHARED\n"); return -1; } 

Chu more code, but you can explicitly localize the error.