home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / answers / Solaris2 / porting-FAQ < prev    next >
Internet Message Format  |  1993-12-29  |  43KB

  1. Path: bloom-beacon.mit.edu!spool.mu.edu!news.clark.edu!netnews.nwnet.net!news.uoregon.edu!news.uoregon.edu!meyer
  2. From: meyer@cambium.uoregon.edu (David M. Meyer 503/346-1747)
  3. Newsgroups: comp.unix.solaris,comp.answers,news.answers
  4. Subject: Solaris 2 Porting FAQ
  5. Followup-To: comp.unix.solaris
  6. Date: 29 Dec 1993 13:44:13 GMT
  7. Organization: University Network Services, University of Oregon, Eugene, OR
  8.     97403
  9. Lines: 1142
  10. Approved: news-answers-request@MIT.Edu
  11. Distribution: world
  12. Message-ID: <MEYER.93Dec29054413@cambium.uoregon.edu>
  13. Reply-To: meyer@ns.uoregon.edu (David M. Meyer 503/346-1747)
  14. NNTP-Posting-Host: cambium.uoregon.edu
  15. Summary: This posting contains a list of Frequently Asked
  16.      Questions (and their answers) about porting to BSD
  17.      applications to ANSI/SVID/SVR4 systems (in general) and
  18.      Solaris 2 (in particular).
  19. Xref: bloom-beacon.mit.edu comp.unix.solaris:10730 comp.answers:3193 news.answers:13436
  20.  
  21.  
  22.  
  23. Archive-name:   Solaris2/porting-FAQ
  24. Last-modified:  Tuesday, November 09, 1993
  25. Version:        2.6
  26.  
  27. Solaris 2 Porting FAQ
  28. [Last changed: 09 November 93]
  29.  
  30. This article contains the answers to some Frequently Asked
  31. Questions (FAQ) often seen in comp.unix.solaris that relate to
  32. porting BSD/Solaris 1 applications to Solaris 2. Over the first
  33. few days of its existence, it has evolved into a more general
  34. discussion about portability among Unix systems, especially as it
  35. relates to BSD, ANSI, POSIX, and SVID compliant systems.  It is
  36. hoped that this document will help reduce volume in this
  37. newsgroup and to provide hard-to-find information of general
  38. interest.
  39.         
  40.         Please redistribute this article!
  41.  
  42. This FAQ is maintained by David Meyer (meyer@ns.uoregon.edu).
  43. Send updates and corrections to me at this address.  It would
  44. help if the subject line contained the phrase "FAQ".
  45.  
  46. This article includes answers to the following questions.  Ones
  47. marked with a + indicate questions new to this issue; those with
  48. changes of content since the last issue are marked by *:
  49.  
  50. 0)  Which preprocessor symbols to use?
  51. 1)  Some Include File Issues
  52. 2)  Libraries
  53. 3)* Possible ANSI/POSIX/SVR4 replacements for some popular BSD functions 
  54. 4)  Signal Primer
  55. 5)  Waiting for Children to Exit
  56. 6)  Dealing with Shadow Password Files
  57. 7)  Some Compatabilty Problems
  58. 8)  Other Resources
  59.  
  60. -----------------------------------------------------------------------------
  61. 0) TOPIC: Which preprocessor symbols to use?
  62.  
  63. [Last modified: 11 October 93]
  64.  
  65. [Editor's Note: This section began life as a Solaris 1 and 
  66. Solaris 2 centric discussion. However, it has grown into a more 
  67. generalized portability discussion. I believe that this is a
  68. useful discussion, but it appears that contrasting styles,
  69. preferences, and requirements will make consensus difficult. DM]
  70.  
  71. Answer: This is a difficult and controversial question.
  72.  
  73. In order to understand the following discussion, we need to be
  74. aware of the following standards:
  75.  
  76. ANSI C (ANSI X3J11) 
  77.                 
  78.         This is the standard C definition, originally adopted as
  79.         American National Standard X3.159-1989 and has since been
  80.         adopted as international standard ISO/IEC 9899:1990.
  81.  
  82.                 
  83. POSIX.1 (IEEE 1003.1-1990)
  84.  
  85.         POSIX.1, the Portable Operating System Interface for
  86.         Computer Environments,  is a system level API that deals
  87.         with the function and format of system calls and
  88.         utilities such as signal handling. 
  89.  
  90. SVID3
  91.  
  92.         SVID3, the System V Interface Definition Issue 3, is is
  93.         fully compliant with POSIX.1, and is a arguably subset of
  94.         the SVR4 system API. For example, SVID3 doesn't have
  95.         "-ldl", but many people consider it of the SVR4 API. That
  96.         is, a system could be SVID3-compliant without necessarily
  97.         being an SVR4 system.
  98.  
  99. XPG
  100.  
  101.         XPG, X/Open Company Ltd's X/Open Portability Guide, is a
  102.         broad document which covers a great number of areas,
  103.         including operating systems and programming languages,
  104.         system interfaces, and internetworking. The latest
  105.         version, XPG4, groups these components into "profiles",
  106.         which are packaged together according to market needs.
  107.  
  108.  
  109. Two additional standards are relevant for Suns:
  110.  
  111. SCD 2.0 and x86 ABIs
  112.  
  113.         SCD 2.0 is the SPARC Compliance Definition 2.0. The SCD
  114.         has two components: On the hardware side, 
  115.  
  116.          (i).   System Compliance Test verifies that the hardware
  117.                 and operating system successfully emulates what
  118.                 Sun is doing. It covers low level system issues
  119.                 such as alignment, and linking and loading. 
  120.  
  121.         (ii).   The SPARC Application Verifier tests software to
  122.                 be sure that it runs on SCD hardware. 
  123.  
  124.                 
  125. As an example of subtle differences that exist between the BSD
  126. interface and SVID/POSIX standards, consider the BSD mktemp(3)
  127. call. The SunOS 4.1 mktemp() replaced the trailing X characters
  128. with the letter (e.g., X) and the current process ID. The SVID
  129. and SVR4 versions specify only that the six trailing Xs be
  130. replaced with a character string that can be used to create a
  131. unique filename, and does not depend on the specific name of the
  132. file.  Thus, the BSD and SVR4/SVID3 versions are only
  133. semantically equivalent in the case where only the application
  134. cares that the filename is unique.
  135.  
  136. Now, the basic philosophical question of which preprocessor
  137. contstucts to use here would appear to revolve around the
  138. following choices: 
  139.  
  140.         (i).    Use a high level, large grained standard
  141.                 definition (e.g., _POSIX_SOURCE). In this case,
  142.                 features are implicitly defined. One problem with
  143.                 such definitions is that they may cause other
  144.                 useful functions to become unavailable. However,
  145.                 there are several such definitions in common use.
  146.                 For operating systems, we have
  147.  
  148.                         SVR4
  149.                         SYSV
  150.                         BSD
  151.                         OSF1
  152.  
  153.                 to name a few. For standards, we are mainly
  154.                 interested interested symbols such as 
  155.  
  156.                         __STDC__
  157.                         _POSIX_SOURCE
  158.                         _XOPEN_SOURCE
  159.                 
  160.   
  161.                 This method is not without pitfalls.  For
  162.                 example, the Sun SC2.0.1 compiler defines
  163.                 __STDC__ as 0 when compiling in transition mode
  164.                 (-Xt), only setting it to 1 when the strict ANSI 
  165.                 mode (-Xc) is used. The expression 
  166.  
  167.                         #if (__STDC__ - 0 == 0) 
  168.  
  169.                 can be used to recognize strict v. transition
  170.                 ANSI modes. On Solaris 2, if you compile with
  171.                 -Xc, you will lose all non-ANSI functionality.
  172.                 However, you can define _POSIX_SOURCE or
  173.                 _XOPEN_SOURCE to get a POSIX or XOPEN
  174.                 environment.   
  175.                 
  176.                 If you use _POSIX_SOURCE, .eg., 
  177.                 
  178.                         #define _POSIX_SOURCE 1
  179.  
  180.                 then all symbols not defined by Standard C or the
  181.                 POSIX standard will be hidden (except those with
  182.                 leading underscores). If you wish to use
  183.                 _POSIX_SOURCE, be sure to define it before
  184.                 including any standard header files, and avoid
  185.                 name clashes by not defining any symbols that
  186.                 begin with "_" (Similarly, note that almost all
  187.                 names beginning with  "E" are reserved by
  188.                 errno.h, and many names prefixed by "va_"
  189.                 reserved by stadarg.h). 
  190.  
  191.                 One more note on _POSIX_SOURCE:   SunOS 5.3 has
  192.                 introduced the new header file <sys/feature_tests.h>. 
  193.                 This file is included in all files which have
  194.                 _POSIX_SOURCE dependancies. 
  195.  
  196.                 A new symbol,  _POSIX_C_SOURCE was introduced in POSIX.2
  197.                 (V1 P720, L51) as a mechanism to enable POSIX.1 and
  198.                 POSIX.2 symbols. Its values are as follows:
  199.  
  200.                 /*
  201.                  *      Values of _POSIX_C_SOURCE
  202.                  *
  203.                  *              undefined       not a POSIX compilation
  204.                  *                      1       POSIX.1-1990 compilation
  205.                  *                      2       POSIX.2-1992 compilation
  206.                  *                1993xxL       POSIX.4-1993 compilation
  207.                  */
  208.  
  209.  
  210.                 This means that POSIX.2 says that a value of 1 = POSIX.1
  211.                 and a value of 2 = POSIX.1 & POSIX.2. The idea here is
  212.                 to provide a single control point over the POSIX namespace,
  213.                 rather than having to edit each file individually. 
  214.  
  215.                 Another potential portability pitfall is the
  216.                 __svr4__ feature defined by the FSF (gcc). If you
  217.                 depend on __svr4__, you may lose portability.
  218.                 gcc also defines sun if you don't give the -ansi
  219.                 argument. If you use -ansi,  then sun is not
  220.                 defined and __sun__ is.
  221.  
  222.                 Finally, complexity may arise surrounding a
  223.                 feature which may be part of some vendor's
  224.                 version of some system Y, but may also exist in
  225.                 non-Y compliant systems. Consider, for example,
  226.                 shadow passwording. Systems conforming to the
  227.                 latest SVID (e.g., SVR4) have shadow.h, but there
  228.                 are many systems that have shadow.h without
  229.                 conforming to the SVID.
  230.  
  231.                 So, in general, for code that uses a STD_FEATURE and
  232.                 runs on systems W, Y, and Z, you are left with 
  233.                 something that may look like   
  234.  
  235.                         #if defined(W)                          ||
  236.                            (defined(Y) && _Y_VERSION_ > 3)      ||
  237.                            (defined(Z) || defined(__Z__))
  238.                         #include <STD_FEATURE.h>
  239.                         #endif
  240.  
  241.                 [W, Y, Z are things like SVR4, AIX, NeXT, BSD,
  242.                 and so on. STD_FEATURE.h is something like shadow.h] 
  243.  
  244.                 This example exposes two problems the large
  245.                 grained method. First, it forces one to keep
  246.                 track of exactly which vendors supply
  247.                 <STD_FEATURE.h>.  Second, the complexity of the
  248.                 preprocessor expressions may be a serious
  249.                 consideration, since their complexity is
  250.                 something like     
  251.  
  252.                         O(n*m) where
  253.  
  254.                         n = the number of standard features, and
  255.                         m = number of vendors/systems
  256.  
  257.  
  258.         (ii).   Define new fine-grained feature tests (e.g.,
  259.                 HAVE_POSIX_SIGNALS, or HAVE_SHADOW_H) for
  260.                 features of interest. Such fine-grained features
  261.                 could be used in conjunction with large grained
  262.                 definitions. An nice example of using feature
  263.                 definitions is the GNU configure program. It
  264.                 uses, for example, the features HAVE_BCOPY and
  265.                 HAVE_MEMSET to enable either the bcopy (BSD) or
  266.                 memset (ANSI) functions.   
  267.  
  268.                 Feature testing has the advantage of being useful
  269.                 for automatic configuration with programs such as
  270.                 GNU configure. GNU configure outputs statements
  271.                 of the form
  272.                 
  273.  
  274.                         #define HAVE_aaaa
  275.                         #define HAVE_bbbb
  276.                         #define HAVE_cccc
  277.                         ....
  278.  
  279.                 Another way to generate a feature set is by
  280.                 using the symbol defining the system, e.g., 
  281.  
  282.                         #ifdef SVR4
  283.                         #define HAVE_aaaa
  284.                         #define HAVE_bbbb
  285.                         #define HAVE_cccc
  286.                         ....
  287.  
  288.                         #endif
  289.                         #ifdef BSD43
  290.                         #define HAVE_yyyy
  291.                         ...
  292.                         #endif
  293.                         #ifdef NEWTHING
  294.                         #define HAVE_zzzz
  295.                         ...
  296.                         #endif
  297.         
  298.                 Feature testing also helps to avoid constructs
  299.                 such as 
  300.  
  301.                 #if defined(_POSIX_SOURCE) || defined(_XOPEN_SOURCE)
  302.  
  303.                 [Editor's Note: Finally, an observation: The real
  304.                 issue here appears to be how many of these
  305.                 "features" are migrating to the standard
  306.                 operating systems and interfaces, and how many
  307.                 vendors are implementing these standards. In
  308.                 general, some people feel that feature testing
  309.                 improves portability (and readability), and
  310.                 others believe that the feature testing style 
  311.                 decreases portability and readability. DM]  
  312.  
  313.  
  314.         (iii).  Use some part of the feature's definition itself
  315.                 to enable the feature, for example 
  316.  
  317.                         #ifdef _IOLBF
  318.                                 setvbuf(stderr, NULL, _IOLBF, 0);
  319.                         #else
  320.                                 setlinebuf(stderr);
  321.                         #endif  /* _IOLBF  */
  322.  
  323.                 Note that in this case, another, possibly better
  324.                 option is (consider the case in which some vendor
  325.                 has inadvertently defined _IOLBF for some other
  326.                 purpose):
  327.  
  328.                         #ifdef   __STDC__
  329.                                 setvbuf(stderr, NULL, _IOLBF, 0);
  330.                         #else
  331.                                 setlinebuf(stderr);
  332.                         #endif  /* __STDC__  */
  333.  
  334.                 since setvbuf is required by Standard C.
  335.  
  336.  
  337.  
  338.         Finally, some people have suggested the use of
  339.         expressions like 
  340.  
  341.                 #if defined(sun) && defined(__svr4__)
  342.                         <Solaris 2 centric code>
  343.                 #else 
  344.                         ...
  345.                 #endif
  346.  
  347.  
  348.         As noted above, the __svr4__ feature is defined by the
  349.         FSF (gcc). If you depend on __svr4__, you may lose 
  350.         portability. gcc also defines sun if you don't give the
  351.         -ansi argument. If you use -ansi,  then sun is not
  352.         defined and __sun__ is. The implication here is that
  353.         depending on symbols defined by a given compiler can
  354.         reduce portability.
  355.  
  356.         In general, such a construct should be used if and only if
  357.         the code in question cannot be covered by some standard
  358.         (e.g., SVR4, _POSIX_SOURCE, etc.). Note that it is also
  359.         compiler specific.
  360.         
  361.  
  362. -----------------------------------------------------------------------------
  363. 1) TOPIC: Include File Issues
  364.  
  365. [Last modified: 19 August 93]
  366.  
  367. The first and apparently most common problem is that
  368. /usr/include/strings.h is not ANSI compliant, and as such does not
  369. exist on Solaris 2 (or SVR4). It should be replaced by
  370. /usr/include/string.h, e.g. (following GNU feature definition
  371. conventions)
  372.  
  373.         #if HAVE_STRING_H || defined(STDC_HEADERS)
  374.         #include <string.h>
  375.         #else
  376.         #include <strings.h>
  377.         #endif
  378.         #if defined(STDC_HEADERS)
  379.         #include <stdlib.h>
  380.         #endif /* HAVE_STRING_H */
  381.  
  382.         while ANSI-C requires the name be string.h, one might
  383.         define this as
  384.  
  385.         #ifdef __STDC__
  386.         #include <string.h>
  387.         #else
  388.         #include <strings.h>
  389.         #endif  /* __STDC__ */
  390.  
  391.         However, this again neglects the case in which the vendor 
  392.         provides string.h in a non-ANSI environment.
  393.  
  394.                         
  395. Another thing to watch is for the symbols O_CREAT, O_TRUNC, and
  396. O_EXCL being undefined. On BSD systems, these are defined in
  397. <sys/file.h>. On Solaris 1 systems (beginning with SunOS 4.0) ,
  398. these are defined in <sys/fnctlcom.h> (which is included in
  399. <sys/file.h>). On a POSIX compliant system, these symbols are
  400. defined in <fcntl.h>, which is not included in <sys/file.h>.
  401. Since <fcntl.h> is defined on SunOS 4.1.x, replacing <sys/file.h>
  402. with <fcntl.h> works for both SunOS 4.1.x and SVR4. See, for
  403. example, section 5.3.1.1 of the POSIX spec.
  404.  
  405.  
  406. -----------------------------------------------------------------------------
  407.  
  408. 2) TOPIC: Libraries
  409.  
  410. [Last modified: 19 August 93]
  411.  
  412. Network Libraries:
  413.  
  414. Many of the network functions and definitions that were present
  415. in the BSD libc are now in libnsl.a and libsocket.a. Thus
  416. networking code will generally need to be linked with -lsocket
  417. -lnsl (since libsocket.a uses stuff from libnsl.a, you must specify
  418. them in this order). Note that you need libnsl.a for functions like
  419. gethostbyname (see gethostbyname note below). 
  420.  
  421.  
  422. Regular Expressions
  423.  
  424. Another problem frequently encountered is that the regexp
  425. functions (see regexpr(3G)) are not defined in libc. On Solaris
  426. 2, you must link with libgen.a (-lgen) in order to get these
  427. definitions. See Intro(3) for a more complete discussion.
  428.  
  429. Name List (nlist)
  430.  
  431. You must link with libelf.a (-lelf) to get the nlist(3E)
  432. definition. 
  433.  
  434. -----------------------------------------------------------------------------
  435.  
  436. 3)* TOPIC: Possible ANSI/POSIX/SVR4 replacements for some popular
  437.           BSD functions  
  438.  
  439. [Last modified: 03 November 93]
  440.  
  441. [Editor's Note: Once again, this section began life a SunOS 4.1.x 
  442. and SunOS 5.x centric discussion.  It too has grown into a
  443. discussion dealing with general portability for BSD to other
  444. standards. DM]
  445.  
  446. Problems finding functions that were defined in the BSD libc.a is
  447. one of the most frequently asked porting questions. The following
  448. table and code fragments suggest substitutes for some common BSD
  449. constructs (more complete lists can be found in some of the texts
  450. listed in section 7 below).
  451.  
  452.  
  453. BSD                     Possibilities           Standards/Notes
  454. ============================================================================
  455. srandom(seed)           srand(seed)             ANSI-C (Also, some older UNIX)
  456.                         srand48(seed)           SVR4
  457.  
  458. non-ANSI signal()       sigset()                SVR4   (systems calls not
  459. (e.g., SunOS)                                          restarted, but bytes r/w
  460.                                                        returned, else EINTR) 
  461.                         sigaction               POSIX  (but extensible by
  462.                                                        implementation) 
  463.  
  464. sigvec                  sigaction               POSIX
  465. sigblock                sigprocmask             POSIX
  466.                         sigset(.., SIG_HOLD)
  467.                         sighold                 SVR4
  468. sigsetmask              sigprocmask             POSIX
  469.                         sigset/sigrelse         SVR4    
  470.  
  471. sigpause                sigsuspend              POSIX
  472.         
  473. setjmp                  sigsetjmp               POSIX 
  474. longjmp                 siglongjmp              POSIX 
  475.  
  476. bcopy                   memmove                 ANSI-C (BSD bcopy() handles
  477.                                                        overlapping areas
  478.                                                        correctly, as does
  479.                                                        memmove, but not memcpy)
  480.  
  481. bzero                   memset                  ANSI-C
  482.  
  483. index                   strchr                  ANSI-C
  484. rindex                  strrchr                 ANSI-C
  485.  
  486. getwd                   getcwd                  POSIX
  487.  
  488. getrusage               open,ioctl              The getrusage information
  489.                                                 (and a whole lot more) can be
  490.                                                 found in the prusage structure.
  491.                                                 Use the PIOCUSAGE ioctl. See
  492.                                                 the example below and the
  493.                                                 proc(4) man page for detail. 
  494.  
  495.  
  496. gethostname             sysinfo(SI_HOSTNAME,..) SVR4   See sysinfo(2) for
  497.                                                        many other possible
  498.                                                        values
  499.  
  500. getdtablesize           sysconf(_SC_OPEN_MAX)   POSIX  See sysconf(3C) for
  501.                                                        many other values
  502.                                                        available via sysconf.
  503.  
  504.  
  505. wait3 w/o rusage        waitpid                 POSIX
  506. wait3                   waitid                  SVR4
  507.  
  508. usleep                   nanosleep              POSIX See nanosleep(3R) on
  509.                                                 Solaris 2.3 (see libposix4.a) 
  510.                                                 For a Solaris 2.2, see the
  511.                                                 example below.
  512.  
  513. Some other commonly used functions are setlinebuf, gethostid,
  514. gethostname, getdtablesize, and getrusage. The following
  515. fragments give some idea of how to emulate this functionality.  
  516.  
  517.         /*
  518.          *      getrusage --
  519.          */
  520.  
  521.         #include <sys/resource.h>
  522.         #ifndef RUSAGE_SELF
  523.         #include <sys/procfs.h>
  524.         #endif
  525.  
  526.         #ifdef PIOCUSAGE
  527.                 int             fd;
  528.                 char            proc[SOMETHING];
  529.                 prusage_t       prusage;
  530.  
  531.                 sprintf(proc,"/proc/%d", getpid());
  532.                 if ((fd = open(proc,O_RDONLY)) == -1) {
  533.                         perror("open");
  534.                         ....
  535.                 }
  536.                 if (ioctl(fd, PIOCUSAGE,, &prusage) == -1) {
  537.                         perror("ioctl");
  538.                         ...
  539.                 }
  540.                 ....
  541.         #else                   /* Again, assume BSD */
  542.                 if (getrusage(RUSAGE_SELF, &rusage) == -1) {
  543.                         perror("getrusage");
  544.                         ....
  545.                 }
  546.                 ....
  547.         #endif /* PIOCUSAGE */
  548.  
  549.  
  550.  
  551.         /*
  552.          *      setlinebuf --
  553.          *
  554.          */
  555.         
  556.         #ifdef   __STDC__
  557.                 setvbuf(stderr, NULL, _IOLBF, 0);
  558.         #else
  559.                 setlinebuf(stderr);
  560.         #endif  /* __STDC__  */
  561.  
  562.  
  563.         /*
  564.          *      gethostid 
  565.          *
  566.          *      This example has a combination of high-level
  567.          *      (SVR4) and (SI_HW_SERIAL) feature declarations.
  568.          */
  569.         
  570.         #if defined(SVR4) && defined(SI_HW_SERIAL)
  571.         long  gethostid() {
  572.                         
  573.           char buf[128];
  574.                 
  575.           if (sysinfo(SI_HW_SERIAL, buf, 128) == -1) {
  576.             perror("sysinfo");
  577.             exit(1);
  578.           }
  579.           return(strtoul(buf,NULL,0));
  580.         }
  581.         #endif /* SVR4 && SI_HW_SERIAL */
  582.  
  583.  
  584.         /*
  585.          *      getdtablesize --
  586.          *
  587.          *      Several possibilites here. Note that while one
  588.          *      can emulate getdtablesize with getrlimit on SVR4
  589.          *      or 4.3BSD (or later), these systems should be
  590.          *      POSIX.1 compliant, so sysconf is preferred.
  591.          *
  592.          */
  593.  
  594.         #ifdef  _SC_OPEN_MAX            /* POSIX -- preferred */
  595.                 if ((tableSize = sysconf(_SC_OPEN_MAX)) == -1) {
  596.                         perror("sysconf");
  597.                         ...
  598.                 }
  599.         #elif   RLIMIT_NOFILE           /* who is non POSIX but has this? */
  600.                 if (getrlimit(RLIMIT_NOFILE, &rlimit) == -1) {
  601.                         perror("getrlimit");
  602.                         exit(1);
  603.                 }
  604.                 tableSize = rlimit.rlim_max;
  605.         #else                           /* assume old BSD type */
  606.                 tableSize = getdtablesize();
  607.         #endif
  608.  
  609.  
  610. ------------------   
  611.  
  612.         /*
  613.          * gethostname  --
  614.          *
  615.          */
  616.  
  617.         #ifdef  SVR4 
  618.         #include <sys/systeminfo.h>
  619.         #endif  /* SVR4 */ 
  620.  
  621.                 ....
  622.  
  623.                 char buf[MAXHOSTNAME]
  624.  
  625.         #ifdef  SVR4
  626.                 if (sysinfo(SI_HOSTNAME, buf, sizeof(buf)) <0) {
  627.                         perror("SI_HOSTNAME");
  628.                         exit(BAD);
  629.                 }
  630.         #else   /* Assume BSD */
  631.                 if (gethostname(buf, sizeof(buf)) < 0) {
  632.                         perror("gethostname");
  633.                         exit(BAD);
  634.                 }
  635.         #endif  /* SVR4 */
  636.  
  637.         /* buf has hostname here... */
  638.  
  639.  
  640.         /*
  641.          *      usleep --
  642.          *
  643.          *      Possible usleep replacement. Another possiblity
  644.          *      is to use poll(2) (poll(&unused,0,timeout))
  645.          */
  646.  
  647.         void usleep(usec)
  648.                 unsigned usec;
  649.         {
  650.  
  651.                 struct timeval tval;
  652.                 
  653.                 tval.tv_sec  = usec/1000000;
  654.                 tval.tv_usec = usec%1000000;
  655.                 select(0,NULL,NULL,NULL,&tval);
  656.         }
  657.  
  658.  
  659.  
  660.         /*
  661.          *      gethostybname --
  662.          *
  663.          *      The following code was contributed by Casper H.S. Dik
  664.          *      to address the following problem:
  665.          *
  666.          *      gethostbyname() always returns null in h->aliases.
  667.          *      Now, gethostbyX can be replaced its __switch_gethostbyX
  668.          *      equivalents. However, these are missing from Solaris 2.3.
  669.          *
  670.          *      The _r functions are reentrant.  They have a different
  671.          *      calling sequence. (The __switch_getXXXbyYYY are called
  672.          *      like getXXXbyYYY, the _switch_getXXXbyYYY_r are called
  673.          *      like getXXXbyYYY_r) 
  674.          *
  675.          *      With this bit of knowledge I constructed the code that
  676.          *      follows this message. Just plug it in every program
  677.          *      that requires gethostbyname to work. (Gethostbyaddr()
  678.          *      is added for symmetry). 
  679.          *
  680.          *      You'll need to link with -lnsl -ldl.
  681.          *
  682.          *      It works for Solaris 2.2 and 2.3.  (Compiled on 2.3 or
  683.          *      2.2 it will run 2.2 and 2.3)
  684.          *
  685.          *      Note that as with __switch* _switch*_r is undocumented
  686.          *      and can be changed in the next release.
  687.          *
  688.          */
  689.  
  690.          /*
  691.           *     Proper gethostbyXX function for Solaris 2.0-2.3
  692.           *     (and later ?) 
  693.           *
  694.           *     Fixed in 2.4?
  695.           *
  696.           *     You'll need -ldl added to the link command line.
  697.           *
  698.           *     Casper Dik (casper@fwi.uva.nl)
  699.           *
  700.           */
  701.  
  702.            #include <netdb.h>
  703.            #include <dlfcn.h>
  704.         
  705.            #define HBUFSIZE 4096
  706.         
  707.            static void *dlhandle;
  708.            /* The gethostbyXXX function variables. Named after
  709.             * then .so files they appear in. nsw*.so in SunOS 5.2
  710.             * and earlier, nss_*.so in 5.3 */ 
  711.            static struct hostent
  712.                *(*nswghba)(const char *, int, int),
  713.                *(*nswghbn)(const char *),
  714.                *(*nss_ghba)(const char *, int, int,
  715.                             struct hostent *, char *, int, int *),
  716.                *(*nss_ghbn)(const char *,
  717.                             struct hostent *, char *, int, int *);
  718.         
  719.            static int dlinit(void)
  720.            {
  721.                static int dlstatus = 0; /* 0 = uninited, 1 = inited & ok, -1 = error */
  722.         
  723.                if (dlstatus)
  724.                    return dlstatus;
  725.         
  726.                dlstatus = -1;
  727.         
  728.                dlhandle = dlopen(0, RTLD_LAZY);
  729.         
  730.                if (dlhandle == 0)
  731.                    return dlstatus;
  732.         
  733.                /* SunOS 5.0 - 5.2 */
  734.                nswghba = (struct hostent *(*)(const char *, int, int))
  735.                            dlsym(dlhandle, "__switch_gethostbyaddr");
  736.         
  737.                nswghbn = (struct hostent *(*)(const char *))
  738.                            dlsym(dlhandle, "__switch_gethostbyname");
  739.         
  740.                /* either both should exist or both should not exist */
  741.                if ((nswghbn == 0) != (nswghba == 0))
  742.                    return dlstatus;
  743.         
  744.                if (nswghbn)
  745.                    return dlstatus = 1;
  746.         
  747.                /* SunOS 5.3 - ? */
  748.                nss_ghba = (struct hostent *(*)
  749.                (const char *, int, int, struct hostent *, char *, int , int *))
  750.                            dlsym(dlhandle, "_switch_gethostbyaddr_r");
  751.         
  752.                nss_ghbn = (struct hostent *(*)
  753.                (const char *, struct hostent *, char *, int , int *))
  754.                            dlsym(dlhandle, "_switch_gethostbyname_r");
  755.         
  756.                /* these two must exist when we get here */
  757.                if (nss_ghbn != 0 && nss_ghba != 0)
  758.                    dlstatus = 1;
  759.         
  760.                return dlstatus;
  761.            }
  762.         
  763.            struct hostent *
  764.            gethostbyname(const char *name) {
  765.         
  766.                    static struct hostent hp;
  767.                    static char buf[HBUFSIZE];
  768.         
  769.                    if (dlinit() == -1)
  770.                        return 0;
  771.         
  772.                    if (nswghbn)
  773.                        return nswghbn(name);
  774.                    else
  775.                        return nss_ghbn(name, &hp, buf, sizeof(buf), &h_errno);
  776.            }
  777.         
  778.            struct hostent *
  779.            gethostbyaddr(const char *addr, int len, int type) {
  780.                    static struct hostent hp;
  781.                    static char buf[HBUFSIZE];
  782.         
  783.                    if (dlinit() == -1)
  784.                        return 0;
  785.         
  786.                    if (nswghba)
  787.                        return nswghba(addr, len, type);
  788.                    else
  789.                        return nss_ghba(addr,
  790.                        len, type, &hp, buf, sizeof(buf), &h_errno);
  791.            }
  792.  
  793. -----------------------------------------------------------
  794.  
  795. 4) TOPIC: BSD/Solaris 1/POSIX Signal Primer
  796.  
  797. [Last modified: 20 September 93]
  798.  
  799.  
  800. The most common problem encountered when porting BSD/Solaris 1
  801. signal code is that Solaris 2 (and SVR4) handles interrupted
  802. systems calls differently than does BSD. In Solaris 2 (SVR4),
  803. system calls are interrupted and return EINTR, unless the call is
  804. read, write, or some other call that returns the number of bytes
  805. read/written (unless 0 bytes have been read/written, in which
  806. case the call returns EINTR). 
  807.  
  808. On the other hand, system calls are restarted on BSD/Solaris 1
  809. systems. The signal calls can be made to restart by specifying a
  810. SA_RESTART with sigaction().  Note, however, that code that
  811. relies on restartable system calls is generally considered bad
  812. practice. The following code is provided for illustrative
  813. purposes only. It is recommended that you remove these
  814. dependencies. Sigaction is the preferred (POSIX) way of
  815. installing signal handlers.  
  816.  
  817.  
  818.         The BSD/Solaris 1 code 
  819.  
  820.                 omask = sigblock(sigmask(SIGXXX));
  821.                 do_stuff_while_SIGXXX_blocked();
  822.                 (void)sigsetmask(omask);
  823.         
  824.         can be emulated by
  825.  
  826.                 sigset_t block, oblock;
  827.         struct   sigaction act, oact;
  828.                 ....
  829.                 (void)sigemptyset(&block);
  830.                 (void)sigaddset(&block, SIGXXX);
  831.                 if (sigprocmask(SIG_BLOCK, &block, &oblock) < 0)
  832.                         perror("sigprocmask");
  833.                 do_stuff_while_SIGXXX_blocked();
  834.                 (void)sigprocmask(SIG_SETMASK, &oblock, (sigset_t *)NULL);
  835.         #ifdef  SA_RESTART                      /* make restartable */
  836.                 act.sa_flags |= SA_RESTART;
  837.         #endif  /* SA_RESTART */
  838.                 if (sigaction(SIGXXX, &act, &oact) < 0)
  839.                        return(SIG_ERR);
  840.  
  841.  
  842.         Note that this (emulating) construct is also available on
  843.         Solaris 1 (sans SA_RESTART), so should work on either
  844.         Solaris 1 or SVR4.
  845.  
  846. Another problem revolves around the use of setjmp and longjmp.
  847. With 4.3+BSD  the setjmp and longjmp save and restore the signal
  848. mask. The default behavior for SVR4 is not to save and restore
  849. the signal mask. Note that these calls are MT-Unsafe.
  850.  
  851. The POSIX.1 interface allows you to do either, by using a second
  852. argument, savemask, for sigsetjmp. To cause the signal mask to be
  853. saved and restored (emulating setjmp/longjmp behavior), use a
  854. nonzero savemask.  For example,
  855.  
  856.  
  857.                 #include        <stdio.h>
  858.                 #include        <stdlib.h>
  859.                 #include        <setjmp.h>
  860.                 
  861.                 sigjmp_buf      env;
  862.                 int             savemask;
  863.                 
  864.                 ....
  865.                 
  866.                 savemask = 1;
  867.                 #ifdef  HAS_SIGSETJMP
  868.                         sigsetjmp(env, savemask);
  869.                 #endif  HAS_SIGSETJMP
  870.  
  871.                 ...
  872.  
  873. In this case, the sigsetjmp saves the current signal mask of the
  874. process in the saved environment (sigjmp_buf). Now, if the
  875. environment was saved by a call to sigsetjmp with a nonzero
  876. savemask, then a subsequent siglongjmp call will restore the
  877. saved signal mask.    
  878.  
  879.  
  880. To summarize,  some basic rules are:
  881.  
  882.         (i).    Limit signal handling code to the POSIX interface
  883.                 whenever possible. 
  884.  
  885.         (ii).   Use sigaction to install signal handlers whenever
  886.                 possible. Use Standard C's signal() only for
  887.                 portability to non-POSIX systems. 
  888.  
  889.         (iii).  Avoid code that relies on restartable system calls. 
  890.  
  891.         (iv).   The main difference between SVR4 sigset() (not
  892.                 POSIX) and SunOS 4.x/BSD signal() is that system
  893.                 calls will return EINTR with sigset() but will be
  894.                 restarted on BSD/SunOS 4.x. On SVR4 EINTR is only
  895.                 returned when no bytes have been read/written.     
  896.  
  897.  
  898. -----------------------------------------------------------------------------
  899.  
  900. 5) TOPIC: Waiting for Children to Exit
  901.  
  902. [Last modified: 26 October 93]
  903.  
  904.  
  905. waitpid(2) is the preferred (POSIX) interface. Wait3 can be
  906. replaced by waitpid (when you don't need the rusage). For
  907. example, the BSD segment  
  908.         
  909.         while((id = wait(&stat)) >=0 && id != pid);
  910.  
  911. can be approximated using the POSIX waidpid(2) interface by code
  912. of the form: 
  913.  
  914.         int status;
  915.         int options;                    /* e.g., WNOHANG */
  916.         ....
  917.         options |= WNOHANG;
  918.         if (waitpid((pid_t) -1, &status, options) == -1)
  919.                 perror("waitpid");
  920.         }
  921.  
  922.  
  923. Note here that if you execute a signal(SIGCHLD, SIG_IGN) or
  924. sigset(SIGCHLD, SIG_IGN), Solaris will discard all child exit
  925. statuses and reap the child processes without giving the parent a
  926. chance to wait. That is, waitpid(2) will return -1 with an ECHILD. 
  927.  
  928.  
  929. Another possibility is emulate the BSD wait(2) call with SVR4's
  930. waitid(2). The code fragment below is an example. In this case,
  931. we wait for a particular child in our process group ((pid_t) 0)
  932. to exit (WEXITED).
  933.  
  934.  
  935.         #ifdef  SVR4
  936.         #include <sys/types.h>
  937.         #include <sys/wait.h>
  938.                 siginfo_t       stat;
  939.                 int             retcode;
  940.         #else
  941.                 union   wait    stat;
  942.         #endif
  943.  
  944.         .....
  945.  
  946.         #ifdef  SVR4
  947.               while (retcode = waitid(P_ALL,(pid_t) 0, &stat, WEXITED)) {
  948.                 if (retcode < 0) {
  949.                   perror("waitid");
  950.                   exit(1);
  951.                 }
  952.                 if (stat.si_pid == pid)
  953.                   break;
  954.               }
  955.         #else           /* BSD */
  956.                while((id = wait(&stat)) >=0 && id != pid);
  957.         #endif  /* SVR4 */
  958.  
  959.  
  960.  
  961. -----------------------------------------------------------------------------
  962.  
  963. 6) TOPIC: Dealing With Shadow Password Files
  964.  
  965. [Last modified: 19 August 93]
  966.  
  967. The following code segment outlines how to handle shadow password
  968. files. In the outline below, <passwd> is the clear text password.
  969. Note that shadow passwords are part of SVR4, so again we have the
  970. conflict between using high level system definitions (e.g., SVR4)
  971. and feature definitions (for systems other than SVR4). I'll use
  972. feature a feature definition (HAVE_SHADOW_H) to illustrate this.
  973.  
  974.  
  975.         #ifdef  HAVE_SHADOW_H
  976.         #include <shadow.h>
  977.             register struct spwd    *sp;
  978.         #endif  /* HAVE_SHADOW_H */
  979.  
  980.              .....
  981.                 
  982.         #ifdef  HAVE_SHADOW_H
  983.             if ((sp = getspnam(<username>)) == NULL)
  984.                <no password entry for username>
  985.             if (sp->sp_pwdp == NULL)
  986.                <NULL password for username>
  987.             if (strcmp (crypt (<passwd>, sp->sp_pwdp), sp->sp_pwdp) != 0)
  988.         #else 
  989.             if ((pw = getpwnam(<username>)) == NULL)
  990.                <no password entry for username>
  991.             if (pw->pw_passwd == NULL)
  992.                <NULL password for username>
  993.             if (strcmp (crypt (<passwd>, pw->pw_passwd), pw->pw_passwd) != 0)
  994.         #endif  /* HAVE_SHADOW_H */
  995.                <incorrect password for username>
  996.                        
  997.  
  998. -----------------------------------------------------------------------------
  999.  
  1000. 7)* TOPIC: Some Compatabilty Problems
  1001.  
  1002. [Last modified: 02 September 93]
  1003.  
  1004.         (i).     vfork doesn't work in Solaris 2
  1005.  
  1006.                 [Editor's Note: The following observation and
  1007.                 example comes courtesy of Paul Eggert
  1008.                 (eggert@twinsun.com). DM] 
  1009.  
  1010.                 In Solaris 2, if a vfork'ed child adjusts signal
  1011.                 handling before exec'ing, signal handling is munged in
  1012.                 the parent in ways that lead to unreliable results;
  1013.                 the parent can dump core in some cases.  This bug
  1014.                 affects some widely distributed programs, so when
  1015.                 building a program that adjusts signal handlers
  1016.                 between `vfork' and `exec', be careful to override its
  1017.                 configuration to use `fork' instead. 
  1018.  
  1019.                 Sun doesn't consider this behavior to be a bug,
  1020.                 so it's not likely to be fixed. 
  1021.  
  1022.                 Here's an illustration of the bug.  This program
  1023.                 works fine in SunOS 4.1.x, but dumps core in
  1024.                 Solaris 2.x. 
  1025.  
  1026.                         #include <signal.h>
  1027.                         #include <unistd.h>
  1028.  
  1029.                         #ifdef SIGLOST          /* must be SunOS 4.1.x */
  1030.                         #include <vfork.h>
  1031.                         #endif
  1032.  
  1033.                         int signalled;
  1034.  
  1035.                         void catch (sig)
  1036.                              int sig;
  1037.                         {
  1038.                              signalled = 1;
  1039.                         }
  1040.  
  1041.                         int main()
  1042.                         {
  1043.                              signal (SIGINT, catch);
  1044.                              if (vfork () == 0) {               /* child */
  1045.                                  signal (SIGINT, SIG_IGN);
  1046.                                  execlp ("sleep", "sleep", "10", (char *) 0);
  1047.                              }
  1048.         
  1049.                             /* parent here */
  1050.  
  1051.                              kill (getpid (), SIGINT);
  1052.                              return signalled != 1;
  1053.                         }
  1054.  
  1055.  
  1056.         (ii).   chown(2) does not allow uid/gid values greater
  1057.                 than 60002 on Solaris 2.2. Check /usr/include/limits.h,
  1058.                 which contains:
  1059.  
  1060.                 #define UID_MAX         60002   
  1061.  
  1062.  
  1063. -----------------------------------------------------------------------------
  1064.  
  1065. 8)* TOPIC: Other Resources
  1066.  
  1067. [Last modified: 27 September 93]
  1068.  
  1069. Porting to Solaris 2
  1070. --------------------
  1071.  
  1072. A excellent text on this subject is  "Solaris Porting Guide",
  1073. SunSoft ISV Engineering, et. al., Prentice Hall, 1993. ISBN
  1074. 0-13-030396-8. 
  1075.  
  1076. Solaris 2 General FAQ
  1077. ---------------------
  1078.  
  1079. The official Solaris 2 Frequently Answered Questions is
  1080. maintained by Ian Darwin, ian@sq.com, and is posted once or twice 
  1081. a month to various newsgroups including comp.unix.solaris and
  1082. comp.answers.
  1083.  
  1084. General
  1085. -------
  1086.  
  1087. "Internetworking with TCP/IP: Volume III Client-Server Programming
  1088. & Applications (AT&T TLI Edition)", Douglas E. Comer & David L.
  1089. Stevens, Prentice-Hall. ISBN 0-13-474230-3. Nice reference for
  1090. TLI programming, etc.
  1091.  
  1092. "Networking Applications on UNIX System V", Mike Padovano, ISBN
  1093. 013-613555. A good reference for System V.
  1094.  
  1095. "UNIX, POSIX, and Open Systems: The Open Standards Puzzle", John
  1096. S. Quarterman and Susanne Wilhelm, Addison-Wesley, 1993. ISBN
  1097. 0-201-52772-3. Another nice modern reference.
  1098.  
  1099. "UNIX System V Network Programming", Steve Rago, ISBN
  1100. 0-201-56318-5. Another good System V reference.
  1101.  
  1102. "Advanced Programming in the UNIX Environment", W. Richard
  1103. Stevens, Addison Wesley, 1992, ISBN 0-201-56317-1, is a nice, in
  1104. depth text covering large parts of this topic.
  1105.  
  1106. ANSI C
  1107. ------
  1108.  
  1109. A very nice text here is "The Standard C Library", P.J. Plauger,
  1110. Prentice Hall, 1992, ISBN 0-13-131509-9.
  1111.  
  1112. Another example of the many texts here is "C,  a Reference
  1113. Manual", Harbison and Steele, Prentice Hall. ISBN 0-13-110933-2.  
  1114.  
  1115. POSIX
  1116. -----
  1117.  
  1118. A nice reference text on the POSIX interface is "POSIX
  1119. Programmer's Guide", Donald Levine, O'Reily & Associates, 1991.
  1120. ISBN 0-937175-73-0. 
  1121.  
  1122.  
  1123. ACKNOWLEDGMENTS
  1124.  
  1125. I would like to thank everyone who contributed to this, and I
  1126. hope that it clarifies some of these issues. I would especially 
  1127. acknowledge the contributions of Casper H.S. Dik and J.G. Vons in
  1128. helping me organize my thoughts on all this.
  1129.  
  1130. Thanks to:
  1131.  
  1132.         Pedro Acebes Bayon      <pacebes@tid.es>
  1133.         Ian Darwin              <ian@sq.com>
  1134.         Casper H.S. Dik         <casper@fwi.uva.nl>
  1135.         Paul Eggert             <eggert@twinsun.com>
  1136.         Stephen L Favor         <xcpslf@atom.oryx.com>
  1137.         Pete Hartman            <pwh@bradley.bradley.edu>
  1138.         Guy Harris              <guy@auspex.com>
  1139.         Jens-Uwe Mager          <jum@anubis.han.de>
  1140.         Richard M. Mathews      richard@astro.West.Sun.COM 
  1141.         Davin Milun             <milun@cs.buffalo.edu>
  1142.         Paul Pomes              <Paul-Pomes@uiuc.edu>
  1143.         Andrew Roach            <andrewr@ultrix.sun.com>
  1144.         M C Srivas              <M._C._Srivas@transarc.com>
  1145.         Larry W. Virden         <lwv26@cas.org>
  1146.         J.G. Vons               <vons%ulysse@crbca1.sinet.slb.com>
  1147.         Peter Wemm              <peter@DIALix.oz.au>
  1148.         christos@deshaw.com
  1149.         jorgens@pvv.unit.no
  1150.         malte@techfak.uni-bielefeld.de
  1151.  
  1152. ----- End of Solaris 2 Porting FAQ -- Maintained by David Meyer meyer@ns.uoregon.edu --
  1153.  
  1154.  
  1155.  
  1156.         David M. Meyer 503/346-1747
  1157.         meyer@cambium.uoregon.edu
  1158.         Fri Jul 16 14:59:28 1993
  1159.  
  1160.         $Header: /net/network-services/disk1/home/meyer/FAQ/RCS/porting-FAQ,v 1.43 1993/11/24 23:39:54 meyer Exp $
  1161.  
  1162.  
  1163.