devctl and errno

Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

  1. devctl returns errno.
  2. devctl returns -1 and sets errno.
  3. devctl returns errno and sets errno.

Michael

“Michael Tasche” <michael.tasche@esd-electronics.com> wrote in message
news:3CB69FD3.7ED05F61@esd-electronics.com

Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the ernno
code is returned by devctl.

Discussion about beta should be done in the appropriate channel.

Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);

fprintf is probably reset by fprintf.

exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

  1. devctl returns errno.
  2. devctl returns -1 and sets errno.
  3. devctl returns errno and sets errno.

Michael

Mario Charest schrieb:

“Michael Tasche” <> michael.tasche@esd-electronics.com> > wrote in message
news:> 3CB69FD3.7ED05F61@esd-electronics.com> …
Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the ernno
code is returned by devctl.

Discussion about beta should be done in the appropriate channel.

Sorry, i do not know, if this behavior happens only on the beta.

Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);

fprintf is probably reset by fprintf.
You mean: errno is probably reset by fprintf.?

No, only if fprintf produces an error!
But anyway, this is the sample code from the docu.
I tested this without the fprintf.

Michael

exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

  1. devctl returns errno.
  2. devctl returns -1 and sets errno.
  3. devctl returns errno and sets errno.

Michael

Michael Tasche <michael.tasche@esd-electronics.com> wrote:

Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

The example is bad.

It should probably be something like:

if (error = devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS: %s.\n”, strerror(error));
exit(EXIT_FAILURE);
}

  1. devctl returns errno value.

This is the behaviour.

devctl() never touches the global errno.

I’ll pass this on to our docs people – though they’ll probably see
it in the thread here too.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs <dagibbs@qnx.com> wrote:

Michael Tasche <> michael.tasche@esd-electronics.com> > wrote:
Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

The example is bad.

Hey Dave, why is the example bad? If fprintf() succeeds, then it should not touch
errno, right? I use the fprintf()/perror() all the time… Are you saying it’s
bad in the case of devctl()/fprintf()/perror(), or in all general cases of fprintf()/perror()?

Cheers,
-RK

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

Well, your right “IF” fprintf() succeeds it won’t touch errno. I just think
it’s good programming practice to save errno before doing ANY other function
that might change it.

I don’t know what Dave meant by errno won’t be set. I think he’s talking
about a different issue.

“Robert Krten” <nospam89@parse.com> wrote in message
news:a96urd$lnv$1@inn.qnx.com

David Gibbs <> dagibbs@qnx.com> > wrote:
Michael Tasche <> michael.tasche@esd-electronics.com> > wrote:
Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the
ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

The example is bad.

Hey Dave, why is the example bad? If fprintf() succeeds, then it should
not touch
errno, right? I use the fprintf()/perror() all the time… Are you
saying it’s
bad in the case of devctl()/fprintf()/perror(), or in all general cases of
fprintf()/perror()?

Cheers,
-RK

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.

I think he means just that, errno will not be set. If you look at the rest
of the docs for devctl, under the returns section it will return EOK/EAGAIN
etc. So if the code was changed to something like the following it may
work a bit better for ya:

if ((rc=devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL)))
{
fprintf(stderr, “Error setting RTS: %s\n”, strerror(rc));
exit(EXIT_FAILURE);
}

-Peter

“Bill Caroselli (Q-TPS)” <QTPS@earthlink.net> wrote:

Well, your right “IF” fprintf() succeeds it won’t touch errno. I just think
it’s good programming practice to save errno before doing ANY other function
that might change it.

I don’t know what Dave meant by errno won’t be set. I think he’s talking
about a different issue.

“Robert Krten” <> nospam89@parse.com> > wrote in message
news:a96urd$lnv$> 1@inn.qnx.com> …
David Gibbs <> dagibbs@qnx.com> > wrote:
Michael Tasche <> michael.tasche@esd-electronics.com> > wrote:
Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the
ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

The example is bad.

