LINUX.ORG.RU

если успелось прочитаться что-то то вернется то что успелось прочитаться, если вообще ничего не успел прочитать то вернется NULL

кстати помоему fgets вывалится только в том случае если read вернет <= 0, а это не обязательно произойдет при сигнале, т/к read может успеть прочитать немного

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

2lg(*) (12.10.2004 15:11:18):

> если успелось прочитаться что-то то вернется то что успелось прочитаться, если вообще ничего не успел прочитать то вернется NULL

А ты уверен?

Есть мнение (не авторитетное), что стримы из stdio в Линухе сами заботятся об EINTR...

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

>> если успелось прочитаться что-то то вернется то что успелось прочитаться, если вообще ничего не
успел прочитать то вернется NULL

> А ты уверен?

нет :), Но это ведь легко проверить

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

FILE *fp1, *fp2;

void
mysh(int s)
{
        fputs("done\n", fp2);
        printf("%s\n", __FUNCTION__);
}

int
main()
{
        char str[1024+1];
        char *p;
        int fds[2];

        if (pipe(fds))
                return -1;

        fp1 = fdopen(fds[0], "r");
        fp2 = fdopen(fds[1], "w");
        if (fp1 == NULL || fp2 == NULL)
                return -2;

        setbuf(fp1, NULL);
        setbuf(fp2, NULL);

        fputs("test .. ", fp2);

        signal(SIGALRM, mysh);
        alarm(1);

        printf("reading ..\n");
        p = fgets(str, 1024, fp1);

        printf("p=%p\n", p);
        if (p)
                printf("str='%s'\n", str);

        return 0;
}

$ gcc -Wall -o ft ft.c
$ ./ft
reading ..
mysh
p=0xbfbff4fc
str='test .. done
'

строка прочиталась полностью

> Есть мнение (не авторитетное), что стримы из stdio в Линухе сами заботятся об EINTR...

хмм, может быть

lg ★★
()
Ответ на: комментарий от Die-Hard

У меня вопрос воник на почве когда я вместо результата получил NULL & EINTR. Ситуацию EINTR создал сигнал SIG_CHLD. Понятно откудова взявшийся.

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

Не знаю.

Я всегда получал сигнал раньше чем успевал что-то прочитать, или после того как всё вычитано(одна строчка).

Так вот меня и заинтересовало можно ли на ето залаживатся или ето случайное совпадение и когдато сигнал попадёт посредине.

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

lg(*) (13.10.2004 11:40:09):

> значит мой тест не совсем корректный?

Твой тест показывает лишь, что fgets хочет читать до '\n'. В этом тесте read не перебивается сигналом.

Die-Hard ★★★★★
()
Ответ на: комментарий от lg

Немного поиграл с тестом lg: #include <signal.h> #include <unistd.h> #include <stdio.h> FILE *fp1, *fp2; void mysh(int s) { /* fputs("done\n", fp2);*/ printf("%s:%d\n", __FUNCTION__,s); } int main() { char str[1024+1]; char *p; int fds[2]; if (pipe(fds)) return -1; if(fork()==0){ printf("aslept\n"); sleep (2); printf("Bye\n"); return(1); } fp1 = fdopen(fds[0], "r"); fp2 = fdopen(fds[1], "w"); if (fp1 == NULL || fp2 == NULL) return -2; setbuf(fp1, NULL); setbuf(fp2, NULL); /*fputs("test .. ", fp2);*/ signal(SIGALRM, mysh); signal(SIGCHLD, mysh); alarm(1); printf("reading ..\n"); p = fgets(str, 1024, fp1); printf("p=%p\n", p); if (p) printf("str='%s'\n", str); return 0; } Результат: aslept reading .. mysh:14 Bye mysh:17 и висим, ждем че-нибудь с пайпа. Т.е., fgets НЕ перебивается ни SIGALRM, ни SIGCHLD. Т.е., у cvv не SIGCHLD перебил fgets, а в чем-то другом причина.

Die-Hard ★★★★★
()
Ответ на: комментарий от lg

Форматирование съехало, повторяю:
Немного поиграл с тестом lg:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

FILE *fp1, *fp2;

void
mysh(int s)
{
/*        fputs("done\n", fp2);*/
        printf("%s:%d\n", __FUNCTION__,s);
}

int
main()
{
        char str[1024+1];
        char *p;
        int fds[2];

        if (pipe(fds))
                return -1;
        if(fork()==0){
           printf("aslept\n");
           sleep (2);
           printf("Bye\n");
           return(1);
        }
        fp1 = fdopen(fds[0], "r");
        fp2 = fdopen(fds[1], "w");
        if (fp1 == NULL || fp2 == NULL)
                return -2;

        setbuf(fp1, NULL);
        setbuf(fp2, NULL);

       /*fputs("test .. ", fp2);*/

        signal(SIGALRM, mysh);
        signal(SIGCHLD, mysh);
        alarm(1);

        printf("reading ..\n");
        p = fgets(str, 1024, fp1);

        printf("p=%p\n", p);
        if (p)
                printf("str='%s'\n", str);

        return 0;
}


Результат:

aslept
reading ..
mysh:14
Bye
mysh:17
и висим, ждем че-нибудь с пайпа.

Т.е., fgets  НЕ перебивается ни SIGALRM, ни SIGCHLD.

Т.е., у cvv не SIGCHLD перебил fgets, а в чем-то другом причина.

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

все таки мой первый пост правильный...

