Info-Unix-Request@BRL.ARPA (Mike Muuss) (07/22/85)
INFO-UNIX Digest Sun, 21 Jul 1985 V1#110 Today's Topics: DECNET <-> UNIX info needed Porting mallocs and structures (followup) Re: inconsistency on read/execute permissions for shell procedures Re: Is there a UNIX SVR2 random/srandom equivalent? what/where is libcore.a?? Lint Libraries Re: Portablity using structures and malloc - Help Re: inconsistency on read/execute permissions for shell procedures Re: Lint Libraries ----------------------------------------------------------------- From: system@asuvax.UUCP (Marc Lesure) Subject: DECNET <-> UNIX info needed Date: 17 Jul 85 15:56:55 GMT To: info-unix@brl-tgr.arpa I need information on connecting 4.2 Unix ethernet to VAX/VMS DECNET. All help would be greatly welcomed. Thanks - ------------------------------------------------- Marc Lesure UUCP: ...!ucbvax!arizona!asuvax!lesure CSNET: lesure@asu ARPA: lesure%asu@csnet-relay ----------------------------- From: vlv@drux1.UUCP (Vaughn Vernon) Subject: Porting mallocs and structures (followup) Date: 18 Jul 85 22:27:27 GMT To: info-unix@brl-tgr.arpa Thanks for all the responses! So fast also! So many of the folks that responded said: "So what's the problem?". That's the same thing that I asked myself. In the interest of finding out more on alignment and possible problems I made up some of the members in the structure example. I figured: if your going to ask a question, be as stupid as possible and get all the information you *may* ever need! You see, I made up almost all of the members in the structure. My real structure only contained character arrays and single character variables. I did it not knowing how the 3B would treat int's (and alignment), and for some other reasons too. My code was blamed for problems but nothing appiers to be wrong with my code. At run-time we were getting something like: "Invalid Instruction - core dumped" (?huh?-you got me?!) I was told that I had a one in four chance of getting a word boundary from malloc on a four byte word non-aligned system. Sounds like Los Vegas to me! But I did learn from *your* help that I don't have to give up all those slick coding methods. I'm not saying slezzy. I don't do that. One of my big concerns was whether sizeof(struct line) took into consider- ation (knew) the gaps that are needed to align int's, doubles and the like. Why wouldn't it?! According to Rich Hammond (rest below): >3) Sizeof is built into the compiler and knows how big the structure is > counting the gaps between elements. I tested it. Even on the VAX cc && sizeof() used the gaps. Also realizing that in aligning all elements for the compiler on any machine is the best thing to do since the code will run faster and uses less memory. The 8086's bus will make two trips to give you an int that straddles two two-byte words. This has some overhead. Along this line, the winner of the Fastest Response Award, Alan Bland writes: >by some external interface). I would define your structure as follows. >The first members are the ones that typically need the largest >alignment boundary. Character arrays are always last. By coding: struct x { int a; char b,c,d,e,f,n[81]; }; instead of: struct x { char n[81]; int a; char b,c,d,e,f; }; or even: struct x { int a; char n[81]; char b,c,d,e,f; }; you use 4 & 3 less bytes respectively per structure on the VAX. This is the kind of rule that I was looking for. It makes simple sense and you don't have to use any crazy unions. According to the other responses about sizeof() though, it's not nessasary on 3B's and 68000's. It certainly is safe and efficient. Yes I did guff in my example. Matt Crawford caught this (first): if((lines[i]->xyz = malloc(sizeof(lines[i]->xyz)))==(char *)NULL) --------------------- It was supposed to be: if((lines[i]->xyz = malloc(strlen(of_something)+1))==(char *)NULL) --------------------- strcpy(lines[i]->xyz, something); For the most part all stressed the rule : char *malloc(num); "allocates num bytes. The pointer returned is sufficiently well aligned to be usable for any purpose. ..." I totally agree with Jim: > .... What is the >use of a high level language if you have to worry about stuff like this. Enjoy reading and thanks again. Vaughn Vernon ihnp4!drutx!drux1!vlv Disclaimer!Disclaimer!Disclaimer! (response cut off Jul 18 - 1:00pm - this is getting huge! edited.) ----------------- From mab Wed Jul 17 14:39 MDT 1985 remote from druca First, according to the manual page, malloc is guaranteed to return a pointer that is suitably aligned to hold any data object. So, at least for the first structure member, it will always be aligned properly. As far as alignment within the structure, it's often possible to rearrange the structure members so that there are no alignment problems (of course you can't do this if the structure ordering is imposed by some external interface). I would define your structure as follows. The first members are the ones that typically need the largest alignment boundary. Character arrays are always last. struct line { double abc; /* no alignment by me! */ char *xyz; int x, /* here either */ y, z; char n[81]; } *lines[MAXLINES]; This definition shouldn't have any extra filler bytes anywhere on most machine architectures. If there are any machines where ints are larger than pointers, then there might be filler characters stuffed between *xyz and x, but the above techique works for me on vax, 3b, and 8086. Alan Bland, druca!mab ------------------- From: ulysses!ggs (Griff Smith) It's really not a problem. The specification of malloc requires that the pointer it returns must point to a "safe" address. ... To get to a 32-bit word boundary for a character pointer, you can use p += 3; p &= ~3; I don't recommend this for portable code, however; it makes too many assumptions about the structure of a pointer. Malloc is safe. ------------------- From: ihnp4!oddjob!matt (Matt Crawford) The compiler decides at compile time what padding is needed and where, assuming that the beginning of the struct is on a major boundary. ... You are doing one fishy thing, however. Why do you write if((lines[i]->xyz = malloc(sizeof(lines[i]->xyz)))==(char *)NULL) --------------------- ? lines[i]->xyz already has space to hold a pointer-to-char. You should perhaps be allocating space for a string of some other size than the size of the pointer itself. ----------------- From: ihnp4!bellcore!hammond (Rich A. Hammond) What was your problem? The malloc(sizeof (struct line) ) should work on any machine because sizeof is built into the compiler and knows how big the structure is and the compiler should allocate offsets in the structure so that all elements fall on legal boundaries. Note that malloc is defined to return at least the requested number of bytes on a boudary suitable for storage of any object. Are you sure your problem was with malloc? Please post the responses to the net, I don't see a problem with what you did. ----------------- From: hounx!bear It's supposed to be automatic. malloc(3C) says: "Malloc returns a pointer to a block of at least size bytes SUITABLY ALIGNED for any use." In my experience (VAX, IBM 3081, 6300) what you originally used works. How much space the structure takes up is a function of the machine. What is the use of a high level language if you have to worry about stuff like this. Jim ------------------------ From: ihnp4!bellcore!hammond (Rich A. Hammond) You don't need the unions, the original example, struct line, ... malloc(sizeof (struct line)) will work because 1) malloc returns a pointer to an area that is at least as large as requested, "suitably aligned (after possible pointer coercion) for storage of ANY [emphasis mine] type of object." ... 2) The compiler automagically leaves gaps in structures when needed to make sure that the elements fall on an appropriate addressing boundary. 3) Sizeof is built into the compiler and knows how big the structure is counting the gaps between elements. ... What was the problem, all you said was that you had one, but the code (not the union stuff) looked fine? --------------------- From: ihnp4!ihnet!tjr The subject of the internal alignment of objects in structures is one of the (several) areas where C is not very portable. The lack of portability is in the data formats, not the code (i.e. any code should work on any machine, as long as the data is not passed to another machine). Unfortunately, different compilers work differently when aligning objects within structures (and outside, too). VAX: no alignment (SVR2 C compiler) 3B2: every int or short or long aligned to 4-byte addr; every struct aligned to 4-byte addr. chars and char arrays have no alignment. BELLMAC8: no alignment. In general, we have found it necessary to add filler arrays of chars to manually align everything other than chars to a 4-byte addr within the enclosing struct; we also fill all structs to be a multiple of 4-bytes long. EXAMPLE: struct bletch { int a; char b[3]; char filler1; struct foo c; char d; char filler2[3]; int e; }; Again, this problem normally only gets you when you have multiple CPU-types passing data around. ---------------------- >From lfd Thu Jul 18 11:01:25 EDT 1985 remote from whuxlm Then, quoting from MALLOC(3C) or MALLOC(3X) in the System V Release 2.0 Programmer Reference Manual, Malloc returns a pointer to a block of at least size bytes suitably aligned for any use. Lee Derbenwick AT&T BL, Whippany NJ ------------------ >From mp Thu Jul 18 10:15:42 1985 remote from allegra malloc returns addresses that are aligned on suitably strict boundaries so that you shouldn't have any problem accessing structure elements. By the way, what does this do? It looks like it's allocating 4 bytes (the size of a character pointer) and assigning the address of those 4 bytes to a character pointer. if((lines[i]->xyz = malloc(sizeof(lines[i]->xyz)))==(char *)NULL) Mark Plotnick allegra!mp ------------------- From: vax135!petsd!pedsgd!jje according to the malloc(3C) manual page (at least the System III and System V versions) "...each of the allocation routines returns a pointer to space suitable aligned (after possible pointer coersion) for storage of *any* type of object..." (emphasis added). --Jeremy Epstein Perkin-Elmer {decvax,ucbvax}!vax135!petsd!pedsgd!jje ---------------- From: ihnp4!uiucdcs!uiucdcsb.Uiuc.ARPA!johnston (Gary Johnston) 1. Malloc(III) *always* returns a word-aligned address (i.e., even). This is true for every malloc() that I've ever heard of. Malloc has no idea of the type of object that you are intending to allocate memory for, but everything should be OK if it's word-aligned. 2. The compiler should take care of aligning fields within structs. The offsets that my 68000 C compiler would use are struct line { char n[81]; /* 0 */ double abc; /* 82 (NOTE: PADDING WAS DONE) */ int x, /* 90 */ y, /* 94 */ z; /* 98 */ char *xyz; /* 102 */ } *lines[MAX_LINES]; So, sizeof(struct line) is 106 bytes. -------------- From: ihnp4!plus5!hokey I am surprised that you had a problem given the example you posted. The compiler is supposed to align structure members. This means that the total size of the structure may be larger than it "could" be, but all the elements are properly aligned for you. Note that writing the structure to disk will keep the "alignment holes" in place, which means one can read the *structure* back in without problems. If you write the structure out to disk element-by-element, these "alignment holes" are not written, but you get better space allocation on disk. This also means that the data must be read back in element-by-element. Are you doing something tricky like trying to reference elements based on an offset from the beginning of the structure? ---------------- >From merlyn Thu Jul 18 11:21 EDT 1985 remote from avalon The malloc routine "returns a pointer ... suitably aligned for any use" according to the manual. Is this what you're looking for? Steve Humphrey ----------------------------- From: sean@ukma.UUCP (Sean Casey) Subject: Re: inconsistency on read/execute permissions for shell procedures Date: 18 Jul 85 05:51:13 GMT To: info-unix@brl-tgr.arpa In article <6503@boring.UUCP> guido@mcvax.UUCP (Guido van Rossum) writes: >In article <1945@ukma.UUCP> sean@ukma.UUCP (Sean Casey) writes: >> ... since a simple solution would be to have the kernel hand the >>shell the file on standard input if --x access is permitted. ... > >Simple: the shell's standard input is also the shell file's standard input, >and with your proposed solution the shell script wouldn't be able to read >interesting user data from its standard input, wouldn't be usable as a filter, >etc. So the contents of the shell file has to be presented to the shell >without closing or dupping the standard input. Ok, that makes sense. How about handing the shell an open file descriptor with the shell script opened for reading? Sean -- - Sean Casey UUCP: sean@ukma.UUCP or - Department of Mathematics {cbosgd,anlams,hasmed}!ukma!sean - University of Kentucky ARPA: ukma!sean@ANL-MCS.ARPA ----------------------------- From: edward@ukecc.UUCP (Edward C. Bennett) Subject: Re: Is there a UNIX SVR2 random/srandom equivalent? Date: 14 Jul 85 20:21:04 GMT To: info-unix@brl-tgr.arpa In article <156@ukecc.UUCP>, edward@ukecc.UUCP (Edward C. Bennett) writes: > In article <2399@sun.uucp>, guy@sun.uucp (Guy Harris) writes: > > > > Does anyone know what I should use in place of random and srandom? > > > > In particular, while BSD and sysV RNGs both return ints, you > must pay attention to what an int is. On a local VAX 11/750 an int is 4 > bytes. On our 3B20S an int is 2 bytes. > Usually this won't make any difference, but every now and then > you'll probably find a program where it does. It seems that I spoke too soon. Ints on our 3B20S are indeed 4 bytes long. rand() returns a 4 byte value BUT (this is the catch) the value is masked to its lower 15 bits yeilding 0 <= rand() <= 32767. -- Edward C. Bennett UUCP: ihnp4!cbosgd!ukma!ukecc!edward /* A charter member of the Scooter bunch */ ----------------------------- From: quent@isucs1.UUCP Subject: what/where is libcore.a?? Date: 12 Jul 85 19:36:24 GMT Sender: notes@isucs1.UUCP Nf-ID: #N:isucs1:17600002:000:351 Nf-From: isucs1!quent Jun 28 15:12:00 1985 To: info-unix@brl-tgr.arpa The makefile for Franz lisp, when making the 68000 version, refers to a file called "/usr/lib/libcore.a". On our 4.2bsd Vax system I can't find this file. Can anyone enlighten me about this? Thanks... Quent Johnson ISU Computer Science Department (515) 294-7214 CSNET: quent@iowa-state UUCP: ...{umn-cs | okstate}!isucs1!quent ----------------------------- From: russell@isucs1.UUCP Subject: Lint Libraries Date: 12 Jul 85 19:36:03 GMT Sender: notes@isucs1.UUCP Nf-ID: #N:isucs1:17600001:000:390 Nf-From: isucs1!russell Jun 20 14:13:00 1985 To: info-unix@brl-tgr.arpa I have a question about lint that I would like answered. I like to use the power of the -C option to create lint libraries, but I have yet to find a way to convert the lint library to a human readable form (like has been done to the standard libraries). If anyone knows how to make this conversion, please let me know. Russell B. Jorgensen {umn-cs,okstate,csu-cs}!isucs1!russell ----------------------------- From: jack@boring.UUCP Subject: Re: Portablity using structures and malloc - Help Date: 20 Jul 85 22:23:33 GMT Apparently-To: rnews@mcvax.LOCAL To: info-unix@brl-tgr.arpa In article <81@drux1.UUCP> vlv@drux1.UUCP (Vaughn Vernon) writes: > >struct line { > char n[81]; > double abc; /* no alignment by me! */ > int x, /* here either */ > y, > z; > char *xyz; >} *lines[MAXLINES]; >... > if((lines[i] = (struct line *)malloc(sizeof(struct line)))\ > ==(struct line *)NULL) > ... > if((lines[i]->xyz = malloc(sizeof(lines[i]->xyz)))==(char *)NULL) > ... What is done here is probably not what was intended. You've allocated a character array with the size of a pointer (e.i. probably 2 or 4 bytes). You should either change the second malloc() to ... lines[i]->xyz = malloc(MAXLINESIZE) ... if you *really* want xyz to be a pointer to the data, or change the declaration to ... char xyz[1]; and replace both malloc() by one like this: lines[i] = (struct line *)malloc(sizeof(struct line)+ MAXLINESIZE-1); This way you'll have the string inside the structure. This has the disadvantage of being slightly tricky code, but the advantage that the whole thing is contiguous, and you can dispose of it with a single free() call. About alignment of malloc(): - It always assumes worst case, so the pointer returned will be able to point to anything, if correctly casted. - *NEVER* assume that two malloc() calls will give you contiguous storage. On the contrary, the won't on any machine that I know of, since malloc() allocates a few bytes for it's own administration. -- Jack Jansen, jack@mcvax.UUCP The shell is my oyster. ----------------------------- From: jpl@allegra.UUCP (John P. Linderman) Subject: Re: Portablity using structures and malloc - Help Date: 20 Jul 85 17:21:09 GMT To: info-unix@brl-tgr.arpa > The answer is simple: malloc has been written by someone who knows > the hardware alignment constraints of the machine, and it returns > a pointer that is aligned for *any* use. > > In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) malloc knows, but it's a pity that you can't make malloc tell. If there were a nice int malign() {return ALIGNMENT_MULTIPLE;} entry in the malloc package, I could do my own storage allocation out of an area acquired from malloc or elsewhere. [I might want to do this so I could allocate variable-length structures from both ends of an area until the area was filled, something malloc itself cannot be made to do.] A totally trivial one-liner that would make it much easier to write portable software. How about it, system implementors? John P. Linderman The much-maligned allegra!jpl ----------------------------- From: chris@umcp-cs.UUCP (Chris Torek) Subject: Re: Portablity using structures and malloc - Help Date: 21 Jul 85 03:31:41 GMT To: info-unix@brl-tgr.arpa > malloc knows [the alignment constraints of the machine], but it's > a pity that you can't make malloc tell. If there were a nice > > int malign() {return ALIGNMENT_MULTIPLE;} True. However, there is a general rule you can use that I've not yet seen fail on any machine: align your object on an ``n'' bit boundary, where ``n'' is the smallest power of 2 that is not less than the size of the object you're allocating. (Of course this can be quite wasteful for large areas....) In case what I wrote doesn't say what I really meant, here's an example: int malign(size) register int size; { register int n = 0; while ((1 << n) < size) n++; return (1 << n); } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland ----------------------------- From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) Subject: Re: inconsistency on read/execute permissions for shell procedures Date: 21 Jul 85 05:13:12 GMT To: info-unix@brl-tgr.arpa > Ok, that makes sense. How about handing the shell an open file descriptor > with the shell script opened for reading? ?? The shell will open the file specified as an argument, or if that is omitted, it will take commands from FD # 0 (standard input). How would opening a file on e.g. FD # 3 do any good? ----------------------------- From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) Subject: Re: Lint Libraries Date: 21 Jul 85 05:14:27 GMT To: info-unix@brl-tgr.arpa > I have a question about lint that I would like answered. I like to use the > power of the -C option to create lint libraries, but I have yet to find a > way to convert the lint library to a human readable form (like has been done > to the standard libraries). Wrong way around. START with a human-readable lint library source .c and make the binary lint library from that. ----------------------------- End of INFO-UNIX Digest ***********************