Hey Dave, why is the example bad? If fprintf() succeeds, then it should
not touch
errno, right? I use the fprintf()/perror() all the time… Are you
saying it’s
bad in the case of devctl()/fprintf()/perror(), or in all general cases of
fprintf()/perror()?

Cheers,
-RK

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.

“Bill Caroselli (Q-TPS)” <QTPS@earthlink.net> wrote:

Well, your right “IF” fprintf() succeeds it won’t touch errno. I just think
it’s good programming practice to save errno before doing ANY other function
that might change it.

OTOH, if fprintf () to stderr fails, then all bets are off, you might as well
shut down the system :slight_smile:

I don’t know what Dave meant by errno won’t be set. I think he’s talking
about a different issue.

“Robert Krten” <> nospam89@parse.com> > wrote in message
news:a96urd$lnv$> 1@inn.qnx.com> …
David Gibbs <> dagibbs@qnx.com> > wrote:
Michael Tasche <> michael.tasche@esd-electronics.com> > wrote:
Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the
ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

The example is bad.

Hey Dave, why is the example bad? If fprintf() succeeds, then it should
not touch
errno, right? I use the fprintf()/perror() all the time… Are you
saying it’s
bad in the case of devctl()/fprintf()/perror(), or in all general cases of
fprintf()/perror()?

Cheers,
-RK

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

“Bill Caroselli (Q-TPS)” <QTPS@earthlink.net> wrote:

Well, your right “IF” fprintf() succeeds it won’t touch errno. I just think
it’s good programming practice to save errno before doing ANY other function
that might change it.

Does it actually say anywhere in ISO C, POSIX, or our docs that a
function call that succeeds is guaranteed not to touch errno?

I know that we have the habit of leaving errno alone unless there’s an
error, but I’m not aware that we officially guarantee that it’s always
the case. My impression is that both ISO C and POSIX allow any call
to change errno to any non-zero value unless the function fails and
is specified to set errno on failure. Am I mistaken?


Wojtek Lerch QNX Software Systems Ltd.

Hi,
thanks for clarification.

Just a thought:
open sets errno.
close sets errno.
dup sets errno.
dup2 sets errno.
ioctl sets errno.
read sets errno.
write sets errno.
select sets errno.

MsgSend sets errno.
MsgSend_r does not set errno but returns neg. errno.
… x sets errno.
… x_r does not set errno but returns neg. errno.

devctl does not set errno, but returns pos. errno.

Actually I found no other api call which behaves like devctl.

Michael

David Gibbs wrote:

Michael Tasche <> michael.tasche@esd-electronics.com> > wrote:
Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

The example is bad.

It should probably be something like:

if (error = devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS: %s.\n”, strerror(error));
exit(EXIT_FAILURE);
}

  1. devctl returns errno value.

This is the behaviour.

devctl() never touches the global errno.

I’ll pass this on to our docs people – though they’ll probably see
it in the thread here too.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

%% Michael Tasche <michael.tasche@esd-electronics.com> writes:

mt> devctl does not set errno, but returns pos. errno.

mt> Actually I found no other api call which behaves like devctl.

Agree 110%! We were just bit in the butt by this on Friday and it took
us quite a bit of puzzlement and head scratching before we checked the
docs and realized this very odd behavior of devctl(); we simply assumed
that it would work like every other system call rather than having a
strange and unusual behavior.

Paul D. Smith <pausmith@nortelnetworks.com> HASMAT–HA Software Mthds & Tools
“Please remain calm…I may be mad, but I am a professional.” --Mad Scientist

These are my opinions—Nortel Networks takes no responsibility for them.

Paul D. Smith <pausmith@nortelnetworks.com> wrote:
: %% Michael Tasche <michael.tasche@esd-electronics.com> writes:

: mt> devctl does not set errno, but returns pos. errno.

: mt> Actually I found no other api call which behaves like devctl.

