From owner-cvs-sys Fri Oct 27 23:27:20 1995 Return-Path: owner-cvs-sys Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id XAA16804 for cvs-sys-outgoing; Fri, 27 Oct 1995 23:27:20 -0700 Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id XAA16766 ; Fri, 27 Oct 1995 23:27:05 -0700 Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.9/8.6.9) id QAA16949; Sat, 28 Oct 1995 16:12:09 +1000 Date: Sat, 28 Oct 1995 16:12:09 +1000 From: Bruce Evans Message-Id: <199510280612.QAA16949@godzilla.zeta.org.au> To: bde@zeta.org.au, terry@lambert.org Subject: Re: SYSCALL IDEAS [Was: cvs commit: src/sys/kern sysv_msg.c sysv_sem.c sysv_shm.c] Cc: CVS-commiters@freefall.freebsd.org, bde@freefall.freebsd.org, cvs-sys@freefall.freebsd.org, hackers@freebsd.org, swallace@ece.uci.edu Sender: owner-cvs-sys@freebsd.org Precedence: bulk >> >I don't understand why passing a bogus mode to open when O_CREAT wasn't >> >present would be a problem??? >... >Hence, my use of the 0 argument on the open in user space in the last >posting to provide a valid call on vararg. The open(2) call is not The difficulty is to extract the 3rd arg if it exists. >a traditional vararg -- it's a limited one. The "..." in its case >means "0 or one argument here" instead of "0 or n arguments here". This only reduces the difficulty. In general you might have to decode all previous args to decide how to extract eacg arg. >I don't know of a real vararg system call. Grepping for \.\.\. in shows the following: open, fcntl, ioctl, msgsys, semsys, shmsys. The last 3 have more than one varargs arg. >> >> SYSCALL_ENTRY(open) >> >> { >> >> ARG( char const *, PATH); >> >> ARG( int, FLAGS); >> >> ARG( promoted_mode_t, MODE); >> >> >> >> return open(p, retval, PATH, FLAGS, MODE); >> >> } >> >> This would require large table of #defines of OFFSETs. I prefer to use >> literal offsets. >Keep all paths at the same offset, etc. You can't. The offsets depend on the ABI. In particular they depend on the word size and endianness even if the packing is the natural one. >Actually, MSC doesn't align stuff correctly. They (Microsoft) pad many >things to even alignment boundries, but structure contents themselves >are tightly packed. This is probably inherited from 16-bit packing and calling conventions. >> #pragma pack(0) /* or whatever stops all packing */ >> struct read_args { >> char const *path; >> int flags; >> char pad1[4]; /* little endian, 4 byte ints, 8 byte regs */ >> mode_t mode; >> char pad2[6]; >> }; >That would be better expressed as: >> #pragma pack(8) /* quad stack alignment, pointers are quads*/ >> struct read_args { >> char const *path; >> int flags; >> mode_t mode; >> }; gcc-2.6 only supports pack(1)..pack(4) - the natural padding can't be increased. Note that it need may need to be increased to support a foreign ABI, and it isn't even natural on Pentiums (doubles should have 8 byte alignment). #pragma is unportable. My version has the advantage of requiring only 1 pragma per struct, while yours requires up to one pragma per struct member and it may still require padding. Consider alignment of 4-byte quantities on boundaries 4, 9, 16, 25, ... >> `lcall' allow users to trace into syscalls. This can be recovered from >I understand the rationale for considering the changes. I don't understand >the rationale for making them. It seems the rationale is "to compete with >NetBSD and Linux regarding speed". Is this correct? To compete in speed and elegance. >> >This was my point on the quad crap and reverting the default interfaces >> >to POSIX compliance (and double doesn't count unless you can use it >> >without a prototype in scope). >> >> if (lseek(fd, (off_t)foo, SEEK_SET) == (off_t)-1) >> perror("lseek"); >> >> works without a prototype in scope even if off_t is quad or double. >But violates POSIX (in the quad case) or the spirit of POSIX (in the >double case -- you yourself suggested that this is probably an error >in the spec). Doesn't matter. The call and check must be written something like the above so that it works independent of the type of off_t even if off_t is one of char, short, int or long. Actually if foo is a variable then it should have type off_t, and the cast of -1 is unnecessary because off_t is _signed_ arithmetic, so the statement should normally be written as if (lseek(fd, foo, SEEK_SET) == -1) perror("lseek"); >> >> Consider a 68K compiler that passes the first 2 pointer args (if any) >> >> in a0-a1 and the first 2 integer args (if any) in d0-d1 and the other >> ... >> But not stupid :-). >OK. I admit it's probably minisculely faster. Is it worth the clutter >of the xxx_OFFSET and the xxx_type and the unreadable glue routines to >get that miniscule speed "improvement"? If it is the compiler or ABI's calling convention, then you have no choice. Bruce