 |
|
 |
|
04-21-04 09:34 PM
Hi
I am trying to create a POSIX library for a language other than C by
calling the C routines in a wrapper routine.
I think I have run up against a problem with popen.
A fragment of the code :
errno=0;
cmdpipe=popen(command,type);
if(cmdpipe==NULL)
{
perror("Failed : popen in posixwrapper:popen");
exit(1);
}
perror("popen");
printf("%d %s\n",errno,strerror(errno));
Now, when I test this, I get :
popen: Success
29 Illegal seek
man popen yields :
NAME
popen, pclose - process I/O
SYNOPSIS
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
The argument needs to be a const char * and I am passing char *.
Questions :
1. Why does perror return "Success" ?
2. Is the error condition 29 (Illegal seek) caused by my not using the const
char* ?
Questions 3, 4 and 5 apply only if you answered 2 in affirmative.
3. If so, can I declare a const char * inside the routine with the fragment
above and set it to the input value of command ? (I am not very savvy with
C syntax, having had done no C programming for almost 7-8 years, but this
kind of thing is usually illegal in many other programming languages.).
4. Since the code is (obviously) going to run on Linux, can the above effect
be achieved somehow by setting the value of some export'ed variable ?
5. Any other suggestions ?
Thanks,
MS
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-21-04 09:34 PM
On Wed, 21 Apr 2004, Madhusudan Singh wrote:
> A fragment of the code :
>
> errno=0;
> cmdpipe=popen(command,type);
> if(cmdpipe==NULL)
> {
> perror("Failed : popen in posixwrapper:popen");
> exit(1);
> }
Urgh! Super ugly FSF coding style.
> perror("popen");
> printf("%d %s\n",errno,strerror(errno));
>
> Now, when I test this, I get :
>
> popen: Success
> 29 Illegal seek
You're calling perror(), even if no error is returned, so you
are getting garbage. Library functions are not required to set
errno to 0 if there isn't an error.
> 1. Why does perror return "Success" ?
Presumably because is was successful.
> 2. Is the error condition 29 (Illegal seek) caused by my not using the con
st
> char* ?
No; see above.
> 4. Since the code is (obviously) going to run on Linux, can the above effect[/vbco
l]
Nothing obvious about that at all; this IS comp.unix.programmer,
not comp.linux.programmer, after all.
[vbcol=seagreen]
> 5. Any other suggestions ?
Call popen onli in the event of an error. And
don't use FSF coding style, of GPL type licenses!
--
Rich Teer, SCNA, SCSA
President,
Rite Online Inc.
Voice: +1 (250) 979-1638
URL: http://www.rite-online.net
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-21-04 09:34 PM
Rich Teer <rich.teer@rite-group.com> writes:
> Call popen onli in the event of an error.
s/open/error/
(other typo ignored).
Bye, Dragan
--
Dragan Cvetkovic,
To be or not to be is true. G. Boole No it isn't. L. E. J. Brouwer
!!! Sender/From address is bogus. Use reply-to one !!!
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-21-04 10:34 PM
On Wednesday 21 April 2004 16:38, Rich Teer (rich.teer@rite-group.com) held
forth in comp.unix.programmer
(<Pine.SOL.4.58.0404211334380.27166@zaphod.rite-group.com> ):
> On Wed, 21 Apr 2004, Madhusudan Singh wrote:
>
>
> Urgh! Super ugly FSF coding style.
>
Ugly as C coding usually is, I do not see how the above is any more ugly
than other stuff in C.
Maybe if((cmdpipe=popen(command,type))==NULL) is a little more compact.
But lets pass over that.
>
> You're calling perror(), even if no error is returned, so you
> are getting garbage. Library functions are not required to set
> errno to 0 if there isn't an error.
*I* had set errno=0 just prior to invoking popen (see the first line of the
code fragment). Would it not stand to reason that it changed from 0 to 29
because popen changed it ?
>
>
> Presumably because is was successful.
Does not seem to be the case. When I try to fflush the pipe after an fputs,
I get an illegal seek. Maybe I need to set errno=0 before each of those
invocations to see if this is merely a matter of flawed error detection.
>
>
> No; see above.
I surely hope that you are right !!
But why the admonition to use a const char* and then allow the use of char*
like this ?
>
>
> Nothing obvious about that at all; this IS comp.unix.programmer,
> not comp.linux.programmer, after all.
I apologize.
>
>
> Call popen onli in the event of an error. And
> don't use FSF coding style, of GPL type licenses!
>
Well, I intend to release the code under LGPL, but I am open to suggestions
regarding the aesthetics. Not that I find any C code itself to be a
particularly "beautiful" thing
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-21-04 10:34 PM
Madhusudan Singh wrote:
> Hi
> I am trying to create a POSIX library for a language other than C
by
> calling the C routines in a wrapper routine.
>
I met some strange errno problems when making a multithreaded plugin for
Tcl/Tk a long time ago. I think they've fix it now though.
> I think I have run up against a problem with popen.
>
> A fragment of the code :
>
> errno=0;
> cmdpipe=popen(command,type);
> if(cmdpipe==NULL)
> {
> perror("Failed : popen in posixwrapper:popen");
> exit(1);
> }
>
> perror("popen");
> printf("%d %s\n",errno,strerror(errno));
>
> Now, when I test this, I get :
>
> popen: Success
> 29 Illegal seek
>
I would concider using oserror() instead. Like this:
fprintf( stderr, "%d %s\n", oserror(), strerror( oserror() ) );
> man popen yields :
>
> NAME
> popen, pclose - process I/O
>
> SYNOPSIS
> #include <stdio.h>
>
> FILE *popen(const char *command, const char *type);
>
> int pclose(FILE *stream);
>
> The argument needs to be a const char * and I am passing char *.
>
> Questions :
>
> 1. Why does perror return "Success" ?
>
> 2. Is the error condition 29 (Illegal seek) caused by my not using the con
st
> char* ?
>
> Questions 3, 4 and 5 apply only if you answered 2 in affirmative.
>
> 3. If so, can I declare a const char * inside the routine with the fragmen
t
> above and set it to the input value of command ? (I am not very savvy with
> C syntax, having had done no C programming for almost 7-8 years, but this
> kind of thing is usually illegal in many other programming languages.).
>
> 4. Since the code is (obviously) going to run on Linux, can the above effe
ct
> be achieved somehow by setting the value of some export'ed variable ?
>
> 5. Any other suggestions ?
>
> Thanks,
>
> MS
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-21-04 10:34 PM
Madhusudan Singh wrote:
> [...]
> Does not seem to be the case. When I try to fflush the pipe after an fputs
,
> I get an illegal seek. Maybe I need to set errno=0 before each of those
> invocations to see if this is merely a matter of flawed error detection.
It might be. This is wrong:
errno = 0;
fputs ("hello\n", fp);
fflush (fp);
if (errno != 0) {
perror ("There may or may not be an error");
..
because a library function can change `errno' even if there
is no failure. This is better:
if (fputs("hello", fp) == EOF || fflush(fp) == EOF) {
perror ("There really was an error");
..
That is, fputs() and fflush() tell you whether a failure has
occurred. `errno' provides additional information about the
failure, *if* something actually went wrong -- but `errno'
itself doesn't tell you whether there was a failure.
Sometimes it is more convenient to gather all the error
tests together:
fputs ("hello\n", fp);
fputs ("world\n", fp);
fprintf (fp, "The answer is %d\n", 052);
fflush (fp);
if (ferror(fp)) {
perror ("There was an error");
..
By the way, this is also wrong:
if (fputs("hello\n", fp) == EOF) {
pclose (fp);
perror ("There was an error");
..
because the pclose() might change `errno' before perror()
has a chance to interpret it. Either do your cleanup after
calling perror(), or save and restore `errno':
if (...) {
int errno_save = errno;
lots_of_cleanup();
errno = errno_save;
perror ("There was an error");
..
--
Eric.Sosman@sun.com
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-21-04 10:34 PM
Rich Teer <rich.teer@rite-group.com> writes:
> On Wed, 21 Apr 2004, Madhusudan Singh wrote:
>
> You're calling perror(), even if no error is returned, so you
> are getting garbage. Library functions are not required to set
> errno to 0 if there isn't an error.
But why would perror() change it? If the perror() call says errno is
0, why would a subsequent call to strerror() say something else? He
did set errno to 0 before calling popen() after all.
Joe
--
If people don't want to come out to the ballpark, nobody's going
to stop them.
- Yogi Berra
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-21-04 11:36 PM
joe@invalid.address wrote:
>
> Rich Teer <rich.teer@rite-group.com> writes:
>
>
>
> But why would perror() change it?
perror() must generate output on stderr. To do so,
it most likely calls other functions, directly or indirectly.
The obvious perror() implementation calls fprintf(), and
fprintf() will in turn call a whole bunch of other things.
Any of these might change errno, even if there's no "failure."
There's a concrete example of this in Question 12.24 of the
comp.lang.c Frequently Asked Questions list
http://www.eskimo.com/~scs/C-faq/top.html
> If the perror() call says errno is
> 0, why would a subsequent call to strerror() say something else?
Because the value has been changed. errno can hold only
one value at a time (multithreaded programs have multiple
errno's, but each has only one value at a time), so if the
perror() causes errno to change, its old value is forgotten.
> He
> did set errno to 0 before calling popen() after all.
Yep. And errno was zero when the program began execution
in main(). But that was a long time ago, and things have
been happening.
--
Eric.Sosman@sun.com
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-22-04 12:36 AM
>> You're calling perror(), even if no error is returned, so you
>
> *I* had set errno=0 just prior to invoking popen (see the first line
> of the code fragment). Would it not stand to reason that it changed
> from 0 to 29 because popen changed it ?
Doesn't matter. ANSI/ISO/POSIX are very clear that the value of errno
is unreliable UNLESS you have just called a library function whose
return value indicated an error took place. If no error has taken
place, library functions are explicitly permitted to fiddle with
errno's value as much as they please.
b
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
04-22-04 12:36 AM
On Wed, 21 Apr 2004 23:07:09 +0200,
DeMarcus <nobody@tellus.orb> wrote:
>
>
> Madhusudan Singh wrote:
[vbcol=seagreen]
> I would concider using oserror() instead. Like this:
> fprintf( stderr, "%d %s\n", oserror(), strerror( oserror() ) );
Why?
What do you believe the advantage to be?
I'd say it is less preferable, because it's less portable. It's not,
for example, available on the GNU/Linux or Solaris systems I have just
checked it on. No man page, and no header entries (except in the
sybase header files, but that doesn't count).
Martien
--
|
Martien Verbruggen |
Trading Post Australia | 42.6% of statistics is made up on the spot.
|
[ Post a follow-up to this message ]
|
|
|
 |
|
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 08:30 PM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|