fwrite() and signals

I’ve only been doing “maintenance” coding in C for the last couple years
or so, so forgive me if this is a stupid question, but:

I’m trying to figure out how signals affect the fwrite() function.
Whenever I try to write more than 1 object, though, I get an errno of
1012 and a status of 0, even though it’s clear by looking at the file
created, that it wrote more than one object (the size is off by a few
hundred to a few thousand bytes depending on the size of bigthing).
This happens whether a signal goes off during the fwrite or not. But if
I write 1 object, whether or not the signal goes off, I get a good
completion (errno 0, and status 1).

Here’s the code:

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

#define NUMBIGTHINGS 2

struct
{
char byte1;
char byte2;
char byte3;
char bigarray1[1024][1024][10];
char bigarray2[1024][1024][10];
char bigarray3[1024][1024][10];
} bigthing[NUMBIGTHINGS];

int status = 0;

void main()
{
FILE *fp;

void signal_handler(); // Signal Handler Proto

errno = 0;

// Establish Signal Handler for the SIGALRM signal

if ( signal (SIGALRM, signal_handler) == SIG_ERR )
{
perror( “Can’t establish SIGALRM handler” );
exit(0);
}

// Set the SIGALRM to go of in N seconds
alarm(10);

if ( (fp = fopen(“test_fwrite.dat”, “w+”)) == NULL )
{
perror( “Can’t open file” );
exit(0);
}

printf (“size of bigthing is %d\n”, sizeof(bigthing));

status = fwrite(&bigthing[0], sizeof(bigthing), NUMBIGTHINGS, fp);

if (status < NUMBIGTHINGS)
printf (“Errno = %d, fwrite status = %d\n”, errno, status);
else
{
printf (“Seems to have written all objects, status = %d\n”,
status);
printf (“errno = %d\n”, errno);
}

fclose(fp);
}

static void signal_handler ()
{
printf (“Singal handler entered, fwrite status = %d, errno = %d\n”,
status, errno);
return;
}

“J. Scott Franko” <jsfranko@switch.com> wrote in message
news:39B5705A.66B51C9E@switch.com

I’ve only been doing “maintenance” coding in C for the last couple years
or so, so forgive me if this is a stupid question, but:

I’m trying to figure out how signals affect the fwrite() function.
Whenever I try to write more than 1 object, though, I get an errno of
1012 and a status of 0, even though it’s clear by looking at the file
created, that it wrote more than one object (the size is off by a few
hundred to a few thousand bytes depending on the size of bigthing).
This happens whether a signal goes off during the fwrite or not. But if
I write 1 object, whether or not the signal goes off, I get a good
completion (errno 0, and status 1).

Fwrite is buffer so write you do in the function are not necesseraly
flush into the file.

Your fwrite is doing an illegal access. See my comments below in your
code


About the crash,

Here’s the code:

#include <sys/types.h
#include <sys/stat.h
#include <fcntl.h
#include <stdio.h
#include <signal.h
#include <errno.h

#define NUMBIGTHINGS 2

struct foo
{
char byte1;
char byte2;
char byte3;
char bigarray1[1024][1024][10];
char bigarray2[1024][1024][10];
char bigarray3[1024][1024][10];
} bigthing[NUMBIGTHINGS];

int status = 0;

sizeof( bigthing ) is equal to the whole “object” but because
of NUMBIGTHINK you’re sending twice the size of the object.
So fwrite is trying to access data beyond the object, causing a fault

status = fwrite(&bigthing[0], sizeof(bigthing), NUMBIGTHINGS, fp);

Better is:
status = fwrite(&bigthing[0], sizeof(struct foo), NUMBIGTHINGS, fp);





static void signal_handler ()
{

printf is not SIGNAL safe, you could get bitten by this

printf (“Singal handler entered, fwrite status = %d, errno = %d\n”,
status, errno);
return;
}
\

Please do not post to two newsgroups, makes us crazy.

“J. Scott Franko” <jsfranko@switch.com> wrote in message
news:39B5705A.66B51C9E@switch.com

I’ve only been doing “maintenance” coding in C for the last couple years
or so, so forgive me if this is a stupid question, but:

I’m trying to figure out how signals affect the fwrite() function.
Whenever I try to write more than 1 object, though, I get an errno of
1012 and a status of 0, even though it’s clear by looking at the file
created, that it wrote more than one object (the size is off by a few
hundred to a few thousand bytes depending on the size of bigthing).
This happens whether a signal goes off during the fwrite or not. But if
I write 1 object, whether or not the signal goes off, I get a good
completion (errno 0, and status 1).

Here’s the code:

#include <sys/types.h
#include <sys/stat.h
#include <fcntl.h
#include <stdio.h
#include <signal.h
#include <errno.h

#define NUMBIGTHINGS 2

struct
{
char byte1;
char byte2;
char byte3;
char bigarray1[1024][1024][10];
char bigarray2[1024][1024][10];
char bigarray3[1024][1024][10];
} bigthing[NUMBIGTHINGS];

int status = 0;

