Linux是一款被广泛应用的操作系统,它有强大的网络功能并且对网络编程提供了丰富的API,gethostname函数就是其中之一。本文将从gethostname函数的概念、用法和实现方法三个方面来探讨Linux中gethostname函数的知识。
1. gethostname函数的概念
gethostname函数是Linux中的一个系统调用,它用于获取当前主机的名称和域名。其原型定义如下:
“`
#include
int gethostname(char *name, size_t len);
“`
其中,name用于存储获取到的主机名,len是主机名的更大长度。
2. gethostname函数的用法
gethostname函数的使用非常简单,只需要传入一个能够存储主机名的缓冲区和缓冲区的大小就可以了。下面是一个示例:
“`
#include
#include
int mn(void)
{
char buf[256];
if (gethostname(buf, sizeof(buf)) != 0) {
printf(“Fled to get hostname\n”);
return 1;
}
printf(“Hostname: %s\n”, buf);
return 0;
}
“`
这个程序将获取当前主机的名称并输出到控制台上。需要注意的是,在调用gethostname函数时,如果缓冲区不足以存储主机名,会返回一个错误码和一个错误消息。
3. gethostname函数的实现方法
linux系统实现gethostname函数的方式不尽相同,但通常是通过调用内核的名字空间系统调用或者获取节点名来实现的。这里我们以Ubuntu 18.04.5 LTS为例,介绍一下其gethostname函数的实现方法。
3.1 内核的名字空间系统调用
Linux系统将所有的系统资源都组织成了名字空间,其中包括网络名字空间。gethostname函数可以通过调用内核的名字空间系统调用来获取当前所在网络名字空间的主机名。
在Ubuntu 18.04.5 LTS中,gethostname函数的实现如下所示:
“`
int gethostname(char *name, size_t len)
{
struct linux_namespace *namespace;
int result = -EFAULT;
if (copy_from_user(&namespace, raw_cpu_ptr(&task_curr()->nsproxy->net_ns), sizeof(namespace)))
goto out_put_task;
rcu_read_lock();
result = strncpy_from_user(name, namespace->ns.in_netns->name, len);
rcu_read_unlock();
out_put_task:
return (result >= 0) ? 0 : -ENOMEM;
}
“`
这个实现方法首先通过task_curr函数获取当前进程的信息,然后使用nsproxy成员变量获取进程所在的网络名字空间。接着在获取网络名字空间的节点名后,使用strncpy_from_user将其拷贝到用于存储主机名的缓冲区中。最后将0或-ENOMEM作为返回值返回。
3.2 获取节点名
除了使用名字空间系统调用以外,gethostname函数还可以通过获取节点名的方式来实现。在Linux中,节点名被保存在内核的uts_namespace结构体中的utsname成员变量中。
在Ubuntu 18.04.5 LTS中,gethostname函数的实现如下所示:
“`
int gethostname(char *name, size_t len)
{
struct new_utsname *utsname = &init_uts_ns.name;
if (len > sizeof(utsname->nodename))
len = sizeof(utsname->nodename);
return strncpy_from_user(name, utsname->nodename, len) >= 0 ? 0 : -EFAULT;
}
“`
这个实现方法首先获取内核的uts命名空间,并从中获取节点名。如果缓冲区的大小超过节点名的长度,就将缓冲区的长度重置为节点名的长度。最后使用strncpy_from_user将获取到的节点名拷贝到缓冲区中,并根据是否成功拷贝返回0或-EFAULT。
4.
相关问题拓展阅读:
- Linux命令更改hostnane
- 用C程序查看linux/win操作系统信息
- Linux 查看域名信息 h_addr_list[]Segmentation fault (core dumped) 为什么出这种错
linux命令更改hostnane
查看当前的主机名
首先我们使用hostname命令来查看当前的主机名。
hostname1
也可以使用hostnamctl命令
hostnamectl
方法1:修改配置文件
主机名保存在/etc/hostname文件里,所以我们可以打开这个文件,手动编辑主机名枣芦。
sudo nano /etc/hosts12
把旧的主机名删除,替换为新的主机名,保存文件就行了。要注意大小写。
方法2:hostnamectl命令
命令语法为握袭:
sudo hostnamectl set-hostname 12
这条命令会删除/etc/hostname文件中的主机名,然后替换为新的主机名。和之一种方法一样,我们也需要更新/etc/hosts文件。这两种方法的本质都是一样的。
方法3:hostname命令进行临时更改
如果只需要临时更改主机名,可以使用hostname命令。 《Linux就该这么学》
sudo hostname 12
这条命令不会更改/etc/hostname文件凳皮带中的静态主机名(static hostname),它更改的只是临时主机名(transient hostname)。所以重启计算机后会回到旧的主机名。
静态主机名保存在/etc/hostname文件中。
用C程序查看linux/win操作系统信息
linux
linux下的/proc下的cpuinfo里是燃兄cpu信息,/proc下的version是版本拦滑相关信简段腊息。
windows不知道
获取 Windows 操作系统版本信息的 C 程序
From:
// OSinfo.cpp : 定义控制台应用程序的入口点。
#include “stdafx.h”
#include
#include
#include “winsock.h”
#include
#include
using std::cout;using std::string;using std::iostream;
using std::endl;using std::ios;using std::fstream;
using std::ofstream;using std::cin;
#pragma comment( lib, “Ws2_32.lib” )
#define MAX_VALUE_NAME 256
//char osinfo;
char patchname;
//全局变量
char *LocalIP=””; //定义IP地址变量
//获取本机ip
bool GetLocalIp()
{
WSADATA wsaData;
char name;//定义用于存放获得的主机名的变量
PHOSTENT hostinfo;
//调用MAKEWORD()获得Winsock版本的正确值,用于加载Winsock库
if ( WSAStartup( MAKEWORD(2,2), &wsaData ) == 0 )
{
//现在是加载Winsock库,如果WSAStartup()函数返回值为0,说明加载成功,程序可以继续
if( gethostname ( name, sizeof(name)) == 0)
{
//简拿启拦如如果成功地将本地主机名存放入由name参数指定的缓冲区中
if((hostinfo = gethostbyname(name)) != NULL)
{
//这是获取主机名,如果获得主机名成功的敏亮话,将返回一个指针,指向hostinfo,hostinfo
//为PHOSTENT型的变量,下面即将用到这个结构体
LocalIP = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
//调用inet_ntoa()函数,将hostinfo结构变量中的h_addr_list转化为标准的点分表示的IP
//地址(如192.168.0.1)
// printf(“the ip is:%s\n”,LocalIP);//输出IP地址
}
}
WSACleanup( );//卸载Winsock库,并释放所有资源
}
return TRUE;
}
//显示系统版本
bool DisplaySystemVesion(FILE *fp)
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
//利用OSVERSIONINFOEX结构调用GetVersionEx()函数
//如果调用失败,可尝试使用OSVERSIONINFO结构
ZeroMemory(&osvi,sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);
if(!(bOsVersionInfoEx=GetVersionEx((OSVERSIONINFO*)&osvi)))
{
//
osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if(!GetVersionEx((OSVERSIONINFO*)&osvi))
return FALSE;
}
switch(osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
//get os information
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
{
printf(“Microsoft Windows Server 2023 family “);
//fprintf( fp, “Microsoft Windows Server 2023 family “);
fprintf( fp, “WindowsServer2023”);
// strcpy(osinfo,”Microsoft Windows Server 2023 family “);
}
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
{
printf(“Microsoft Windows XP “);
//fprintf( fp, “Microsoft Windows XP “);
fprintf( fp, “WindowsXP”);
// strcpy(osinfo,”Microsoft Windows XP “);
}
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
{
printf(“Microsoft Windows 2023 “);
//fprintf( fp, “Microsoft Windows 2023 “);
fprintf( fp, “Windows2023”);
// strcpy(osinfo,”Microsoft Windows 2023 “);
}
if ( osvi.dwMajorVersion
{
printf(“Microsoft Windows NT “);
//fprintf( fp, “Microsoft Windows NT “);
fprintf( fp, “WindowsNT”);
// strcpy(osinfo,”Microsoft Windows NT “);
}
//
if(bOsVersionInfoEx)
{
if(osvi.wProductType==VER_NT_WORKSTATION)
{
printf(“Professional “);
// fprintf(fp,”Professional “);
}
if(osvi.wProductType==VER_NT_SERVER)
{
printf(“Server “);
// fprintf(fp,”Server “);
}
//printf(“\n”);
fprintf(fp,”\n”);
}
else
{
HKEY hKey;
char szProductType;
DWORD dwBufLen;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,”SYSTEM\\CurrentControlSet\\Control\\ProductOptions”,0,KEY_QUERY_VALUE,&hKey);
RegQueryValueEx(hKey,”ProductType”,NULL,NULL,(LPBYTE)szProductType,&dwBufLen);
RegCloseKey(hKey);
if(lstrcmpi(“WINNT”,szProductType)==0)
{
printf(“Workstation “);
// fprintf(fp,”Workstation “);
}
if(lstrcmpi(“SERVERNT”,szProductType)==0)
{
printf(“Server “);
// fprintf(fp,”Server “);
}
//printf(“\n”);
fprintf(fp,”\n”);
}
// Display service pack (if any) and build number.
if( osvi.dwMajorVersion == 4 &&
lstrcmpi( osvi.szCSDVersion, “Service Pack 6” ) == 0 )
{
HKEY hKey;
LONG lRet;
// Test for SP6 versus SP6a.
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
“SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009”,
0, KEY_QUERY_VALUE, &hKey );
if( lRet == ERROR_SUCCESS )
{
printf( “Service Pack 6a (Build %d)\n”, osvi.dwBuildNumber & 0xFFFF );
// fprintf( fp,”Service Pack 6a (Build %d)\n”, osvi.dwBuildNumber & 0xFFFF );
// fprintf( fp,”Service Pack 6a\n” );
fprintf( fp,”6a\n” );
}
else // Windows NT 4.0 prior to SP6a
{
printf( “%s (Build %d)”,osvi.szCSDVersion,osvi.dwBuildNumber & 0xFFFF);
/* printf( “%s (Build %d)\n”,
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
*/
// fprintf( fp,”%s (Build %d)\n”,
// osvi.szCSDVersion,
// osvi.dwBuildNumber & 0xFFFF);
// fprintf( fp,”%s\n”,osvi.szCSDVersion);
fprintf( fp,”%s\n”,osvi.szCSDVersion+13); //去掉”Service Pack “共13个字节,只保留最后的号
}
RegCloseKey( hKey );
}
else // Windows NT 3.51 and earlier or Windows 2023 and later
{
printf( “%s (Build %d)”,osvi.szCSDVersion,osvi.dwBuildNumber & 0xFFFF);
/*printf( “%s (Build %d)\n”,
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
*/
// fprintf( fp,”%s (Build %d)\n”,
// osvi.szCSDVersion,
// osvi.dwBuildNumber & 0xFFFF);
// fprintf( fp,”%s\n”,osvi.szCSDVersion);
fprintf( fp,”%s\n”,osvi.szCSDVersion+13); //去掉”Service Pack “共13个字节,只保留最后的号
}
break;
case VER_PLATFORM_WIN32_WINDOWS:
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
{
printf(“Microsoft Windows 95 “);
fprintf(fp,”Microsoft Windows 95 “);
if ( osvi.szCSDVersion == ‘C’ || osvi.szCSDVersion == ‘B’ )
{
printf(“OSR2”);
fprintf(fp,”OSR2″);
// strcat(osinfo, “OSR2” );
}
printf(“\n”);
fprintf(fp,”\n”);
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
{
printf(“Microsoft Windows 98 “);
fprintf(fp,”Microsoft Windows 98 “);
if ( osvi.szCSDVersion == ‘A’ )
{
printf(“SE”);
fprintf(fp,”SE”);
}
printf(“\n”);
fprintf(fp,”\n”);
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
{
printf(“Microsoft Windows Millennium Edition\n”);
fprintf(fp,”Microsoft Windows Millennium Edition\n”);
}
break;
case VER_PLATFORM_WIN32s:
printf(” Microsoft Win32s\n”);
fprintf(fp,” Microsoft Win32s\n”);
break;
}
return TRUE;
}
void DisplaySetupedPatch(FILE *fp)
{
HKEY hKey;
// LONG lRet;
// char Buf;
// char lpBuf;
DWORD i;
DWORD retCode;
// DWORD j;
// DWORD retValue;
DWORD dwxValueName=MAX_VALUE_NAME;
LPCTSTR path=”SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix”;
LONG return0=RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,0,KEY_READ,&hKey);
if(return0!=ERROR_SUCCESS)
{
printf(“错误:无法打开有关的键!”);
}
for(i=1,retCode=ERROR_SUCCESS;retCode==ERROR_SUCCESS;i++)
{
retCode=RegEnumKey(hKey,i,patchname,MAX_PATH);
if(retCode==ERROR_SUCCESS)
{
printf(“%s\n”,patchname);
fprintf(fp,”%s\n”,patchname);
}
}
}
void main()
{
//写入文件
FILE *fp;
GetLocalIp();
const char SaveReciveFilePath=”f:\\”;
string abPath(SaveReciveFilePath);
char Filename=””;
strcpy(Filename,LocalIP); //拷贝字符串
strcat(Filename,”.txt”); //连接字符串
abPath += Filename;
fp=fopen(abPath.c_str(),”w”);
while(fp==NULL);
// printf(“the LocalIP is:%s\n”,LocalIP);//输出IP地址
printf(“本机IP
// fprintf(fp,”本机IP:%s\n”,LocalIP);
// fprintf(fp,”%s\n”,LocalIP);
bool a=FALSE;
printf(“本机操作系统版本是:”);
// fprintf(fp,”本机操作系统版本是:”);
//操作系统版本信息
while (a!=TRUE)
{
a=DisplaySystemVesion(fp);
}
//操作系统语言信息
printf(“语言:”);
// fprintf(fp,”语言:”);
/* WORD wLangPID = PRIMARYLANGID( GetSystemDefaultLangID() );
if( LANG_CHINESE == wLangPID )
{
printf(“CHS\n”);//中文
fprintf(fp,”CHN\n”);
}
else
{
printf(“ENG\n”); //英文
fprintf(fp,”ENG\n”);
}
if( NULL == wLangPID )
{
printf( “Failure!\n” );
}
*/
int LanguageID=GetSystemDefaultLangID(); //返回操作系统语言的ID号
switch(LanguageID)
{
case 0x0404:
printf(“CHT\n”);//Chinese Taiwan
fprintf(fp,”CHT\n”);
break;
case 0x0804:
printf(“CHS\n”);//Chinese PRC
fprintf(fp,”CHS\n”);
break;
case 0x0c04:
printf(“ZHH\n”);//Chinese Hong Kong SAR
fprintf(fp,”ZHH\n”);
break;
case 0x1004:
printf(“ZHH\n”);//Chinese Singapore
fprintf(fp,”ZHH\n”);
break;
case 0x1404:
printf(“ZHM\n”);//Chinese Macau SAR
fprintf(fp,”ZHM\n”);
break;
case 0x0809:
printf(“ENG\n”);//English United Kingdom
fprintf(fp,”ENG\n”);
break;
case 0x0409:
printf(“USA\n”);//English United States
fprintf(fp,”USA\n”);
break;
default:
printf(“Default\n”);
fprintf(fp,”Default\n”);
break;
}
// printf(“%d\n”,id);
//操作系统已安装补丁信息
printf(“系统已经安装的升级补丁有:\n”);
// fprintf(fp,”系统已经安装的升级补丁有:\n”);
DisplaySetupedPatch(fp);
fclose(fp);
Linux 查看域名信息 h_addr_list[]Segmentation fault (core dumped) 为什么出这种错
for(i=0; i h_length;i++)
{
printf(“IP adderss %d :%s\n”,i+1,inet_ntoa(*(struct in_addr *)h->h_addr_list));
}
这个地方错了隐裂。
struct hostent
{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
#define h_addr h_addr_list
};
h_length 表示的是主机ip地址的长度
h_addr_list :表示的是铅携磨主机的ip地址
所以应该是直接打印:槐斗
关于linux gethostname函数的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。