LINUX.ORG.RU

Segmentation fault core dumped

 , , ,


0

1

Здравствуйте, есть задание: First получает со стандартного потока информацию о файлах каталога, и, во-первых, выводит на экран (в консоль) строки о тех из них, у которых установлен бит запуска владельцем; во-вторых, при помощи FIFO передает размер каждого из таких файлов second’у, который суммирует значения и выводит полученное значение на экран. Проблема в том, что при чтении файла в second.c возникает переполнение. first.c:

#ifndef _FILE_OFFSET_BITS
    #define _FILE_OFFSET_BITS 64
#endif
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

uint64_t total_size_files(char *path){
    char buf[PATH_MAX + 1], buf1[PATH_MAX + 1];
    struct stat file_stats;
    DIR *dirp;
    struct dirent* dent;
    uint64_t sum = 0;
    dirp = opendir(path);
    if(!dirp){
        perror("opendir()");
        return -1;
    }
    do{
        dent = readdir(dirp);
        if(dent > 0){
            printf("%s - ", dent->d_name);
            snprintf(buf1, PATH_MAX, "%s/%s", path, dent->d_name);
            if(!realpath(buf1, buf)){
                printf("realpath(): %s", strerror(errno));
                continue;
            }
            if(!stat(buf, &file_stats)){
                printf("%" PRIu64 " bytes\n", (uint64_t)file_stats.st_size);
                sum += file_stats.st_size;
            }else{
                printf("stat(): %s\n", strerror(errno));
            }
        }else if(dent < 0){
            printf("readdir(): %s", strerror(errno));
        }
    }while(dent);
    closedir(dirp);
    printf("Size of %ld is %" PRIu64 " bytes\n", sum);
    return sum;
}

int main(){
    char *path = ".";
    //printf("Size of %ld is %" PRIu64 " bytes\n", path, total_size_files(path));
    int fd, result;
    uint64_t size;
    char resstring[1000000];
    char name[]="MYFIFO.fifo";
    (void)umask(0);
    if(mknod(name, S_IFIFO | 0666, 0) < 0){
        printf("Can\'t create FIFO\n");
        exit(-1);
    }
    if((result = fork()) < 0){
        printf("Can\'t fork child\n");
        exit(-1);
    } else if (result > 0) {
        if((fd = open(name, O_WRONLY)) < 0){
            printf("Can\'t open FIFO for writing\n");
            exit(-1);
        }
        size = write(fd, total_size_files(path), sizeof(uint64_t));
        close(fd);
        printf("Parent exit\n");
        close(fd);
    }
    return 0;
}
[\code=C]


second.c:


#ifndef _FILE_OFFSET_BITS
    #define _FILE_OFFSET_BITS 64
#endif
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(){
    int fd, result;
    size_t size;
    char name[]="MYFIFO.fifo";
 if((fd = open(name, O_RDONLY)) < 0){
        printf("Can\'t open FIFO for reading\n");
        exit(-1);
    }
        size = read(fd, &result, sizeof(uint64_t));
        if(size < 0){
            printf("Can\'t read string\n");
            exit(-1);
        }
    /* Печатаем прочитанную строку */
    printf("%ld\n",size);
    /* Закрываем входной поток и завершаем работу */
    close(fd);
    return 0;
}

[\code=C]


Последнее исправление: Qwertyr (всего исправлений: 1)

    size_t size;
    size = read(fd, &result, sizeof(uint64_t));
    printf("%s\n",size);

Если тебе не понятно, что здесь не так, то программирование — не твоё.

gremlin_the_red ★★★★★
()
Ответ на: комментарий от gremlin_the_red

Извините, ошибся, так было


char readbuffer[1000];
size = read(fd, readbuffer, 1000);
printf("%s\n", readbuffer);
[\code=C]

Qwertyr
() автор топика

printf(«%s\n»,size);

Мегаэпичненько. Идите и прочтите в документации что именно значит %s и чем он отличается от %d (например)

Nastishka ★★★★★
()
Ответ на: комментарий от Nastishka

Идите и прочтите в документации что именно значит %s и чем он отличается от %d (например)

От %lu тогда уж. И вообще, любая IDE с clang-бакендом выплюнет ворнинг на такой printf.

dimgel ★★★★★
()
Ответ на: комментарий от Qwertyr

Исправил в обеих программах.

Пока не исправил.

anonymous
()

компилируй всегда с опциями -Wall -Wextra -Wpedantic и все твои неточности будут налицо

IvanR ★★★
()
Ответ на: комментарий от Qwertyr

