mjr@hussar.dco.dec.com (Marcus J. Ranum) (10/19/90)
In article <19547:Oct1818:25:2690@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >You allude to a real problem, though: an application may have to deal >with disk-full errors on any write(). An fwaste(fd,n) syscall, to >allocate n bytes for a file, would solve this. Gee - why not just have your systems programmer allocate a fixed number of sectors of disk for each file when you create it ? :) Oh, oops, I forgot - it's been done. Is anyone seriously considering an fwaste() system call ? I can imagine the results of that ("gee, better make sure I have a spare megabyte for this one in case I need space next week - this disk is getting awfully tight because of all the software that uses fwaste() to grab a spare 256K) What's the big deal, anyhow ? So you check your close() calls if it's important to you that your files close properly. I'm sure everyone makes sure that fprintf() and printf() don't return EOF, too. I do. I've had people mention that my code might be big and slow because of all the error checking, but nothing in my experience runs as slowly as code that has dumped core. A good rule of thumb is that, "if it returns a value, it might be trying to tell you something." I've seen DBMS' that don't check returns on read(2) and write(2), but I'd be reluctant to use one, and very upset if I bought one. mjr. -- Nothing is beautiful unless it is large. Vastness and immensity can make you forget a great many weaknesses. - Emperor Napoleon I, predicting the development of X-window in 1813
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/19/90)
In article <1990Oct18.194707.12313@decuac.dec.com> mjr@hussar.dco.dec.com (Marcus J. Ranum) writes: > Is anyone seriously considering an fwaste() > system call ? I can imagine the results of that ("gee, better make sure I > have a spare megabyte for this one in case I need space next week - this > disk is getting awfully tight because of all the software that uses fwaste() > to grab a spare 256K) At worst the application will ftruncate() before closing the file. fwaste()ing too much is just as dumb as write()ing too much. Periodically there are requests for functions to do the same thing. Most applications know how much disk they need, and it's a lot better to allocate the space beforehand than to wait for disaster to strike. What do you think the news package's ``spacefor'' does? fwaste() is also very useful for asynchronous I/O. > What's the big deal, anyhow ? So you check your close() calls > if it's important to you that your files close properly. And do what if it returns EDQUOT? It is simply wrong for write() to succeed if there's no space for the data. The application might erase what it wrote; how do you expect it to recover if it doesn't find out until later? Well? What excuse do you have for forcing applications to buffer all their data until close()? There's no efficiency loss in making write() return accurate errors. > I'm sure everyone > makes sure that fprintf() and printf() don't return EOF, too. But those are meant to use internal buffers, and if you want better error checking you can and should be using descriptors directly. There's no level to escape to below descriptors if they don't do the job. ---Dan
bet@bent.mc.duke.edu (Bennett Todd -- gaj) (10/20/90)
Anyone who cares about writing robust programs should be checking the return values of every system call that can return an error. This can get tedious; I've seen a solution in other people's programs that I like, and which I've adopted for my own use. There is an external "char *" variable "progname", which I initialize to argv[0] as the first line of executable code in main(). Thereafter, if I don't want to program any special handling and recovery of an error, but just print a message and exit, I call a routine whose name is prefixed with "e". Thus if I call eclose() I don't have to check for an error return; if anything goes wrong it will end up running (void) fprintf(stderr, "%s: close() failed: %s\n", progname, ((errno == 0) ? "No error!?" : ((errno < sys_nerr) ? sys_errlist[errno] : "Unknown error"))); exit(1); only with the filename included (see below). I've got routines starting with 'e' for everything that I've needed so far out of sections 2 and 3 of the UPM; it sure takes the pain out of whipping out robust utilities. I also have some other goodies tucked in to this library. Emalloc() overallocates by a fixed amount and inserts a header and appends a trailer; erealloc()/efree() check the header and trailer, reporting that the malloc arena has been corrupted if they have been stomped. Eopen() and efopen() stash a copy of the filename in a table indexed by the file descriptor; all the routines that take file descriptors attempt to report the filename by checking that table, and report the file descriptor number if the filename isn't available. The program size penalty isn't all that great, the source code doesn't get any more cluttered, and the resulting programs seem to be more robust in the face of full filesystems and suchlike. If anyway wants a copy I'll be glad to email or post my library; it fits neatly in two mailings/postings, one for libc.h and one for everything else. -Bennett bet@orion.mc.duke.edu