void main()
{
FILE *fp;

void signal_handler(); // Signal Handler Proto

errno = 0;

// Establish Signal Handler for the SIGALRM signal

if ( signal (SIGALRM, signal_handler) == SIG_ERR )
{
perror( “Can’t establish SIGALRM handler” );
exit(0);
}

// Set the SIGALRM to go of in N seconds
alarm(10);

if ( (fp = fopen(“test_fwrite.dat”, “w+”)) == NULL )
{
perror( “Can’t open file” );
exit(0);
}

printf (“size of bigthing is %d\n”, sizeof(bigthing));

status = fwrite(&bigthing[0], sizeof(bigthing), NUMBIGTHINGS, fp);

if (status < NUMBIGTHINGS)
printf (“Errno = %d, fwrite status = %d\n”, errno, status);
else
{
printf (“Seems to have written all objects, status = %d\n”,
status);
printf (“errno = %d\n”, errno);
}

fclose(fp);
}

static void signal_handler ()
{
printf (“Singal handler entered, fwrite status = %d, errno = %d\n”,
status, errno);
return;
}
\

Mario Charest wrote:

Please do not post to two newsgroups, makes us crazy.

Sorry. Way I figured it, some people read qdn, some read comp.os, some read
both. I wanted to give my questions the broadest possible coverage, so that I
might get many answers. I’ll quit though.

Scott

Right, that was my stupid mistake. sizeof(bigthing) was the size of the whole
array of structs, right? I did as you suggested, and named the struct, so I
could sizeof(struct…), and it worked fine.

Closing the file at the end of the program should flush the buffer into the
file, write?

In any case, I am now getting the sizeof(bigthing) equal to the size of the
file, using sizeof(struct bigstruct) in the fwrite call. It now writes more
than one object without error.

The results seems to say that a signal handler that returns has no affect on
the fwrite function. It seems to pick up where it left off perfectly, and
doesn’t give the EINTR error as many of the io functions do.

I have a file that is getting corrupted by an fwrite call very rarely, and
that was my lead to see if it would be causing the problem. Now I guess I had
better look at the calculated length being passed to fwrite (no sizeof used in
the real problem).

Thanks for your help!

Scott

Mario Charest wrote:

“J. Scott Franko” <> jsfranko@switch.com> > wrote in message
news:> 39B5705A.66B51C9E@switch.com> …
I’ve only been doing “maintenance” coding in C for the last couple years
or so, so forgive me if this is a stupid question, but:

I’m trying to figure out how signals affect the fwrite() function.
Whenever I try to write more than 1 object, though, I get an errno of
1012 and a status of 0, even though it’s clear by looking at the file
created, that it wrote more than one object (the size is off by a few
hundred to a few thousand bytes depending on the size of bigthing).
This happens whether a signal goes off during the fwrite or not. But if
I write 1 object, whether or not the signal goes off, I get a good
completion (errno 0, and status 1).


Fwrite is buffer so write you do in the function are not necesseraly
flush into the file.

Your fwrite is doing an illegal access. See my comments below in your
code

About the crash,
Here’s the code:

#include <sys/types.h
#include <sys/stat.h
#include <fcntl.h
#include <stdio.h
#include <signal.h
#include <errno.h

#define NUMBIGTHINGS 2

struct foo
{
char byte1;
char byte2;
char byte3;
char bigarray1[1024][1024][10];
char bigarray2[1024][1024][10];
char bigarray3[1024][1024][10];
} bigthing[NUMBIGTHINGS];

int status = 0;

sizeof( bigthing ) is equal to the whole “object” but because
of NUMBIGTHINK you’re sending twice the size of the object.
So fwrite is trying to access data beyond the object, causing a fault

status = fwrite(&bigthing[0], sizeof(bigthing), NUMBIGTHINGS, fp);

Better is:
status = fwrite(&bigthing[0], sizeof(struct foo), NUMBIGTHINGS, fp);

static void signal_handler ()
{

printf is not SIGNAL safe, you could get bitten by this

printf (“Singal handler entered, fwrite status = %d, errno = %d\n”,
status, errno);
return;
}
\

“J. Scott Franko” <jsfranko@switch.com> wrote in message
news:39B68872.66A52973@switch.com

Mario Charest wrote:

Please do not post to two newsgroups, makes us crazy.


Sorry. Way I figured it, some people read qdn, some read comp.os, some
read
both. I wanted to give my questions the broadest possible coverage, so
that I
might get many answers.

Yeah that’s a good point, I understand that but for guys like me that tries
to answer as much question as I can it makes me nuts. Maybe I’ll get
use to it :wink:

I’ll quit though.

Scott

It might be useful to designate comp.os.qnx primarily for
configuration/setup/installation problems and qdn for development type
problems. To make this work, somebody (QSSL?) should publish an FAQ
periodically in both comp.os.qnx and qdn.news so that newbies get the picture.
It seems QSSL people are reading both. Another approach is, if QSSL doesn’t
want to track comp.os.qnx is to make it (comp.os.qnx) function primarily like
the old user2user sections of quics. Still a periodic FAQ would be needed for
newbies.

Mario Charest wrote:

“J. Scott Franko” <> jsfranko@switch.com> > wrote in message
news:> 39B68872.66A52973@switch.com> …


Mario Charest wrote:

Please do not post to two newsgroups, makes us crazy.


Sorry. Way I figured it, some people read qdn, some read comp.os, some
read
both. I wanted to give my questions the broadest possible coverage, so
that I
might get many answers.

Yeah that’s a good point, I understand that but for guys like me that tries
to answer as much question as I can it makes me nuts. Maybe I’ll get
use to it > :wink:

I’ll quit though.

Scott