Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!wuarchive!udel!princeton!notecnirp!nfs From: nfs@notecnirp.Princeton.EDU (Norbert Schlenker) Newsgroups: comp.os.minix Subject: Re: POSIX headers, which of the below are correct Keywords: POSIX Message-ID: <22014@princeton.Princeton.EDU> Date: 1 Dec 89 20:20:17 GMT References: <682@augean.OZ: Sender: news@princeton.Princeton.EDU Reply-To: nfs@notecnirp.UUCP (Norbert Schlenker) Organization: Dept. of Computer Science, Princeton University Lines: 76 In article <682@augean.OZ: cagney@chook.ua.oz (Andrew Cagney - aka Noid) writes: : :I've being trying to compile earl chew's stdio using the POSIX header files :recently posted. Among the problems encountered there is the following: : :In POSIX/usr/include/fcntl.h creat is declared as: : _PROTOTYPE( int creat, (char *__path, int __mode) ); : ie int creat(char *__path, int __mode); :Where as Earl has declared it as: : int creat P((const char *, mode_t)); /* create a file */ : ie int creat(const char, mode_t); :The two key differences are: : 1. const : 2. mode_t :Which is correct? I suspect that the correct one should be: : : _PROTOTYPE( int creat, (const char *__path, mode_t __mode) ); :ie int creat (const char *__path, mode_t __mode); : :(Yes I know that the names __path & __mode are optional but they are still :nice :-) : :any thoughts? : Andrew Cagney : cagney@cs.ua.oz.au Well, it's always nice to see all but the correct possibility chosen.:-) The correct prototype, per IEEE 1003.1, is: _PROTOTYPE( int creat, (char *__path, mode_t __mode) ); i.e. int creat(char *__path, mode_t __mode); The declaration of mode's type is a simple oversight on Andy's part (but I have to admit that I didn't see it either when I had a sneek peek in advance of the posting). The declaration of the pathname is more interesting though. Functions like fopen() take a string as one of their arguments, and ANSI insists that the string be declared "const char *". ANSI (rightly) figures that the fopen() user wants a file opened, not a character string mangled, and enforces that with "const". Earl's stdio then turns around and hands that string to creat() in some cases. Now if creat() is declared to take a "char *" (without the const), an ANSI compiler, like gcc can be, should fail when compiling fopen(). That's because it isn't legal to loosen the restriction on such a pointer. (I can't quote chapter and verse from ANSI, but it's so. Trust me :-) The only legal way to do this correctly, I believe, is something like: FILE *fopen(const char *path, const char *mode) { ... char localpath[PATH_MAX+1]; ... strcpy(localpath, path); ... creat(localpath, 0666); ... } So there is extra overhead (both time and space) for doing this right. I understand why Earl did what he did; I did almost the same thing for my package, but had the audacity to ignore gcc's complaints. What should be done? I believe that the correct thing is that POSIX should be modified to reflect the non-modifiability of the pathname. After all, programs use creat() to create files, not to mangle pathnames. But knowing that the standard is virtually set in stone at this point, I think the correct thing is out of the question. What will be done? I am considering changing my code to handle this, but confess that a change which will cost space and time and which I know will never be necessary in Minix (since I have the source of creat()) isn't very high on my list of priorities. Norbert