fgets продолжает висеть т/к read продолжает висеть ..

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

void
mysh(int s)
{
        printf("%s\n", __FUNCTION__);
}

int
main()
{
        char str[1024+1];
        int rb;
        int fds[2];

        if (pipe(fds))
                return -1;

        signal(SIGALRM, mysh);
        alarm(1);

        printf("reading ..\n");
        rb = read (fds[0], str, 1);

        printf("rb=%d\n", rb);
        if (rb>0) {
                str[rb] = '\0';
                printf("str='%s'\n", str);
        }

        return 0;
}


lg ★★
()
Ответ на: комментарий от Die-Hard

>Т.е., fgets НЕ перебивается ни SIGALRM, ни SIGCHLD.

>Т.е., у cvv не SIGCHLD перебил fgets, а в чем-то другом причина.

Сейчас не спорю потому что логи strace уже прибил.

Хотя если удастся вытащить из ЦВС нужный срез то может воссоздам ситуацию

cvv ★★★★★
() автор топика
Ответ на: комментарий от Die-Hard

>Т.е., fgets  НЕ перебивается ни SIGALRM, ни SIGCHLD.

>Т.е., у cvv не SIGCHLD перебил fgets, а в чем-то другом причина.

Значит здесь кажись вы ошиблись вот лог strace в котором чётко видно что read вызванный fgets перебивается именно SIGCHLD

кстати заворачивание read выполняю я вручную

pipe([8, 10])                           = 0                                                                                                  
fork()                                  = 6229                                                                                               
close(10)                               = 0                                                                                                  
fstat64(8, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0                                                                                       
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40023000                                                    
read(8, 0x40023000, 4096)               = ? ERESTARTSYS (To be restarted)                                                                    
--- SIGCHLD (Child exited) ---                                                                                                               
wait4(6228, NULL, WUNTRACED, NULL)      = -1 ECHILD (No child processes)                                                                     
sigreturn()                             = ? (mask now [RTMIN])                                                                               
time([1097673187])                      = 1097673187                                                                                         
getpid()                                = 6221                                                                                               
writev(2, [{"./login2db[6221]: error reading pipe to \"date \'+%Y.%m.%d %H:%M:%S\'\" : \363\311\323\324\305\315\316\331\312 \327\331\332\317\
327 \320\322\305\322\327\301\316", 93}, {"\n", 1}], 2) = 94                                                                                  
rt_sigaction(SIGPIPE, {0x40c87b50, [], 0x4000000}, {SIG_IGN}, 8) = 0                                                                         
send(4, "<11>\357\313\324 13 16:13:07 ./login2db[6221]: error reading pipe to \"date \'+%Y.%m.%d %H:%M:%S\'\" : \363\311\323\324\305\315\316\
331\312 \327\331\332\317\327 \320\322\305\322\327\301\316", 113, 0) = 113                                                                    
rt_sigaction(SIGPIPE, {SIG_IGN}, NULL, 8) = 0                                                                                                
read(8, "2004.10.13 16:13:07\n", 4096)  = 20                                                                                                 
close(8)                                = 0                                                                                                  
wait4(6229, [WIFEXITED(s) && WEXITSTATUS(s) == 0], 0, NULL) = 6229  

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

cvv(*) (13.10.2004 17:27:21):

> ...read вызванный fgets перебивается именно SIGCHLD

Конечно read() перебьется SIGCHLDом. Но fgets его рестартует.

Die-Hard ★★★★★
()
Ответ на: комментарий от lg

lg (*) (13.10.2004 19:58:58):

> ...похоже что только в том случае если fgets успел что-то прочитать до этого

А как же быть с моим тестом? Там fgets тупо висит на пайпе, ждет, ничего не прочитав, и ни один сигнал его не перебивает,,,

Вечером в исходники посмотрю, если успею...

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

>> ...read вызванный fgets перебивается именно SIGCHLD

>Конечно read() перебьется SIGCHLDом. Но fgets его рестартует.

Если fgets его рестартует то откудова мне знать что возникла ситуация EINTR??? А я там везде записываю (write(2,); send(4,)) О том что fgets вместо рестарта read вернул мне NULL & EINTR.

Повторяю ещё раз read(тоесть fgets) перестартовую _я_ и притом вручную !!!

Кстати я бы сильно обрадовался если б заставил fgets перестартовывать read(). Может чё подскажите???

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

>а нелегче было в libc залезть

Ты имееш ввиду LD_DEBUG???

Не знаю. Мне чёто пока strace больше по душе

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

cvv (*) (14.10.2004 11:21:32):

> Повторяю ещё раз read(тоесть fgets) перестартовую _я_ 
> и притом вручную !!! 

Странно. У меня fgets сам read  перестартовывает.
Вот:
$./a.out
aslept
reading ..
mysh:14
Bye
mysh:17
(висим)

Вот что дает strace ./a.out >/dev/null:

read(3, 0x80498df, 1)                   = ? ERESTARTSYS (To be restarted)
--- SIGALRM (Alarm clock) ---
sigreturn()                             = ? (mask now [])
read(3, 0x80498df, 1)                   = ? ERESTARTSYS (To be restarted)
--- SIGCHLD (Child exited) ---
sigreturn()                             = ? (mask now [])
read(3, 

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

(текст программы я приводил раньше).

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

cvv
А обработчик как у тебя на сигчилд поставлен ?
Может быть ты флагами указал что не надо рестартить
сисколы после сигнала ? Вот они у тебя и не рестартятся...

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