home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.solaris:216 comp.sys.sun.misc:4241 comp.unix.programmer:4673
- Path: sparky!uunet!auspex-gw!guy
- From: guy@Auspex.COM (Guy Harris)
- Newsgroups: comp.unix.solaris,comp.sys.sun.misc,comp.unix.programmer
- Subject: Re: swapctl() problems
- Keywords: swap swapctl
- Message-ID: <14658@auspex-gw.auspex.com>
- Date: 16 Sep 92 00:29:06 GMT
- References: <1992Sep15.215809.20252@icd.teradyne.com>
- Sender: news@auspex-gw.auspex.com
- Followup-To: comp.unix.solaris
- Organization: Auspex Systems, Santa Clara
- Lines: 79
- Nntp-Posting-Host: auspex.auspex.com
-
- > The specific problem is that function seems to want you to
- > define a struct which has as one of its members an array of structs.
- > However, the struct declaration in /usr/include/swap.h declares that
- > array to be of length 1. This causes no end of problems which I can't
- > seem to get around.
-
- A fairly standard C-language trick; take a look at the SV message queue
- stuff, for example.
-
- Standard C doesn't support the notion of variable-length arrays, so you
- can't declare a structure that contains such an array, which is what the
- structure filled in by the SC_LIST call *really* is. So, instead, such
- a structure is declared with a fixed-length array, and you have to
- depend on compile-time array-bounds checking not being done; you also
- have to create such a structure yourself, e.g. by dynamically
- allocating it.
-
- Furthermore, standard C doesn't support zero-element arrays, so a data
- structure with a variable-length array as the last element is often
- declared as having a one-element array.
-
- Assuming that there's one entry in "swt_ent" for every swap resource,
- you can use SC_GETNSWP to find out how many entries there are:
-
- int n_swap_entries;
-
- n_swap_entries - swapctl(SC_GETNSWP, NULL);
- if (n_swap_entries == -1)
- complain and quit;
- if (n_swap_entries == 0)
- note that there are, miraculously, no swap entries, and quit;
-
- Then allocate a table to hold that many entries:
-
- swaptbl_t *swaptbl;
-
- swaptbl = (swaptbl_t *)malloc(
- sizeof (swaptbl_t) + (n_swap_entries - 1)*sizeof (struct swapent));
-
- It's "n_swap_entries - 1" because the first entry is accounted for by
- "sizeof (swaptbl_t)".
-
- Then put the number of elements into the structure:
-
- swaptbl->swt_n = n_swap_entries;
-
- Then fetch the entries:
-
- n_swap_entries = swapctl(SC_LIST, (void *)swaptbl);
- if (n_swap_entries == -1) {
- if (errno == ENOMEM)
- try again, with a bigger array;
- else
- complain and quit;
- }
-
- and loop through them.
-
- NOTE: "complain" in "complain and quit" doesn't mean "print some typical
- dumb UNIX error message saying that the call failed", it means "print
- some atypical *useful* error message that prints the error string
- associated with 'errno' - using 'perror()' or 'strerror()' - so that if
- it fails you have a clue as to why". (It doesn't mean "print some
- typical only-marginally-less-dumb UNIX error message giving the
- numerical value of 'errno'", either; computers are at *least* as good as
- humans at translating cryptic numeric values such as that into error
- messages.)
-
- "Try again, with a bigger array" deals with the case where a new entry
- was added to the table between the two "swapctl()" calls.
-
- If SC_GETNSWP *doesn't* return the number of entries you should expect
- to get back from SC_LIST (although, if not, I've no idea why the hell
- SC_GETNSWP exists), you'll have to go through some more pain, starting
- at some fixed table size and, for example, doubling it each time the
- SC_LIST call fails with ENOMEM. Hopefully, that's not the case....
-
- (No, I don't have a SunOS 5.0 system with a C compiler handy on which to
- try the above, so you'll have to do it yourself.)
-