Linux系统调用十、进程地址空间、文件描述符、errno错误码、dup()重定向_linux错误码10

最全的Linux教程,Linux从入门到精通

======================

  1. linux从入门到精通(第2版)

  2. Linux系统移植

  3. Linux驱动开发入门与实战

  4. LINUX 系统移植 第2版

  5. Linux开源网络全栈详解 从DPDK到OpenFlow

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。

需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!


🥇1. 进程虚拟地址空间与文件描述符

首先我们看一下进程虚拟空间和文件描述符的示意图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VSaJybyg-1653311215263)(./Typora_picture_reference/1652502540415.png)]
下面我们写一个程序来测试一下,一次性最多能打开的文件数量,来验证文件描述符的作用和范围。

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 >File Name : openfilemax.c
 >Author : QQ
 >Company : QQ
 >Create Time: 2022年05月14日 星期六 10时25分25秒
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc, char\* argv[])
{
	int id = 3;
	char filename[128] = {0};
	while(1)
	{
		sprintf(filename, "file\_%04d", id);
		if(open(filename, O_CREAT | O_RDONLY, 0644) < 0)
		{
			perror("open err:");
			break;	
		}
		id++;
	}
	printf("open file maxnum: %d\n", id);
	return 0;
}

编译运行,可以看到运行结果为1024,实际文件名最小是0003最大是1023。这是为什么呢?我们通过上面的文件描述符示意图可以看到,文件描述符最大是1023,从0到1023也就是总共1024个文件描述符。也就是说我们最多可以一次性打开1024个文件,再多的话就没有文件描述符可用了。这样的话,我们打开的文件从0003到1023,再加上标准输入0、标准输出1、标准错误2这三个文件,总共就是1024个文件。因为在开启一个进程的时候默认会打开标准输入输出和标准错误这三个文件,所以我们实际打开的文件只有1023-3+1=1021个文件,那么总共打开的文件个数就是1024个。
在这里插入图片描述

🥇2. errno错误码与strerror()函数

🥈2.1 什么是errno

errno可以理解为一个全局变量,它存储了出错信息。在下面三个路径可以看到errno相关的内容

/usr/include/errno.h
/usr/include/asm-generic/errno-base.h
/usr/include/asm-generic/errno.h

我们可以在这些文件中自己定义一些errno,这样可以做到我们自己知道原始错误信息,而打印出来给用户看的是我们希望用户看到的对原始错误的解释。

🥈2.2 strerror()函数说明
  • 包含头文件
#include <string.h>

  • 函数原型
char \*strerror(int errnum);

  • 函数功能

可以打印errno对应的详细错误信息。The strerror() function returns a pointer to a string that describes the error code passed in the argument errnum, possibly using the LC_MESSAGES part of the current locale to select the appropriate language. This string must not be modified by the application, but may be modified by a subsequent call to perror(3) or strerror(). No library function will modify this string.

  • 函数参数

    • errnum:错误编号
  • 函数返回值

The strerror() functions return the appropriate error description string, or an “Unknown error nnn” message if the error number is unknown. 返回错误信息。

🥇3. dup()和dup2()函数

  • 包含头文件
#include <unistd.h>

  • 函数原型
int dup(int oldfd);
int dup2(int oldfd, int newfd);

#define \_GNU\_SOURCE
#include <unistd.h>

int dup3(int oldfd, int newfd, int flags);

  • 函数功能

这两个函数主要用于重定向,它们两个的功能和区别就是:

+ dup(oldfd):复制文件描述符,返回一个当前空闲的最小文件描述符,并且让这个文件描述符指向oldfd所指向的文件;dup() uses the lowest-numbered unused descriptor for the new descriptor.
+ dup2(oldfd, newfd):重定向,关闭newfd对应的文件使文件描述符newfd空闲,然后让newfd指向oldfd所指向的文件;dup2() makes newfd be the copy of oldfd, closing newfd first if necessary, but note the following: If oldfd is not a valid file descriptor, then the call fails, and newfd is not closed. If oldfd is a valid file descriptor, and newfd has the same value as oldfd, then dup2() does nothing, and returns newfd.

