[comp.unix.wizards] ENOTTY error when executing cp

jon@fdmetd.uucp (Jon Ivar Tr|stheim) (09/07/89)

Please help me........

I am running a deamon "server-process" on a TOWER 32/600 machine. The
server is implemented with IPC (pipes (FIFO), and semaphores).

The server receives request from client's. When server get request about
copying files from one directory to another the cp(1) command fails
after a while.

The command that gets executed in the server is:
	
	.
	.
	.
	sprintf(sh_cmd,"cp %s %s%s", filename, target->path, target->filename);

	if(system(sh_cmd) != 0){

	}
	.
	.
	.
Errno is equal 25 (ENOTTY) Not a typewriter !!!!!!!!!

I think the error has something to do with the number of files beeing
copied, because the error occures on the same file in the filelist
every time.
If i remove one file from the filelist, then the error occures on the
next file in the filelist.

if someone knows why !!!! please mail me as soon as possible...


Thanks....


-- 
Jon Tr|stheim, Fellesdata a.s, P.O. Box 248, 0212 OSLO 2, NORWAY
Phone : +47 2 52 80 80                            Fax   : +47 2 52 85 10
E-mail : ...!mcvax!ndosl!fdmetd!jon  or           jon@fdmetd.uucp
<The opinions expressed, if any, do not represent Fellesdata a.s>

amos@taux01.UUCP (Amos Shapir) (09/12/89)

There's a combination of two common errors here:

1. Errno is meaningful only after a system call fails; ENOTTY is usually
  generated in the normal course of starting up stdio.  To make sure
  its value is relevant, always clear errno before doing a system call.

2. Despite its name, system() is not a system call, but a routine;
  its return value is the shell's exit status, which is usually specific
  to the command it runs.  Errno has nothing to do with it. RTFM.

-- 
	Amos Shapir		amos@taux01.nsc.com or amos@nsc.nsc.com
National Semiconductor (Israel) P.O.B. 3007, Herzlia 46104, Israel
Tel. +972 52 522261  TWX: 33691, fax: +972-52-558322
34 48 E / 32 10 N			(My other cpu is a NS32532)

decot@hpisod2.HP.COM (Dave Decot) (09/13/89)

> There's a combination of two common errors here:
> 
> 1. Errno is meaningful only after a system call fails; ENOTTY is usually
>   generated in the normal course of starting up stdio.  To make sure
>   its value is relevant, always clear errno before doing a system call.

No.  To make sure its value is relevant, only use it when it is
meaningful; i.e., when a function returns a documented error return
value and says that it sets errno in its documentation.  Clearing errno
is irrelevant except where it is the only way to detect errors (as in
functions that use all possible return values for successful
completions).

> 2. Despite its name, system() is not a system call, but a routine;
>   its return value is the shell's exit status, which is usually specific
>   to the command it runs.  Errno has nothing to do with it. RTFM.

Yes.

Dave

blm@6sigma.UUCP (Brian Matthews) (09/13/89)

In article <2556@taux01.UUCP> amos@taux01.UUCP (Amos Shapir) writes:
|1. Errno is meaningful only after a system call fails; ENOTTY is usually
|  generated in the normal course of starting up stdio.  To make sure
|  its value is relevant, always clear errno before doing a system call.

Is it guarenteed anywhere that errno is left untouched if a system call
succeeds?  I couldn't find it.  Intro(2) (in my System V manuals) states:

    "Errno is not cleared on successful calls, so it should be tested
     only after an error has been indicated."

The second half of that sentence says to me that errno may be modified
even if the system call succeeds, so relying on errno staying zero is
a Bad Thing.  But the first half of the sentence seems to talk about
clearing errno on success, so the second half might not say anything
about whether errno is modified on success.
-- 
Brian L. Matthews			blm@6sigma.UUCP
Six Sigma CASE, Inc.			+1 206 854 6578
PO Box 40316, Bellevue, WA  98004

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/14/89)

In article <301@6sigma.UUCP> blm@6sigma.UUCP (Brian Matthews) writes:
>Is it guarenteed anywhere that errno is left untouched if a system call
>succeeds?

This isn't guaranteed in any "standard" (SVID, POSIX, whatever), partly
because some apparent "system calls" may actually be implemented as
library functions that perform other real system calls to get the job
done, and some of those subordinate system calls may set errno as a
side effect without the overall emulated system call failing.  To
require that errno remain untouched would force such implementations to
continually save and restore its value, a lot of work for no real gain.

You should only inspect errno when it is documented to contain a valid
value.

jba@harald.ruc.dk (Jan B. Andersen) (09/14/89)

>In article <2556@taux01.UUCP> amos@taux01.UUCP (Amos Shapir) writes:
>|  To make sure
>|  its value is relevant, always clear errno before doing a system call.

blm@6sigma.UUCP (Brian Matthews) writes:

> Intro(2) (in my System V manuals) states:

>    "Errno is not cleared on successful calls, so it should be tested
>     only after an error has been indicated."

>The second half of that sentence says to me that errno may be modified
>even if the system call succeeds, so relying on errno staying zero is
>a Bad Thing.  But the first half of the sentence seems to talk about
>clearing errno on success, so the second half might not say anything
>about whether errno is modified on success.

