LINUX.ORG.RU

Помогите разобраться с программой!

 , ,


0

3

Вот задание. Процесс 1 открывает файл, порождает потомка 2, пишет в файл N байт и посылает сигнал SIG1 процессу 2. Процесс 2 по сигналу SIG1 читает данные, выводит их на экран и завершается. Если сигнал от процесса 1 не поступит в течение M секунд, процесс 2 начинает считывать данные по сигналу SIGALRM.
Вот как я пыталась его реализовать:

#include <stdio.h>
#include <signal.h>
#include <wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

int f_in, fd, ppid, pid, N, M, count=0;

void wakeup ()                         //
{
        signal(SIGALRM, wakeup);
        printf("Wake up!\n");
}

void sleeptime (int timeout)
{
        signal(SIGALRM, wakeup);
        alarm(timeout);
        pause();
}

void sigper(int n)
{
        signal(SIGUSR1,sigper);
        printf("KOL-VO BYTE: %d\n", count);
        write(f_in,"1",1);
        kill(pid,SIGUSR1);
}
void sigchail(int n)
{
        signal(SIGUSR1, sigchail);
        write(f_in,"2",1);
        kill(ppid,SIGCHLD);
}
int main(int argc, char*argv[])
{
        ppid=getpid();
        if((f_in= open(argv[1],O_RDONLY))<0){
                ERR("Can't open %s\n",argv[1]);
        }
        N = atoi(argv[2]);

        if (pid=fork()<0){
                ERR("Can't fork");
        }
        else if(fork_pid>0){
                signal(SIGUSR1,sigper);
                kill(pid,SIGUSR1);
        }
        else {
                pause();
                signal(SIGUSR1,sigchail);
                _exit(-1);
        }
        read(1,&inp,1);
        putchar(inp);
        close(f_in);
        printf("1");
        return(0);
}

Заранее благодарю за помощь!

Не в тот раздел запостил же.

pon4ik ★★★★★
()

Заранее благодарю

Первая созданная тема: 30.04.20 15:51:10

Всегда, пожалуйста.

anonymous
()

Хорошо, я вижу какой-то код, я сегодня очень добрый и не буду бурчать, что это не в Job, но в чём ошибка? Ты предлагаешь мне это качать и собирать/ковыряться в твоей лабе просто так? Хоть ошибку назови и скажи что не так в твоей попытке. Вангую какие-то проблемы с синхронизациями потоков, рекомендую пойти почитать про семафоры, мьютексы, пайпы и иже с ними.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
  1. Выложите пример, который хотя бы компилируется.

  2. Задайте вопрос по инструкции.

anonymous
()

Вот что случилось, когда я попытался это собрать:

xms@XMs-desktop ~/projects/tests $ gcc -Wall -Wextra -Werror -pedantic bullshit.c 
bullshit.c: В функции «sigper»:
bullshit.c:28:17: ошибка: неиспользуемый параметр «n» [-Werror=unused-parameter]
   28 | void sigper(int n)
      |             ~~~~^
bullshit.c: В функции «sigchail»:
bullshit.c:38:19: ошибка: неиспользуемый параметр «n» [-Werror=unused-parameter]
   38 | void sigchail(int n)
      |               ~~~~^