在这里插入图片描述

  • 函数参数

    • oldfd:旧的文件描述符
    • newfd:新的文件描述符
  • 函数返回值

    • On success, these system calls return the new descriptor.
    • On error, -1 is returned, and errno is set appropriately.

示例:一句话打印两次,先打入文件,后打至屏幕

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
 >File Name : dup\_test.c
 >Author : QQ
 >Company : QQ
 >Create Time: 2022年05月17日 星期二 16时09分41秒
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc, char\* argv[])
{
	if(argc < 2)
	{
		printf("not found string\n");
		return -1;
	}	
	/\*每开启一个进程,默认打开 0 1 2 三个文件描述符\*/
	/\*首先备份标准输出\*/
	int stdoutfd = dup(STDOUT_FILENO);
	/\*打开一个文件\*/
	int fd = open("hello.txt", O_WRONLY | O_CREAT, 0644);
	/\*重定向标准输出1至文件\*/
	dup2(fd, STDOUT_FILENO);	
	printf("first: %s\n", argv[1]);
    
    /\* ===========================
 printf会进行系统调用,需要刷新buffer


### 最后的话

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

### 资料预览

给大家整理的视频资料:

![](https://img-blog.csdnimg.cn/img_convert/781546383684ef2b85abea286b771af7.png)

给大家整理的电子书资料:

  

![](https://img-blog.csdnimg.cn/img_convert/945ebf017961f793ba9a09a6a46c07d8.png)



**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux错误码65280对应的错误号(errno)是126,表示执行一个命令时发生了错误。以下是常见的Linux错误号及其对应的错误: 1. EPERM (1):操作不允许 2. ENOENT (2):文件或目录不存在 3. ESRCH (3):没有这样的进程 4. EINTR (4):系统调用被中断 5. EIO (5):输入/输出错误 6. ENXIO (6):没有这样的设备或地址 7. E2BIG (7):参数列表太长 8. ENOEXEC (8):执行格式错误 9. EBADF (9):文件描述符无效 10. ECHILD (10):没有这样的子进程 11. EAGAIN (11):资源暂时不可用 12. ENOMEM (12):内存不足 13. EACCES (13):权限不足 14. EFAULT (14):错误的地址 15. ENOTBLK (15):块设备必须使用块IO 16. EBUSY (16):设备或资源忙 17. EEXIST (17):文件已存在 18. EXDEV (18):跨文件系统链接 19. ENODEV (19):操作不支持设备 20. ENOTDIR (20):不是目录 21. EISDIR (21):是目录 22. EINVAL (22):无效的参数 23. ENFILE (23):文件打开太多 24. EMFILE (24):文件描述符打开太多 25. ENOTTY (25):不是终端设备 26. ETXTBSY (26):文本文件忙 27. EFBIG (27):文件太大 28. ENOSPC (28):没有空间 29. ESPIPE (29):无效的seek 30. EROFS (30):只读文件系统 31. EMLINK (31):链接太多 32. EPIPE (32):捕获信号管道 33. EDOM (33):数学参数超出定义域 34. ERANGE (34):数学结果不可表示 35. EDEADLK (35):资源死锁避免 36. ENAMETOOLONG (36):文件名太长 37. ENOLCK (37):没有可用的记录锁 38. ENOSYS (38):函数不支持 39. ENOTEMPTY (39):目录不为空 40. ELOOP (40):太多的符号链接 41. ENOMSG (42):没有消息的标识符 42. EIDRM (43):标识符已删除 43. ECHRNG (44):通道范围不正确 44. EL2NSYNC (45):Level 2不同步 45. EL3HLT (46):Level 3被挂起 46. EL3RST (47):Level 3重置 47. ELNRNG (48):Link number超出范围 48. EUNATCH (49):Protocol driver不可用 49. ENOCSI (50):没有CSI结构可用 50. EL2HLT (51):Level 2被挂起 51. EBADE (52):无效的交换 52. EBADR (53):无效的请求描述符 53. EXFULL (54):交换空间已满 54. ENOANO (55):没有对应的自动识别对象 55. EBADRQC (56):无效的请求描述符或参数 56. EBADSLT (57):Slot不存在 57. EBFONT (59):无效字体文件格式 58. ENOSTR (60):设备不是流 59. ENODATA (61):没有数据可用 60. ETIME (62):计时器已过期 61. ENOSR (63):没有记录可用 62. ENONET (64):网络不可用 63. ENOPKG (65):包没有安装 64. EREMOTE (66):对象是远程的 65. ENOLINK (67):链路不存在 66. EADV (68):广告错误 67. ESRMNT (69):Srmount错误 68. ECOMM (70):通信错误 69. EPROTO (71):协议错误 70. EMULTIHOP (72):多跳跃I / O 71. EDOTDOT (73):RFS特定错误 72. EBADMSG (74):错误的消息 73. EOVERFLOW (75):值太大以便于定义 74. ENOTUNIQ (76):名称不唯一 75. EBADFD (77):文件描述符在错误状态 76. EREMCHG (78):远程地址已更改 77. ELIBACC (79):无法访问共享库 78. ELIBBAD (80):共享库损坏 79. ELIBSCN (81):没有共享库文本段 80. ELIBMAX (82):共享库表已满 81. ELIBEXEC (83):无法执行共享库 82. EILSEQ (84):无效的或不完整的多字节序列 83. ERESTART (85):无需重新启动系统调用 84. ESTRPIPE (86):管道流不支持 85. EUSERS (87):太多用户 86. ENOTSOCK (88):套接字操作的目标不是套接字 87. EDESTADDRREQ (89):需要目标地址 88. EMSGSIZE (90):消息太长 89. EPROTOTYPE (91):错误的协议类型 90. ENOPROTOOPT (92):协议不可用 91. EPROTONOSUPPORT (93):协议不支持 92. ESOCKTNOSUPPORT (94):套接字类型不支持 93. EOPNOTSUPP (95):操作不支持 94. EPFNOSUPPORT (96):协议族不支持 95. EAFNOSUPPORT (97):地址族不支持 96. EADDRINUSE (98):地址已在使用中 97. EADDRNOTAVAIL (99):不能分配所需的地址 98. ENETDOWN (100):网络已关闭 99. ENETUNREACH (101):网络不可达 100. ENETRESET (102):网络连接已重置 101. ECONNABORTED (103):连接被中止 102. ECONNRESET (104):连接被重置 103. ENOBUFS (105):没有缓冲区可用 104. EISCONN (106):套接字已连接 105. ENOTCONN (107):套接字未连接 106. ESHUTDOWN (108):不能执行发送,套接字已关闭 107. ETOOMANYREFS (109):太多参考:无法分配请求的资源 108. ETIMEDOUT (110):连接超时 109. ECONNREFUSED (111):连接被拒绝 110. EHOSTDOWN (112):主机已关闭 111. EHOSTUNREACH (113):主机不可达 112. EALREADY (114):操作已经在进行中 113. EINPROGRESS (115):操作正在进行中 114. ESTALE (116):Stale NFS文件句柄 115. EUCLEAN (117):结构取消 116. ENOTNAM (118):不是XENIX命名文件 117. ENAVAIL (119):No XENIX semaphores available 118. EISNAM (120):Is a named type file 119. EREMOTEIO (121):远程I / O错误 120. EDQUOT (122):Quota exceeded 121. ENOMEDIUM (123):没有中介信息 122. EMEDIUMTYPE (124):中介错误 123. ECANCELED (125):操作被取消 124. ENOKEY (126):没有KEY值 125. EKEYEXPIRED (127):KEY已过期 126. EKEYREVOKED (128):KEY已被撤销 127. EKEYREJECTED (129):KEY被拒绝 128. EOWNERDEAD (130):所有者已死 129. ENOTRECOVERABLE (131):无法恢复

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值