: Agree 110%! We were just bit in the butt by this on Friday and it took
: us quite a bit of puzzlement and head scratching before we checked the
: docs and realized this very odd behavior of devctl(); we simply assumed
: that it would work like every other system call rather than having a
: strange and unusual behavior.

That’s why we have docs. :slight_smile:


Steve Reid stever@qnx.com
TechPubs (Technical Publications)
QNX Software Systems

Paul D. Smith <pausmith@nortelnetworks.com> wrote:

%% Michael Tasche <> michael.tasche@esd-electronics.com> > writes:

mt> devctl does not set errno, but returns pos. errno.

mt> Actually I found no other api call which behaves like devctl.

Agree 110%!

We (QSSL) didn’t invent the behaviour.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Robert Krten <nospam89@parse.com> wrote:

David Gibbs <> dagibbs@qnx.com> > wrote:
Michael Tasche <> michael.tasche@esd-electronics.com> > wrote:
Hi all,

on my 6.2 Beta (bld447) the devctl does not set errno. Instead the ernno
code is returned by devctl.
Well, this seems to match the docu about devctl, but if you look at the
example, you see following:

if (devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
{
fprintf(stderr, “Error setting RTS.\n”);
perror (NULL);
exit(EXIT_FAILURE);
}

The “perror” will ever say “No error”, because ernno is not set.

Which behavior is intended by qnx?

The example is bad.

Hey Dave, why is the example bad?

A couple reasons.

It assumes that devctl() will set errno, and that the perror() can be
used to display the reason that devctl() failed. (FALSE)

It assumes that a successful fprintf() will NOT set errno, thus losing
the failure reason from devctl().

It is at best confusing – is perror() trying to display the reason
devctl() failed (we ARE in the devctl() function docs) or the reason
fprintf() failed, should it have failed?

If fprintf() succeeds, then it should not touch
errno, right? I use the fprintf()/perror() all the time…
Are you saying it’s bad in the case of devctl()/fprintf()/perror(),
or in all general cases of fprintf()/perror()?

My understanding is that a function IS allowed to update errno whether
or not it has failed.

The usual specification for functions is something like, “retuns blah
on success, and blah2 if failure, in which case errno will be set, list
of errno values”. For those functions, errno only has meaning if the
function failed – it might or might not get changed along the way.

Some functions (I think some of the math functions) actually always
set errno, set it to EOK if the function succeeded, or to some failure
value if they failed.

Now, fprintf() might happen to not set errno if it succeeds, but this
is not guaranteed behaviour.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Peter Graves <pgraves@qnx.com> wrote:

I think he means just that, errno will not be set. If you look at the rest
of the docs for devctl, under the returns section it will return EOK/EAGAIN
etc. So if the code was changed to something like the following it may
work a bit better for ya:

if ((rc=devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL)))
{
fprintf(stderr, “Error setting RTS: %s\n”, strerror(rc));
exit(EXIT_FAILURE);
}

In addition, I went and inspected the source to devctl(). It uses
MsgSend_r() and never explicitly touches errno, so it will NOT
change the value of errno.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

%% Steve Reid <stever@qnx.com> writes:

sr> That’s why we have docs. :slight_smile:

IMO: that’s a cop-out :slight_smile:.

APIs should be fundamentally consistent. It’s much better to be able to
intuitively know how a function will behave (and be right), than have to
go searching through documents to read about it.

Whatever. It’s obviously too late to change this now, as it would be a
non-backward-compatible change.

Paul D. Smith <pausmith@nortelnetworks.com> HASMAT–HA Software Mthds & Tools
“Please remain calm…I may be mad, but I am a professional.” --Mad Scientist

These are my opinions—Nortel Networks takes no responsibility for them.

David Gibbs <dagibbs@qnx.com> wrote:

Some functions (I think some of the math functions) actually always
set errno, set it to EOK if the function succeeded, or to some failure
value if they failed.

That would be bad. POSIX specifically says:

No function in this volume of IEEE Std 1003.1-2001 shall set errno
to 0.


Wojtek Lerch QNX Software Systems Ltd.

