mike@whuts.UUCP (BALDWIN) (07/08/87)
In article <1219@ius2.cs.cmu.edu>, edw@ius2.cs.cmu.edu (Eddie Wyatt) writes: } > ] > Almost agreed: but if a negative return code other than -1 is returned } > the code doesn't react the same. ] I can think of no Unix system call that doesn't return -1 on error. } So I would say that it's a pretty good bet that "if (call(...) < 0)" and ] "if (call(...) == -1)" will act the same in all cases. System V Release 1.0 had a PDP-11 only set of system calls collectively named maus(2) which implemented a particularly obfusticated version of shared memory. Two of the calls, dismaus and switmaus, would sometimes return -2 on successful completion. } Though, one should ] always consult the man pages for return values if in doubt. True, and the man pages are all very explicit. The DIAGNOSTICS section of (almost) every one contains the sentence, "Otherwise, a value of -1 is returned and errno is set to indicate the error." The man page *only* guarantees -1, so why write potentially unportable code when it is so *trivial* to make it correct? It is _not_ just a style issue. -- Michael Scott Baldwin (not the opinions of) AT&T Bell Laboratories {at&t}!whuts!mike
dave@sds.SciCom.MN.ORG (dave schmidt x194) (07/09/87)
> I can think of no Unix system call that doesn't return -1 on error.
What about nice()?
mike@whuts.UUCP (BALDWIN) (07/10/87)
> > I can think of no Unix system call that doesn't return -1 on error. > What about nice()? No, nice() *does* return -1 on error, so the original statement is true. Unfortunately, it returns -1 on success (sometimes), which is a real pain. The only way to be sure is to set errno to 0, then if nice returns -1 AND errno is set, you have an error. Yecch! Although I'm just as queasy about char *sbrk(), char *shmat(), and void (*signal/set())() returning -1 on error. [Signal/set has even more rudeness with SIG_IGN (1) and SIG_HOLD (2). Hiding the rudeness with #define's (ala SIG_ERR (-1)) doesn't fix it.] -- Michael Scott Baldwin (not the opinions of) AT&T Bell Laboratories {at&t}!whuts!mike
guy%gorodish@Sun.COM (Guy Harris) (07/10/87)
> > I can think of no Unix system call that doesn't return -1 on error. > > What about nice()? From the S5R3 manual page: DIAGNOSTICS Upon successful completion, "nice" returns the new nice value minus 20. Otherwise, a value of -1 is returned and "errno" is set to indicate the error. Other versions of "nice" may just return 0 on success, but they all return -1 on error. You may be thinking that -1 is a legitimate return value in the S5 "name", and you're right. This is one of several botches in the UNIX system call interface; to check for errors from "nice", you have to clear "errno" before making the call, and test it after making the call. There are other calls, such as "ptrace", where this same problem occurs. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
dg@wrs.UUCP (David Goodenough) (07/12/87)
In article <428@sds.SciCom.MN.ORG> dave@sds.SciCom.MN.ORG (dave schmidt x194) writes: >> I can think of no Unix system call that doesn't return -1 on error. > >What about nice()? Well I don't know about your system, but on ours (ISI 68K - BSD 4.3) there ain't no entry for nice in sect. 2 of the manual - it's in section 3. What this tells me is that nice(3) isn't a direct system call. In fact it goes via [sg]etpriority(2) which IS a system type call: witness the following - First comes foo.c main() { nice(); } and now comes the output from an 'adb foo' run _main: link fp,#0 jsr _nice ; call to nice(3) unlk fp rts _nice: link fp,#-4 clrl _errno pea 0:w pea 0:w jsr _getpriority ; call to getpriority(2) addql #8,sp . . . pea 0:w jsr _setpriority ; call to setpriority(2) lea sp@(12),sp unlk fp ; no traps (i.e. system entries) rts ; anywhere in nice .word 0 _getpriority: moveml sp@(4),#<d1,a0> moveq #0x64,d0 trap #1 ; HERE is the system entry trap bccs 0xec jmp cerror rts _setpriority: moveml sp@(4),#<d1,a0,a1> moveq #0x60,d0 trap #1 ; and the other bccs 0x100 jmp cerror rts So order is restored!! -- dg@wrs.UUCP - David Goodenough +---+ | +-+-+ +-+-+ | +---+
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/12/87)
There are several UNIX library routines in various implementations that attempt to return a -1 value for a function whose return type is (char *). This is a holdover from the PDP-11 days where it didn't matter, but these days we encounter environments for which there is simply no such thing as (char *)-1. I would hope that all these botches could be fixed (certainly in any proposed standards!). One could do this in two phases: Phase 1 -- change all applications and library code that invokes such functions to check for either -1 or NULL instead of just -1; Phase 2 -- change these functions to return NULL (of the appropriate type) on failure. There have been similar phased transitions before; we should get this fixed before it gets worse.
guy%gorodish@Sun.COM (Guy Harris) (07/13/87)
> >> I can think of no Unix system call that doesn't return -1 on error. > > > >What about nice()? > > Well I don't know about your system, but on ours (ISI 68K - BSD 4.3) > there ain't no entry for nice in sect. 2 of the manual - it's in section 3. > What this tells me is that nice(3) isn't a direct system call. In fact it > goes via [sg]etpriority(2) which IS a system type call... Yes, but that's only the case on systems that have derived their "nice" and "[sg]etpriority" implementations from the 4.[23]BSD one. On other UNIX systems, "nice" *is* a system call, and it *does* return -1 on error. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
dave@sds.SciCom.MN.ORG (dave schmidt x194) (07/15/87)
> > > I can think of no Unix system call that doesn't return -1 on error. > > > > What about nice()? > > From the S5R3 manual page: > > DIAGNOSTICS > Upon successful completion, "nice" returns the new nice > value minus 20. Otherwise, a value of -1 is returned and > "errno" is set to indicate the error. > > Other versions of "nice" may just return 0 on success, but they all > return -1 on error. How about "all reasonable versions return -1 on error"? Here in the backwaters of UNIX work-a-likes (aka XENIX), the manual says RETURN VALUE On successful completion, 'nice' returns the new nice value minue 20. Note that 'nice' is unusual in the way return codes are handled. It differs from most other system calls in two ways: the value -1 is a valid return code (in the case where the new nice value is 19), and the system call either works or ignores the request; THERE IS NEVER AN ERROR. [my emphasis] Personally, I'd regard ignoring the request as an error, but ...
guy%gorodish@Sun.COM (Guy Harris) (07/16/87)
(This is now a UNIX discussion rather than a C discussion, so I'm moving it to comp.unix.questions.) > > Other versions of "nice" may just return 0 on success, but they all > > return -1 on error. > > How about "all reasonable versions return -1 on error"? Here in the > backwaters of UNIX work-a-likes (aka XENIX), the manual says > > Note that 'nice' is unusual in the way return codes are > handled. It differs from most other system calls in two ways: the > value -1 is a valid return code (in the case where the new nice > value is 19), and the system call either works or ignores the > request; THERE IS NEVER AN ERROR. [my emphasis] Well, if this is really the case (i.e., they didn't just botch the manual page), I'd be curious to know why they changed the AT&T code. (Yes, Xenix *IS* derived from AT&T code; it's not a "rewritten from scratch" "work-alike".) My suspicion is that the documentation writers just got confused. Try writing a program that attempts to reduce your "nice", and run that program when not the super-user. Have the program set "errno" to zero before making the call, and check both the return code from "nice" and the value of "errno" after making the call. If the return code isn't -1, and the value of "errno" isn't EPERM, somebody doing the software screwed up. If the return code is -1, and the value of "errno" is EPERM, somebody doing the documentation screwed up. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
mpl@sfsup.UUCP (M.P.Lindner) (07/17/87)
In article <2337@whuts.UUCP>, mike@whuts.UUCP writes: > In article <1219@ius2.cs.cmu.edu>, edw@ius2.cs.cmu.edu (Eddie Wyatt) writes: > ] > Almost agreed: but if a negative return code other than -1 is returned > } > the code doesn't react the same. > > True, and the man pages are all very explicit. The DIAGNOSTICS section > of (almost) every one contains the sentence, "Otherwise, a value of -1 is > returned and errno is set to indicate the error." The man page *only* > guarantees -1, so why write potentially unportable code when it is so > *trivial* to make it correct? It is _not_ just a style issue. > -- Whoa there, let's take a look: return code sys call 0 or -1 access, acct, brk, chdir, chmod, chown, chroot, close, kill, link, mknod, mount, msgctl, pipe, plock, setuid, setgid, shmctl, stat, stime, umount, unlink, ustat, utime non-negative int or -1 creat, dup, fork, lseek, msgget, nice, open, read, semget, shmget, time, times, ulimit, umask, uname, wait, write bad things sbrk, signal, semop, shmop, msgop ha ha exit, exec, pause, sync can't tell from man getpid, getuid, ioctl, profil, ptrace, semctl, setpgrp or no error code alarm, fcntl So, what call returns a -1 as an error that can also return a negative integer as a valid value? NONE! I know about maus, but since we're talking portable, don't even mention it. My claim is that since *most* of the system calls return n >= 0 on success, it is more natural to test for !(n >= 0) which is the same as n < 0 for failure. Therefore, testing for < 0 is _not_ incorrect. It _is_ a style issue.
edw@ius1.cs.cmu.edu (Eddie Wyatt) (07/17/87)
In article <1641@sfsup.UUCP>, mpl@sfsup.UUCP (M.P.Lindner) writes: > In article <2337@whuts.UUCP>, mike@whuts.UUCP writes: > > In article <1219@ius2.cs.cmu.edu>, edw@ius2.cs.cmu.edu (Eddie Wyatt) writes: > > ] > Almost agreed: but if a negative return code other than -1 is returned > > } > the code doesn't react the same. > > > > True, and the man pages are all very explicit. The DIAGNOSTICS section > > of (almost) every one contains the sentence, "Otherwise, a value of -1 is > > returned and errno is set to indicate the error." The man page *only* > > guarantees -1, so why write potentially unportable code when it is so > > *trivial* to make it correct? It is _not_ just a style issue. > > -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ These aren't my comments, please don't credit them to me. Give the proper credit to who ever wrote them. > > Whoa there, let's take a look: > return code sys call > 0 or -1 access, acct, brk, chdir, chmod, chown, chroot, close, > kill, link, mknod, mount, msgctl, pipe, plock, setuid, > setgid, shmctl, stat, stime, umount, unlink, ustat, > utime > non-negative int or -1 creat, dup, fork, lseek, msgget, nice, open, > read, semget, shmget, time, times, ulimit, umask, > uname, wait, write > bad things sbrk, signal, semop, shmop, msgop > ha ha exit, exec, pause, sync > can't tell from man getpid, getuid, ioctl, profil, ptrace, semctl, setpgrp > or no error code alarm, fcntl > > So, what call returns a -1 as an error that can also return a negative > integer as a valid value? NONE! I know about maus, but since we're > talking portable, don't even mention it. My claim is that since *most* > of the system calls return n >= 0 on success, it is more natural to test > for !(n >= 0) which is the same as n < 0 for failure. > > Therefore, testing for < 0 is _not_ incorrect. It _is_ a style issue. As others have pointed out, there are a few obsure Unix system calls that will return an negetive number on success (dismaus, switmaus PDP-11, some implementations of nice, one networking primative which I forget its name). So its not totally a question of style. Neither is a total question of correctness. If your read or write calls are returning negative bytes read or written then somethings has gone wrong. There are a few widely used systems calls which return values are /should be/ understood - examples read, write, open ... In case as such, the issue of == -1 vs. < 0 becomes a style issue. I like to diverge a minute to the signal system call. I think this is a good example of bad interface design. By intermixing return value with error status information, one has created a sloppy interface with incompatible return types (int and int (*func)()). In general, the interface to any system call should only return status information and modify input parameters to return values. If this where the case, there would be no need for errno and no more sloppy interfaces like signal. The type of the error could be return as an indication of an error with one value reserved to indicate success. This method has been the the approach MACH has taken. -- Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu
guy%gorodish@Sun.COM (Guy Harris) (07/17/87)
> Whoa there, let's take a look: > return code sys call > non-negative int or -1 creat, dup, fork, lseek, msgget, nice, open, > > So, what call returns a -1 as an error that can also return a negative > integer as a valid value? NONE! I know about maus, but since we're > talking portable, don't even mention it. My claim is that since *most* > of the system calls return n >= 0 on success, it is more natural to test > for !(n >= 0) which is the same as n < 0 for failure. Whoa there, let's take a *careful* look this time. "nice" *can* return a negative integer ("Upon successful completion, 'nice' returns the new nice value minus 20," from the S5R2 manual page, and the new "nice" value can be less than 20). It is OK to test for "n < 0" if the call is guaranteed to return a non-negative integer on success, but NOT if it can return a negative integer. "nice" is even worse, because (at least on systems where it returns the new "nice" value) it can return -1 on *success*! You can only test this by clearing "errno", making the call, and testing "errno" after the call. (The same is true of "ptrace".) Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com
mike@whuts.UUCP (BALDWIN) (07/17/87)
In article <1641@sfsup.UUCP>, mpl@sfsup.UUCP (M.P.Lindner) writes: > So, what call returns a -1 as an error that can also return a negative > integer as a valid value? NONE! Sorry, but you've misclassified nice(2). It returns the new nice value (range 0-39) minus 20. Thus, it can return anything in the range -20 to 19 on SUCCESSFUL completion. > My claim is that since *most* > of the system calls return n >= 0 on success, it is more natural to test > for !(n >= 0) which is the same as n < 0 for failure. > Therefore, testing for < 0 is _not_ incorrect. It _is_ a style issue. I claim it is more natural and correct to test for whatever the manual page says. E.g., fcntl(2) DIAGNOSTICS in SVR3.0 says for most cmds taht the successful completion return is "Value other than -1." Therefore, if you code it as "if (fcntl() < 0)" then you are NOT PORTABLE, because nothing guarantees that it won't return -2 on success in the future. For a great many system calls, it doesn't matter currently. But why make it more difficult in the future if something changes in a way that's compatible with the docs but not with your code? -- Michael Scott Baldwin {at&t}!whuts!mike I only speak AT&T Bell Laboratories +1 201 386 3052 for myself!
paul@whuts.UUCP (HO) (07/22/87)
In article <1641@sfsup.UUCP>, mpl@sfsup.UUCP (M.P.Lindner) writes: > So, what call returns a -1 as an error that can also return a negative > integer as a valid value? NONE! Ever wonder why in /usr/src/cmd/nice.c, nice is called without having its return value checked? Paul Ho