tclUnixSock.c

Go to the documentation of this file.
00001 /*
00002  * tclUnixSock.c --
00003  *
00004  *      This file contains Unix-specific socket related code.
00005  *
00006  * Copyright (c) 1995 Sun Microsystems, Inc.
00007  *
00008  * See the file "license.terms" for information on usage and redistribution of
00009  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
00010  *
00011  * RCS: @(#) $Id: tclUnixSock.c,v 1.20 2007/12/13 15:28:42 dgp Exp $
00012  */
00013 
00014 #include "tclInt.h"
00015 
00016 /*
00017  * The following variable holds the network name of this host.
00018  */
00019 
00020 static TclInitProcessGlobalValueProc InitializeHostName;
00021 static ProcessGlobalValue hostName =
00022         {0, 0, NULL, NULL, InitializeHostName, NULL, NULL};
00023 
00024 
00025 /*
00026  *----------------------------------------------------------------------
00027  *
00028  * InitializeHostName --
00029  *
00030  *      This routine sets the process global value of the name of the local
00031  *      host on which the process is running.
00032  *
00033  * Results:
00034  *      None.
00035  *
00036  *----------------------------------------------------------------------
00037  */
00038 
00039 static void
00040 InitializeHostName(
00041     char **valuePtr,
00042     int *lengthPtr,
00043     Tcl_Encoding *encodingPtr)
00044 {
00045     CONST char *native = NULL;
00046 
00047 #ifndef NO_UNAME
00048     struct utsname u;
00049     struct hostent *hp;
00050 
00051     memset(&u, (int) 0, sizeof(struct utsname));
00052     if (uname(&u) > -1) {                               /* INTL: Native. */
00053         hp = TclpGetHostByName(u.nodename);             /* INTL: Native. */
00054         if (hp == NULL) {
00055             /*
00056              * Sometimes the nodename is fully qualified, but gets truncated
00057              * as it exceeds SYS_NMLN. See if we can just get the immediate
00058              * nodename and get a proper answer that way.
00059              */
00060 
00061             char *dot = strchr(u.nodename, '.');
00062 
00063             if (dot != NULL) {
00064                 char *node = ckalloc((unsigned) (dot - u.nodename + 1));
00065 
00066                 memcpy(node, u.nodename, (size_t) (dot - u.nodename));
00067                 node[dot - u.nodename] = '\0';
00068                 hp = TclpGetHostByName(node);
00069                 ckfree(node);
00070             }
00071         }
00072         if (hp != NULL) {
00073             native = hp->h_name;
00074         } else {
00075             native = u.nodename;
00076         }
00077     }
00078     if (native == NULL) {
00079         native = tclEmptyStringRep;
00080     }
00081 #else
00082     /*
00083      * Uname doesn't exist; try gethostname instead.
00084      *
00085      * There is no portable macro for the maximum length of host names
00086      * returned by gethostbyname(). We should only trust SYS_NMLN if it is at
00087      * least 255 + 1 bytes to comply with DNS host name limits.
00088      *
00089      * Note: SYS_NMLN is a restriction on "uname" not on gethostbyname!
00090      *
00091      * For example HP-UX 10.20 has SYS_NMLN == 9, while gethostbyname() can
00092      * return a fully qualified name from DNS of up to 255 bytes.
00093      *
00094      * Fix suggested by Viktor Dukhovni (viktor@esm.com)
00095      */
00096 
00097 #    if defined(SYS_NMLN) && SYS_NMLEN >= 256
00098     char buffer[SYS_NMLEN];
00099 #    else
00100     char buffer[256];
00101 #    endif
00102 
00103     if (gethostname(buffer, sizeof(buffer)) > -1) {     /* INTL: Native. */
00104         native = buffer;
00105     }
00106 #endif
00107 
00108     *encodingPtr = Tcl_GetEncoding(NULL, NULL);
00109     *lengthPtr = strlen(native);
00110     *valuePtr = ckalloc((unsigned int) (*lengthPtr)+1);
00111     memcpy(*valuePtr, (void *) native, (size_t)(*lengthPtr)+1);
00112 }
00113 
00114 /*
00115  *----------------------------------------------------------------------
00116  *
00117  * Tcl_GetHostName --
00118  *
00119  *      Returns the name of the local host.
00120  *
00121  * Results:
00122  *      A string containing the network name for this machine, or an empty
00123  *      string if we can't figure out the name. The caller must not modify or
00124  *      free this string.
00125  *
00126  * Side effects:
00127  *      Caches the name to return for future calls.
00128  *
00129  *----------------------------------------------------------------------
00130  */
00131 
00132 CONST char *
00133 Tcl_GetHostName(void)
00134 {
00135     return Tcl_GetString(TclGetProcessGlobalValue(&hostName));
00136 }
00137 
00138 /*
00139  *----------------------------------------------------------------------
00140  *
00141  * TclpHasSockets --
00142  *
00143  *      Detect if sockets are available on this platform.
00144  *
00145  * Results:
00146  *      Returns TCL_OK.
00147  *
00148  * Side effects:
00149  *      None.
00150  *
00151  *----------------------------------------------------------------------
00152  */
00153 
00154 int
00155 TclpHasSockets(
00156     Tcl_Interp *interp)         /* Not used. */
00157 {
00158     return TCL_OK;
00159 }
00160 
00161 /*
00162  *----------------------------------------------------------------------
00163  *
00164  * TclpFinalizeSockets --
00165  *
00166  *      Performs per-thread socket subsystem finalization.
00167  *
00168  * Results:
00169  *      None.
00170  *
00171  * Side effects:
00172  *      None.
00173  *
00174  *----------------------------------------------------------------------
00175  */
00176 
00177 void
00178 TclpFinalizeSockets(void)
00179 {
00180     return;
00181 }
00182 
00183 /*
00184  * Local Variables:
00185  * mode: c
00186  * c-basic-offset: 4
00187  * fill-column: 78
00188  * End:
00189  */



Generated on Wed Mar 12 12:18:26 2008 by  doxygen 1.5.1