Потому что у тебя в сендере тоже хлам. write() получает вторым параметром УКАЗАТЕЛЬ НА БУФЕР. А у тебя там целое число - которое интерпретируется как указатель и указывает неведомо куда.

Nastishka ★★★★★
()
Ответ на: комментарий от anonymous

Жуть. Мерзость какая. Мало бардака с этими «переносимыми» типами, так оказывается ещё stdlib поддержкой typedef-ов засирают. А для ptrdiff_t тоже какая-нибудь буковка в printf есть?

dimgel ★★★★★
()
Последнее исправление: dimgel (всего исправлений: 1)
Ответ на: комментарий от Qwertyr

У тебя на руках корка, там все ответы. Компилируй с отладочными символами и делай после сегфолта:

$ coredumpctl gdb your_app
bt

у тебя перед глазми будет стек вызовов перед падением с номерами строк.

kvpfs ★★
()
Ответ на: комментарий от dimgel

Жуть. Мерзость какая.

Четырёхзвёздочный говнокодер as is…

anonymous
()
Ответ на: комментарий от Qwertyr

Ты специально всех троллишь? Что такое стековая (локальная) переменная тебе не объясняли на уроках? И почему нельзя возвращать наружу её адрес?

Nastishka ★★★★★
()
Ответ на: комментарий от dimgel

Жуть. Мерзость какая. Мало бардака с этими «переносимыми» типами, так оказывается ещё stdlib поддержкой typedef-ов засирают. А для ptrdiff_t тоже какая-нибудь буковка в printf есть?.

%td

https://gcc.godbolt.org/z/vej451cnP

вот тут таблица есть: https://en.cppreference.com/w/c/io/fprintf

fsb4000 ★★★★★
()
Ответ на: комментарий от Qwertyr

учить C ради курсовой тоже не очень хочется

Эммм… учить матан ради зачета по матану не очень зочется… учить анатомию ради диплома хирурга не очень хочется…

Может тогда просто сменить род деятельности?

AntonI ★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от fsb4000

size_t может быть unsigned long long, а unsigned long - 32 битный тип.

  1. В этом случае каст type{value} матюгнётся, в отличие от type(value) или (type)value. Я тут не так давно как раз на эту тему спрашивал.

  2. Вот он, вышеупомянутый бардак. Вот что в расте хорошо сделали, так это целочисленные типы.

dimgel ★★★★★
()
Последнее исправление: dimgel (всего исправлений: 1)
Ответ на: комментарий от Nastishka

Бывает так, что на С надо сдавать лабы, а под лекции/семинары по С часов нет, потому что препода нет. И вот скубент такой вопрошает: а нас не учили С. На что препод отвечает: это оочень странно, но я-то тут причем, тогда учите С сами с книгой в библиотеке. И вот скубент почитал книгу, и пробует что-то закодировать - а оно сегфолтится…

seiken ★★★★★
()
Ответ на: комментарий от dimgel

Вот он, вышеупомянутый бардак.

Бардак только в твоём кочане. Ты от безграмотности наподставлял костыли и думаешь что только так — костыльно — и возможно писать.

anonymous
()
Ответ на: комментарий от anonymous

Мнение какого-то анонима в интернете очень важно для нас, оставайтесь на линии.

dimgel ★★★★★
()
Ответ на: комментарий от dimgel

Из последних сил надеюсь, что у человека проснётся совесть.

hobbit ★★★★★
()
Ответ на: комментарий от seiken

на С надо сдавать лабы, а под лекции/семинары по С часов нет, потому что препода нет.

Жуть какая. В моё время такого не было. Что лабы опережали лекции — бывало иногда, но в этом случае преподы были в курсе и старались как-то разрулить.

препод отвечает: это оочень странно, но я-то тут причем

Жуть какая №2. Лектор и лаборант по идее должны быть с одной кафедры и быть в курсе, в чём проблема.

В общем, либо общая деградация налицо, либо это особенность конкретных вузов. В оба варианта охотно верю, к сожалению.

hobbit ★★★★★
()
Ответ на: комментарий от Nastishka
uint64_t temp = total_size_files(path);
...
write(fd, &tmp, sizeof(uint64_t))
Qwertyr
() автор топика

Еще вопрос такой, как можно проверить, установлен ли бит запуска владельцем? st_uid?

Qwertyr
() автор топика
Ответ на: комментарий от dimgel

Обычно я явно кастую: myprintf(«%lu», ulong{size}).

И как это у тебя в Си работает?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.