martin@innovus.UUCP (Martin Renters) (07/26/89)
We just found some rather strange behaviour on our 9000/825 running HP-UX 3.0. Seems we get an errno 25 (not a typewriter) on the first I/O we do on any newly opened file, although the I/O is actually carried out. Any subsequent I/Os work fine, without error. Both HFS and NFS filesystems seem to have this problem. Here's a test program (a.c) that illustrates this problem: #include <stdio.h> #include <errno.h> extern int errno; main() { FILE *fp; char buffer[80]; buffer[0]='\0'; if ((fp=fopen("a.c","r")) == NULL) { printf("File fails to open\n"); exit(2); } printf("File opens, errno=%d, fp=%d\n",errno,fp); fgets(buffer,64,fp); printf("File read, errno=%d, fp=%d, buffer=%s",errno,fp,buffer); clearerr(fp); errno=0; fgets(buffer,64,fp); printf("File read2, errno=%d, fp=%d, buffer=%s",errno,fp,buffer); } When compiled with 'cc a.c' and executed the following output results: File opens, errno=0, fp=1073742056 File read, errno=25, fp=1073742056, buffer=#include <stdio.h> File read2, errno=0, fp=1073742056, buffer=#include <errno.h> Anybody care to comment about why this is happening? Martin Renters martin@innovus Technical Analyst ..utgpu!maccs!innovus!martin Innovus Inc.
fkittred@bbn.com (Fletcher Kittredge) (07/26/89)
In article <227@innovus.UUCP> martin@innovus.UUCP (Martin Renters) writes: > >We just found some rather strange behaviour on our 9000/825 running >HP-UX 3.0. Seems we get an errno 25 (not a typewriter) on the first >I/O we do on any newly opened file, although the I/O is actually carried >out. Any subsequent I/Os work fine, without error. Both HFS and NFS >filesystems seem to have this problem. >File opens, errno=0, fp=1073742056 >File read, errno=25, fp=1073742056, buffer=#include <stdio.h> >File read2, errno=0, fp=1073742056, buffer=#include <errno.h> > >Anybody care to comment about why this is happening? > Sure, I'll comment. I think you have a fundamental misunderstanding of errno. It is only guaranteed to be set to a meaningfull value after a system call fails. Since you don't check to see if a system call fails, basically what your code is doing is checking the value of an uninitialized variable. As one might expect, you get garbage. I recommend the following books: "The Unix Programming Environment" Kernighan and Pike Prentice-Hall, 1984 "Advanced Unix Programming" Rochkind Prentice-Hall, 1985 regards, fletcher Fletcher E. Kittredge fkittred@bbn.com
jack@csccat.UUCP (Jack Hudler) (07/27/89)
In article <227@innovus.UUCP> martin@innovus.UUCP (Martin Renters) writes: > >We just found some rather strange behaviour on our 9000/825 running >HP-UX 3.0. Seems we get an errno 25 (not a typewriter) on the first >I/O we do on any newly opened file, although the I/O is actually carried >out. Any subsequent I/Os work fine, without error. Both HFS and NFS >filesystems seem to have this problem. It is my understanding that errno is only checked when you have an error, not to indicate that one occured. If no error from the function call is returned, then the value of errno is meaningless. -- Jack Computer Support Corportion Dallas,Texas Hudler UUCP: {texsun,texbell,attctc}!csccat!jack
stroyan@hpfcdc.HP.COM (Mike Stroyan) (07/27/89)
> File opens, errno=0, fp=1073742056 > File read, errno=25, fp=1073742056, buffer=#include <stdio.h> > File read2, errno=0, fp=1073742056, buffer=#include <errno.h> > > Anybody care to comment about why this is happening? The fopen is checking isatty() to see if it should buffer the stream output. The isatty call is using a failed ioctl() call to see that the file is not a tty. The failed ioctl() call is setting errno to ENOTTY. Your program is checking the value of errno without first checking ferror() or the return value from fgets(). You can't depend on the value of errno being to be 0 when an error has not occured. You must first determine that an error occured, then use errno to find out more about the error. The errno value is not always defined to reflect the state of libraries such as stdio. While some library calls will refer the user to errno for more information, it is really intended to return information about kernel calls rather than arbitrary library calls. Mike Stroyan, stroyan@hpfcla.hp.com
walter@hpclwjm.HP.COM (Walter Murray) (07/28/89)
Several others have pointed out the problem of checking errno when no error condition has been indicated. Here are a few more interesting things to know about errno, which will be true in any ANSI-conforming compiler and library. 1. The value of errno is always zero at program startup. 2. The program itself may set errno to zero, but none of the standard library functions will ever do so. 3. Even though any particular library function may not be documented to use errno, it is possible that that function will set errno to a nonzero value, regardless of whether an error occurred. 4. For portability, it is better not to declare errno yourself. Just include <errno.h> and rely on the declaration there. On some systems, errno will be a macro, and if you try to declare it yourself as 'extern int', there'll be a problem. Walter Murray Hewlett-Packard ----------------------------------------------------------------------
corrigan@net1.ucsd.edu (Mike Corrigan) (07/28/89)
In article <227@innovus.UUCP> martin@innovus.UUCP (Martin Renters) writes: > printf("File opens, errno=%d, fp=%d\n",errno,fp); /* > fgets(buffer,64,fp); > printf("File read, errno=%d, fp=%d, buffer=%s",errno,fp,buffer); */ Should go like: while(fgets(64,fp) != NULL) printf("File read, buffer=%s",buffer); if(!feof(fp)) { fprintf(stderr,"ERROR detected on File read\n"); exit(ferror(fp)); }