Wojtek Lerch <wojtek_l@yahoo.ca> wrote:

David Gibbs <> dagibbs@qnx.com> > wrote:
Some functions (I think some of the math functions) actually always
set errno, set it to EOK if the function succeeded, or to some failure
value if they failed.

That would be bad. POSIX specifically says:

No function in this volume of IEEE Std 1003.1-2001 shall set errno
to 0.

Yes it would. I couldn’t find one doc’ed that way – but seemed to
remember somebody mentioning it recently. Hm… maybe you were
supposed to set it to 0 yourself, then check to make sure it was
still 0 afterwards in order to determine if the function succeeded
or not. I can’t find an example of this, so maybe I was just hallucinating.

Also, The ANSI C (C99) spec echos the definition that no function shall
set errno to 0. It also notes that a function is free to set errno to
a value that is non-zero irrespective of function failure provided the use
of errno is not documented in the description of the function.

So, apparently, fprintf() is NOT allowed to change errno unless it fails.
(I was wrong about this risk when talking about why the example was bad.)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs <dagibbs@qnx.com> wrote:

Wojtek Lerch <> wojtek_l@yahoo.ca> > wrote:
David Gibbs <> dagibbs@qnx.com> > wrote:
Some functions (I think some of the math functions) actually always
set errno, set it to EOK if the function succeeded, or to some failure
value if they failed.

That would be bad. POSIX specifically says:

No function in this volume of IEEE Std 1003.1-2001 shall set errno
to 0.

Yes it would. I couldn’t find one doc’ed that way – but seemed to
remember somebody mentioning it recently. Hm… maybe you were
supposed to set it to 0 yourself, then check to make sure it was
still 0 afterwards in order to determine if the function succeeded
or not. I can’t find an example of this, so maybe I was just hallucinating.

Also, The ANSI C (C99) spec echos the definition that no function shall
set errno to 0. It also notes that a function is free to set errno to
a value that is non-zero irrespective of function failure provided the use
of errno is not documented in the description of the function.

So, apparently, fprintf() is NOT allowed to change errno unless it fails.
(I was wrong about this risk when talking about why the example was bad.)

whew I knew that someone, somewhere, sometime, had told me fprintf/perror
was “a good thing” (or at least an “ok thing”) :slight_smile:

Thanks folks,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:a9fak9$lfp$1@nntp.qnx.com

Wojtek Lerch <> wojtek_l@yahoo.ca> > wrote:
No function in this volume of IEEE Std 1003.1-2001 shall set errno
to 0.

Yes it would. I couldn’t find one doc’ed that way – but seemed to
remember somebody mentioning it recently. Hm… maybe you were
supposed to set it to 0 yourself, then check to make sure it was
still 0 afterwards in order to determine if the function succeeded
or not. I can’t find an example of this, so maybe I was just
hallucinating.

Funny: I found it in footnote 170 in the C standard:

Thus, a program that uses errno for error checking should set it to zero
before a library function call, then inspect it before a subsequent
library
function call.

Also, The ANSI C (C99) spec echos the definition that no function shall
set errno to 0. It also notes that a function is free to set errno to
a value that is non-zero irrespective of function failure provided the use
of errno is not documented in the description of the function.

Yes you’re right; I have always assumed that any function can set errno to
any
non-zero value on success, but after re-reading the relevant paragraph in
C99,
I have to admit I was wrong. On my defense, surprisingly few C99 functions
are documented to set errno, and POSIX does not mind if functions modify
errno on success (as long as C allows it, of course):

The value of errno shall be defined only after a call to a function for
which
it is explicitly stated to be set and until it is changed by the next
function
call or if the application assigns it a value. The value of errno should
only
be examined when it is indicated to be valid by a function’s return
value.

So, apparently, fprintf() is NOT allowed to change errno unless it fails.

Actually, the description of fprintf() in the C standard does not mention
errno;
therefore, fprintf() is free to modify errno whether it succeeds or not.