bullshit.c: В функции «main»:
bullshit.c:52:5: ошибка: неявная декларация функции «ERR» [-Werror=implicit-function-declaration]
   52 |     ERR(«Can't open %s\n»,argv[1]);
      |     ^~~
bullshit.c:54:6: ошибка: неявная декларация функции «atoi» [-Werror=implicit-function-declaration]
   54 |  N = atoi(argv[2]);
      |      ^~~~
bullshit.c:56:6: ошибка: присваивание, используемое как логическое выражение, рекомендуется  [-Werror=parentheses]
   56 |  if (pid=fork()<0)
      |      ^~~
bullshit.c:60:10: ошибка: «fork_pid» не описан (первое использование в этой функции)
   60 |  else if(fork_pid>0)
      |          ^~~~~~~~
bullshit.c:60:10: замечание: сообщение о каждом неописанном идентификаторе выдается один раз в каждой функции, где он встречается
bullshit.c:71:10: ошибка: «inp» не описан (первое использование в этой функции); имелось в виду «int»?
   71 |  read(1,&inp,1);
      |          ^~~
      |          int
bullshit.c:47:14: ошибка: неиспользуемый параметр «argc» [-Werror=unused-parameter]
   47 | int main(int argc, char*argv[])
      |          ~~~~^~~~
cc1: все предупреждения считаются ошибками
xms@XMs-desktop ~/projects/tests $ 

Я могу, конечно, и исправить эти ошибки, и задание выполнить, но цель заданий не в этом. Исправь код так, чтобы он собирался (да, со всеми этими флагами), а потом сформулируй вопрос. Я сейчас вижу просто кучу кода, половина которого даже не используется.

Если тебе нужна подсказка, с чего начать, возьми такую последовательность:

  1. Сотри всё;
  2. Напиши прогу, которая просто запишет в файл сколько-то байт (например, строку «hello, world»);
  3. Добавь к ней чтение из файла и вывод этого на экран;
  4. Разнеси всё по функциям;
  5. Добавь fork() и разнеси по процессам;
  6. Во втором потоке жди сигнала SIGUSR1 с помощью, допустим, sigtimedwait();
  7. Добавь смену ожидаемого сигнала, если таймер сработал.

На каждом этапе кроме первого обеспечь полную работоспособность приложения (т. е. оно должно собираться и выводить на экран то, что требуется)

XMs ★★★★★
()

А тебе не кажется, что если даже с таким простым заданием возникли сложности, то это не твоё?

(Hint: Достаточно прочесть несколько глав о программировании Unix, чтобы решить её.)

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

ошибка: неиспользуемый параметр «n» [-Werror=unused-parameter]
Я могу, конечно, и исправить эти ошибки

Ну-ка, ну-ка, продемонстрируй скилл. c89 или c99 на выбор. Я лажаю на таком всегда

DllMain
()

А в чем проблема?

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

KOJIN4ECTBO_6AuTOB

ТС, ты просишь помочь разобраться. Какие конкретно места тебе непонятны, в чем требуется помощь?

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от XMs

Глядя на тебя, решил таки шлангом собрать, может ТС-у поможет, он побольше срёт варнингами.

$ clang -Weverything bullshit.c
bullshit.c:9:32: warning: no previous extern declaration for non-static variable 'count'
      [-Wmissing-variable-declarations]
int f_in, fd, ppid, pid, N, M, count=0;
                               ^
bullshit.c:11:6: warning: no previous prototype for function 'wakeup' [-Wmissing-prototypes]
void wakeup ()                         //
     ^
bullshit.c:20:15: warning: implicit conversion changes signedness: 'int' to 'unsigned int'
      [-Wsign-conversion]
        alarm(timeout);
        ~~~~~ ^~~~~~~
bullshit.c:17:6: warning: no previous prototype for function 'sleeptime' [-Wmissing-prototypes]
void sleeptime (int timeout)
     ^
bullshit.c:24:17: warning: unused parameter 'n' [-Wunused-parameter]
void sigper(int n)
                ^
bullshit.c:24:6: warning: no previous prototype for function 'sigper' [-Wmissing-prototypes]
void sigper(int n)
     ^
bullshit.c:31:19: warning: unused parameter 'n' [-Wunused-parameter]
void sigchail(int n)
                  ^
bullshit.c:31:6: warning: no previous prototype for function 'sigchail' [-Wmissing-prototypes]
void sigchail(int n)
     ^
bullshit.c:41:17: warning: implicit declaration of function 'ERR' is invalid in C99
      [-Wimplicit-function-declaration]
                ERR("Can't open %s\n",argv[1]);
                ^
bullshit.c:41:17: warning: this function declaration is not a prototype [-Wstrict-prototypes]
bullshit.c:43:13: warning: implicit declaration of function 'atoi' is invalid in C99
      [-Wimplicit-function-declaration]
        N = atoi(argv[2]);
            ^
bullshit.c:43:13: warning: this function declaration is not a prototype [-Wstrict-prototypes]
bullshit.c:45:16: warning: using the result of an assignment as a condition without parentheses
      [-Wparentheses]
        if (pid=fork()<0){
            ~~~^~~~~~~~~
bullshit.c:45:16: note: place parentheses around the assignment to silence this warning
        if (pid=fork()<0){
               ^
            (           )
bullshit.c:45:16: note: use '==' to turn this assignment into an equality comparison
        if (pid=fork()<0){
               ^
               ==
bullshit.c:46:17: warning: implicit declaration of function 'ERR' is invalid in C99
      [-Wimplicit-function-declaration]
                ERR("Can't fork");
                ^
bullshit.c:48:17: error: use of undeclared identifier 'fork_pid'
        else if(fork_pid>0){
                ^
bullshit.c:57:17: error: use of undeclared identifier 'inp'
        read(1,&inp,1);
                ^
bullshit.c:58:17: error: use of undeclared identifier 'inp'
        putchar(inp);
                ^
bullshit.c:37:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc, char*argv[])
             ^
bullshit.c:9:5: warning: no previous extern declaration for non-static variable 'f_in'
      [-Wmissing-variable-declarations]
int f_in, fd, ppid, pid, N, M, count=0;
    ^
bullshit.c:9:11: warning: no previous extern declaration for non-static variable 'fd'
      [-Wmissing-variable-declarations]
int f_in, fd, ppid, pid, N, M, count=0;
          ^
bullshit.c:9:15: warning: no previous extern declaration for non-static variable 'ppid'
      [-Wmissing-variable-declarations]
int f_in, fd, ppid, pid, N, M, count=0;
              ^
bullshit.c:9:21: warning: no previous extern declaration for non-static variable 'pid'
      [-Wmissing-variable-declarations]
int f_in, fd, ppid, pid, N, M, count=0;
                    ^
bullshit.c:9:26: warning: no previous extern declaration for non-static variable 'N'
      [-Wmissing-variable-declarations]
int f_in, fd, ppid, pid, N, M, count=0;
                         ^
bullshit.c:9:29: warning: no previous extern declaration for non-static variable 'M'
      [-Wmissing-variable-declarations]
int f_in, fd, ppid, pid, N, M, count=0;
                            ^
21 warnings and 3 errors generated.

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

дрочево ради дрочева, эти неиспользуемые параметры ничем не вредят

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

нет, Weverything включает вообще все проверки, которые есть в компиляторе.

В gcc такого аналога нет :(

И не хотят добавлять: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66293

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

Не комментируешь имя параметра, оставляя тип, а вообще удаляешь. Т. е. не void foo(int /*bar*/), а void foo(/*int bar*/)

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

включает вообще все проверки, которые есть в компиляторе

Полезно. Надо будет в CI-скрипты добавить сборку шлангом, раз такое дело

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

но там обработчик сигнала же

Действительно, не увидел сразу. Тогда, если аргумент не нужен, можно добавить какой-нибудь ассерт или просто сделать так:

void foo(int bar)
  { 
	if (bar)
	  {}

	…
  }

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

Глядя на тебя, решил таки шлангом собрать, может ТС-у поможет, он побольше срёт варнингами.

он побольше срёт варнингами.

Нет, очевидно. К тому же ты родился херню какую-то нелепую - там половина ворнингов ошибочные срабатывания. И ошибочные же предположения. Зачем вы пытаетесь перепащивать из из интернета всякую херню и врубать её? Какой «implicit conversion», какой «no previous extern declaration for non-static variable»? Такого не существует.

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

Полезно. Надо будет в CI-скрипты добавить сборку шлангом, раз такое дело

Да, уровень невежества населения лора не перестаёт меня удивлять.

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

Почему-то думал, что такое только со старыми gcc работает, но нет… ok, запомнил

На тебе еще на будущее «перегруженный» макрос UNUSED:

#define UNUSED1(a)                      ((void)(a))
#define UNUSED2(a, b)                   ((void)(a),(void)(b))
#define UNUSED3(a, b, c)                ((void)(a),(void)(b),(void)(c))
#define UNUSED4(a, b, c, d)             ((void)(a),(void)(b),(void)(c),(void)(d))
#define UNUSED5(a, b, c, d, e)          ((void)(a),(void)(b),(void)(c),(void)(d),(void)(e))
#define UNUSED6(a, b, c, d, e, f)       ((void)(a),(void)(b),(void)(c),(void)(d),(void)(e),(void)(f))
#define UNUSED7(a, b, c, d, e, f, g)    ((void)(a),(void)(b),(void)(c),(void)(d),(void)(e),(void)(f),(void)(g))
#define UNUSED8(a, b, c, d, e, f, g, h) ((void)(a),(void)(b),(void)(c),(void)(d),(void)(e),(void)(f),(void)(g),(void)(h))
#define GET_MACRO(a, b, c, d, e, f, g, h, macro, ...) macro
#define UNUSED(...) \
GET_MACRO(__VA_ARGS__, UNUSED8, UNUSED7, UNUSED6, UNUSED5, UNUSED4, UNUSED3, UNUSED2, UNUSED1)(__VA_ARGS__)

Можно вызывать с любым количеством параметров (от 1 до 8, если надо больше можешь добавить):

UNUSED(var);
UNUSED(var1, var2);
// и т.д.
anonymous
()
Ответ на: комментарий от XMs

Полезно. Надо будет в CI-скрипты добавить сборку шлангом, раз такое дело

pedantic там нахер не упёрся, лишь кучу мусора выбросит

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

вот, спросоня написал какую-то фигню, но тут кучка лишнего - я не писал с чистого листа, а просто исправил то, что было у тебя.
Только поудаляй лишний вывод и неиспользующиеся функции (wakeup, sleeptime и sigchail)

#include <stdio.h>
#include <signal.h>
#include <wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>

int f_in, fd, ppid, pid, N, M, count = 0;

void wakeup()			//
{
	signal(SIGALRM, wakeup);
	printf("Wake up!\n");
}

void sleeptime(int timeout)
{
	signal(SIGALRM, wakeup);
	alarm(timeout);
	pause();
}

void sigper(int n)
{
	char c;
printf("SIGNAL %d\n", n);
	if (n != SIGUSR1 && n != SIGALRM)
		return;

	while (read(f_in, &c, 1) == 1)
		write(1, &c, 1);
	kill(pid, SIGUSR1);
//	signal(SIGUSR1, sigper);
}

void sigchail(int n)
{
	write(f_in, "3", 1);
	kill(ppid, SIGCHLD);
//	signal(SIGUSR1, sigchail);
}

int main(int argc, char *argv[])
{
	int i = 0, ret;
	char inp;

	if (argc < 4) {
		printf("error: insuffucient arguments\n");
		return 1;
	}

	ppid = getpid();
	if ((f_in = open(argv[1], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
		printf("Can't open %s\n", argv[1]);
		return 1;
	}
	N = atoi(argv[2]);
	M = atoi(argv[3]);

	if ((pid = fork()) < 0) {
		printf("Can't fork\n");
		return 1;
	} else if (pid == 0) {
		do {
			ret = read(0, &inp, 1);
			if (inp == '\n' || ret <= 0)
				break;
			if (i < N)
				write(f_in, &inp, 1);
			i++;
		} while (ret > 0);
		lseek(f_in, 0, SEEK_SET);
		kill(pid, SIGUSR1);
	} else {
		signal(SIGUSR1, sigper);
		signal(SIGALRM, sigper);
		alarm(M);
		pause();
	}
	close(f_in);

	return (0);
}


p.s. ща меня закидают кучкой гнилых помидор и смачных какашек, но ты почитывай, там наверняка будут и полезные отзывы - это ЛОР, детка ;)

p.p.s. и не обижайся на местную братию, так-то они белые и пушистые :))

metawishmaster ★★★★★
()
Последнее исправление: metawishmaster (всего исправлений: 2)
Ответ на: комментарий от anonymous

-Werror

В школу сходи

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


Не ври - это не гцц, а какая-то окаменелость

xms@XMs-desktop ~/projects/tests $ gcc --version
gcc (Gentoo 9.3.0 p2) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
Это свободно распространяемое программное обеспечение. Условия копирования
приведены в исходных текстах.

  Без гарантии каких-либо качеств, включая 
коммерческую ценность и применимость для каких-либо целей.



xms@XMs-desktop ~/projects/tests $ 
XMs ★★★★★
()
Ответ на: комментарий от peregrine

Отлично, буду использовать. Благодарю за информацию

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

implicit conversion
Такого не существует

В твоей вселенной не существует неявного преобразования и связанных с ним ошибок? Речь не про конкретно этот случай, а вообще.


no previous extern declaration for non-static variable

В чём проблема? Если символ экспортируется, его стоит объявить как extern в каком-нибудь хедере либо добавить static, чтобы не экспортировать. Предпочитаешь не заморачиваться — дело твоё

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

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

Причём тут предупреждения? Werror как базовый флаг используют только явно альтернативно одарённые. Этот флаг имеет смысл только в рамках какой-то скриптухе, когда нужно получить код возврата - это в рамках всяких ci/cd-пайплайнов. Но флаг должен активироваться только в особом окружении.

Для разработки и как базовый флаг - это не нужно и вредно. И самое интересное - ты даже в рамках этих оправданий засыпался. Ведь если ты врубаешь Werror - ты игнорируешь предупреждения компилятора, делая из них ошибки. Если бы ты их не игнорировал - в Werror нету смысла исходя из твоих же слов.

К тому же, куда пропал педентик?

gcc (Gentoo 9.3.0 p2) 9.3.0 *.3.0

Это не важно.

gcc-10.0.1 (Gentoo 10.0.1_pre9999 p2, commit 691eeb65a01dab3084b6ce381737adf097bd2e65) 10.0.1 20200429 (experimental)

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

В твоей вселенной не существует неявного преобразования и связанных с ним ошибок?

Зачем ты начинаешь мазаться? Мазы твои нелепы. Проблему тебе описали - ты(или кто там) не зная нихрена включаешь непонятно что. И в этом твоя проблема.

Речь не про конкретно этот случай, а вообще.

Ты и тут засыпался. Ворнинги должны работать в любом случае. И именно поэтому врублено то, что врублено. Но всякие мамкины гении идут и перепащивают наборы флажков из интернета нихрена в них не понимая. Тебе дали умолчания и если какой-то флаг применим в общем случае - его и без тебя добавят.

Что-бы ты потом не мазался рассказывая о том, что «ну не в этом случае» и «не существует ошибок», о которых тебе никто не говорил.

Этот ворнинг не говорит об ошибках. Он лишь провоцирует колхозника заткнуть дыру явным кастом, что только скроет ошибку.

В чём проблема?

Описано выше.

Если символ экспортируется, его стоит объявить как extern в каком-нибудь хедере

Не стоит.

либо добавить static,

У меня -fwhole-program, но всё это неважно. Важно то, что этот ворнинг ничего не значит и смысла не имеет. Особенно вкупе с Werror

чтобы не экспортировать. Предпочитаешь не заморачиваться — дело твоё

Ещё раз, повторяю. Ворнинги должны иметь однозначный смысл - есть проблема. Данный ворнинг, как и предыдущий - этого смысла не несёт. Это дополнительные статические проверки, которые осмысленно интегрируются в определённые подходы к разработке.

К тебе это не относится. Ты просто врубил херню увиденную в интернете. И пытаешься показывать её другим. Тем, кому это нужно - всё это и без тебя знает. Ни ни тебе, ни студенты выше - это ненужно.

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

Но флаг должен активироваться только в особом окружении

С чего бы? Скорее уж так: этот флаг не должен активироваться в особом случае. Например, сборка у пользователя.


Для разработки и как базовый флаг - это не нужно и вредно

Почему? С любопытством изучу случаи, когда это вредно.


Ведь если ты врубаешь Werror - ты игнорируешь предупреждения компилятора, делая из них ошибки

/0. Делая из них ошибки я не могу игнорировать их, потому что сборка тупо не пройдёт. А вот не делая — шанс такой есть.


gcc-10.0.1 (Gentoo 10.0.1_pre9999 p2, commit 691eeb65a01dab3084b6ce381737adf097bd2e65) 10.0.1 20200429 (experimental)

Т. е. для тебя всё, что не -9999 — говно мамонта, я правильно понимаю?

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

ага или если чужая библиотека принимает коллбек, в котором ты не используешь некоторые параметры. ууух какой полезный при этом будет ворнинг

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

С чего бы? Скорее уж так: этот флаг не должен активироваться в особом случае. Например, сборка у пользователя.

Нет, очевидно. Основания для одного случая я привёл и сообщил, что для других случаев его нет. Ты не привёл ничего - все твои рассуждения не стоят ничего.

Почему? С любопытством изучу случаи, когда это вредно.

Потому что. Выше ты уже начал мазаться и рассказывать, что «а вот у пользователя». В любом случае это так не работает. Никто не имеет смысла до тех пор, пока смысл ты не определил, а ты его не определил.

/0. Делая из них ошибки я не могу игнорировать их, потому что сборка тупо не пройдёт. А вот не делая — шанс такой есть.

Ты очень слаб. Если ты не игнорируешь ворнинги - ты не игнорируешь ворнинги. Если тебе для отсутствия игнорирования недостаточно присутствия ворнингов - твоё утверждение ложно. Поэтому сразу пиши «я игнорирую ворнинги при сборке», зачем мажешься?

К том уже, ворнинги нужны для осмысленной работы с ними, превращая их в ошибки - ты просто пытаешься от них избавиться. Это умножает смысл существования их.

Т. е. для тебя всё, что не -9999 — говно мамонта, я правильно понимаю?

Изучи тему перед тем как нести херню. гцц развивается ветками, девятой ветке уже больше года. И от того, что тебя там 9.3, а не 9.0 - ничего не значит. К тому же 10 ветка для гцц фундаментальна. Правда это больше для С++, а не для си. Но и даже архитектурно там произведены так же фундаментальные изменения.

К тому же, сравнение было со шлангом, который по-сути такой же 9999.

К тому же десятый гцц не 9999.

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

Ну не используемые параметры имеют смысл. И использоваться он должен с unused, но колхозники ваяют какое-то нелепое бездарное говно с pedantic, который не работает и нахрен не нужен.

Правда в крестах с этим проще. Там база тип, а не идентификатор как в сишке.

Всё это неважно. В общем случае ворнинг имеет смысл. Если что-то передаётся - оно должно использоваться, почти всегда. В противном случае нахрена оно передаётся? Исключения есть - это всякое легаси и те самые «библиотека принимает коллбек», где сигнутуру определяет не реализация.

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

Этот ворнинг не говорит об ошибках. Он лишь провоцирует колхозника заткнуть дыру явным кастом, что только скроет ошибку.

Он провоцирует подумать. Если колхозник не умеет думать, программирование не для него.

Ещё раз, повторяю. Ворнинги должны иметь однозначный смысл - есть проблема.

Никто тебе ничего не должен. Когда какая-то фигня происходит сидишь и смотришь всё, что может быть полезно, включая все варнинги

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

на ночь глядя, окинул взглядом - если препод злой, лучше убрать «return 1» после «printf(„Can't fork\n“);», иначе файловый дескриптор не закроется программой. ну и переменная ppid нигде не используется, так что:

#include <stdio.h>
#include <signal.h>
#include <wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>

int f_in, fd, pid, N, M;

void sigper(int n)
{
	char c;

	if (n != SIGUSR1 && n != SIGALRM)
		return;

	printf("SIG%s\n", n == SIGUSR1 ? "USR1" : "ALRM");

	while (read(f_in, &c, 1) == 1)
		write(1, &c, 1);
	kill(pid, SIGUSR1);
}

int main(int argc, char *argv[])
{
	int i = 0;
	char inp;
	ssize_t ret;

	if (argc < 4) {
		printf("error: insuffucient arguments\n");
		return 1;
	}

	if ((f_in = open(argv[1], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
		printf("Can't open %s\n", argv[1]);
		return 1;
	}
	N = atoi(argv[2]);
	M = atoi(argv[3]);

	if ((pid = fork()) < 0) {
		printf("Can't fork\n");
	} else if (pid == 0) {
		do {
			ret = read(0, &inp, 1);
			if (inp == '\n' || ret <= 0)
				break;
			if (i < N)
				write(f_in, &inp, 1);
			i++;
		} while (ret > 0);
		lseek(f_in, 0, SEEK_SET);
		kill(pid, SIGUSR1);
	} else {
		signal(SIGUSR1, sigper);
		signal(SIGALRM, sigper);
		alarm(M);
		pause();
	}
	close(f_in);

	return (0);
}

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

иначе файловый дескриптор не закроется программой

лол что? завершение процесса всё закрывает

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

«файловый дескриптор закроется программой» и «файловый дескриптор закроется операционной системой» чуток разные вещи для преподавателей.

metawishmaster ★★★★★
()

пардон муа, пропустил - «kill(pid, SIGUSR1);» в конце sigper не нужен

metawishmaster ★★★★★
()

пардон муа, пропустил - «kill(pid, SIGUSR1);» в конце sigper не нужен

а если без него, то какая-то фигня (line feed) добавляется в конец :-\


в общем, дай еще сроку

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

пропускаю '\r' и escape-символ, который каким-то чудом оказывался в конце:

#include <stdio.h>
#include <signal.h>
#include <wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>

int f_in, pid, N, M;

void sigper(int n)
{
	char c;

	if (n != SIGUSR1 && n != SIGALRM)
		return;

	printf("SIG%s\n", n == SIGUSR1 ? "USR1" : "ALRM");

	while (read(f_in, &c, 1) == 1)
		write(1, &c, 1);
}

int main(int argc, char *argv[])
{
	int i = 0;
	char inp;
	ssize_t ret;

	if (argc < 4) {
		printf("error: insuffucient arguments\n");
		return 1;
	}

	if ((f_in = open(argv[1], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
		printf("Can't open %s\n", argv[1]);
		return 1;
	}
	N = atoi(argv[2]);
	M = atoi(argv[3]);

	if ((pid = fork()) < 0) {
		printf("Can't fork\n");
	} else if (pid == 0) {
		do {
			ret = read(0, &inp, 1);
			if (inp == '\r' || inp == '\n' || ret <= 0)
				break;
			if (i < N && inp != 27) {
				write(f_in, &inp, 1);
				i++;
			}
		} while (ret > 0);
		lseek(f_in, 0, SEEK_SET);
		kill(pid, SIGUSR1);
	} else {
		signal(SIGUSR1, sigper);
		signal(SIGALRM, sigper);
		alarm(M);
		pause();
	}
	close(f_in);

	return (0);
}


надеюсь, все, но если будут вопросы - спрашивай

metawishmaster ★★★★★
()
Последнее исправление: metawishmaster (всего исправлений: 5)
Ответ на: комментарий от anonymous

Зачем ты пишешь лабы за студентов? Какой в этом смысл?

да заняться сейчас особо не чем

// и кстати к стыду своему, о существовании функции pause - я узнал только когда разбиралл код ТС'а, а до этого всякие костыли городил

да и не работает как надо пока это мое поделие.... чую я забыл что-то, но не могу понять что

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

да заняться сейчас особо не чем

Не дак не пасти сюда код. Просто пиши что поменял без когда. Смысл то лабы в том, что-бы пациент сам сделал, а ты лишаешь его этой возможности.

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