As I see it, the "correct" way to check for errors is by coding something
like this:

  if( some_system_call() ) {
	printf( "errno %d has occured in some_system_call()\n", errno );
	exit( errno );
  }

If you don't like if'ing the call do something like this:

  errno = 0;
  some_system_call();
  if( errno ) {
	...
  }

frank@zen.co.uk (Frank Wales) (09/15/89)

In article <109@harald.UUCP> jba@harald.ruc.dk (Jan B. Andersen) writes:
>As I see it, the "correct" way to check for errors is by coding something
>like this:
>
>  if( some_system_call() ) {
>	printf( "errno %d has occured in some_system_call()\n", errno );
>	exit( errno );
>  }

Assuming some_system_call() returns true for failure, yes; this is
not always the case, however.

>If you don't like if'ing the call do something like this:
>
>  errno = 0;
>  some_system_call();
>  if( errno ) {
>	...
>  }

This isn't equivalent to the previous code fragment, and furthermore is
not a valid use of errno; if you don't like the former style, then an
alternative is:

  returnval=some_system_call();
  if (returnval) {
    /* appropriate failure action... */
  }

It bears repeating that the purpose of errno is *not* to indicate 
system call failure, but to elaborate on the reason for such a failure.
Examining it without due cause, such as some_system_call() returning
a failure value, is wrong and dangerous, precisely because it sometimes
seems to generate the right behaviour.
--
Frank Wales, Systems Manager,        [frank@zen.co.uk<->mcvax!zen.co.uk!frank]
Zengrange Ltd., Greenfield Rd., Leeds, ENGLAND, LS9 8DB. (+44) 532 489048 x217 

blm@6sigma.UUCP (Brian Matthews) (09/16/89)

In article <109@harald.UUCP> jba@harald.ruc.dk (Jan B. Andersen) writes:
|As I see it, the "correct" way to check for errors is by coding something
|like this:
|  if( some_system_call() ) {
|	printf( "errno %d has occured in some_system_call()\n", errno );
|	exit( errno );
|  }

Two problems with this:

1.  You should use perror so the user gets a reason for the failure,
    not just a number.

2.  errno isn't preserved across many stdio calls, so the exit will
    not exit with the errno generated by some_system_call.

|If you don't like if'ing the call do something like this:
|  errno = 0;
|  some_system_call();
|  if( errno ) {
|	...
|  }

My question was basically, is that guaranteed to work.  I suspected not,
but couldn't find anything to prove it.  Doug Gwyn has since posted
that you can't do this - some_system_call may set errno to any arbitrary
value, yet still succeed.
-- 
Brian L. Matthews			blm@6sigma.UUCP
Six Sigma CASE, Inc.			+1 206 854 6578
PO Box 40316, Bellevue, WA  98004

shaw@paralogics.UUCP (Guy Shaw) (09/25/89)

In article <109@harald.UUCP>, jba@harald.ruc.dk (Jan B. Andersen) writes:

>   if( some_system_call() ) {
> 	printf( "errno %d has occured in some_system_call()\n", errno );
> 	exit( errno );
>   }

1. "if (some_system_call()) { ... }"  is not the way to test for failure
   of a system call.  Most system calls return -1 to indicate failure,
   and may return 0 or some other non-zero result, if successful.

2. Even after substituting an appropriate test for failure, such as,
   "if (some_system_call() == -1)", there is still a problem.  Printf()
   may invoke a system call, for instance write().  In that case,
   the value of errno will be the droppings from that system call,
   whether it was successful or not.  So, the "exit(errno)" may cause
   the program to exit with the new value of errno as its return code.

> If you don't like if'ing the call do something like this:
> 
>   errno = 0;
>   some_system_call();
>   if( errno ) {
> 	...
>   }

Again, this is not safe.  Errno should be tested only after an error
has occurred.  It is not just that successful system calls don't bother
to clear errno; there is more to it than that.  Clearing errno before a
system call won't help.  A system call can succeed and leave trash in errno.
A system call can have code sequences in it like:

	errno = EBARF;
	if (! precondition)
		return (-1);
	ok_do_it();
	return (handy_value);

They are not obliged to be coded like:

	if (! precondition) {
		errno = EBARF;
		return (-1);
		}
	ok_do_it();
	return (handy_value);

In article <2163@munnari.oz.au>, ok@cs.mu.oz.au (Richard O'Keefe) writes:

> But if we were talking extensions, I would much rather have a portable way
> of making *sure* that I got the errno appropriate to a failed system call
> (such as HP-UX's method that was posted some time ago), ...

I missed that posting, but it sounds interesting.  Judging from the number
of postings that contain misconceptions about when errno is valid, I think
there ought to be some kind of change.  I have mixed feelings about which
direction the change ought to take.  On the one hand, the mistakes I see are
all based on very natural assumptions - maybe those assumptions should be
made valid in future.  But then, for the foreseeable future, we would all have
to code without making those assumptions, anyway, for the sake of backward
compatibility.  So, maybe future versions of UNIX should *guarantee* that
errno will be set to garbage after all successful system calls.  That will
flush out a lot of latent bugs, and those people who have been "lucky"
so far will learn quickly.


-- 
Guy Shaw
Paralogics
paralogics!shaw@uunet.uu.net  or  uunet!paralogics!shaw