《Linux C编程实战》笔记:进程操作之ID,优先级

获得进程ID

getpid函数

这个函数都用了很多次了,看一下定义和例子就行了

#include<sys/types.h>
#include <unistd.h>
pid_t getpid(void);

示例程序1

#include<cstdlib>
#include<malloc.h>
#include<cstring>
#include <cstdio>
#include<ctime>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<unistd.h>
#include<cerrno>
using namespace std;
int main(){pid_t pid;if((pid=fork())==-1){printf("fork error!\n");exit(1);}if(pid==0)printf("getpid return %d\n",getpid());//子进程exit(0);
}

setuid和setgid

用setuid设置实际用户ID和有效用户ID.setgid用来设置实际组ID和有效组ID

实际用户和有效用户解释见 《Linux C编程实战》笔记:进程操作之创建进程-CSDN博客

 

#include <sys/types.h>
#include <unistd.h>
int setuid(uid_t uid);
int seteuid(uid_t uid);//使用seteuid只会设置有效用户,无论是什么权限
int setgid(gid_t gid);
int setegid(gid_t gid);

设置用户ID的setuid函数遵守以下规则(设置组ID的setgid函数与此类似)。

若进程具有root权限,则函数将实际用户ID、有效用户ID设置为参数uid。
若进程不具有root权限,则setuid只将有效用户ID设置为uid,不改变实际用户ID。
若以上两个条件都不能满足,则函数调用失败,返回-1,并设置errno为 EPERM。

从以上规则可以看出,只有超级用户进程才能更改实际用户ID,所以一个非特权用户进程是不能通过setuid或seteuid得到特权用户权限的。

内核时检查一个进程是否有权限访问某文件时,是使用进程的有效用户ID来检查的。

像su命令,普通用户运行时,su进程的权限是root权限

示例程序2

演示有效用户

#include<cstdlib>
#include<malloc.h>
#include<cstring>
#include <cstdio>
#include<ctime>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<unistd.h>
#include<cerrno>
using namespace std;
int main(){int fd;printf("uid study:\n");printf("Process;s uid=%d,euid=%d\n",getuid(),geteuid());//seteuid(0);//printf("Process;s uid=%d,euid=%d",getuid(),geteuid());if((fd=open("test.c",O_RDWR))==-1){//想要以读写方式打开一个文件printf("Open failure,errno is %d:%s \n",errno,strerror(errno));exit(1);}else printf("Open successfully!\n");close (fd);exit(0);
}

首先,我们以root用户创建一个文件,可以看到其他用户只能读不能写 

我们切换到一个普通用户运行程序,由于程序想要读写文件,是没有权限的

我们把注释取消看看这回能不能读写

首先要在root下位程序文件设置set_uid位,不然程序也是改变不了uid的

  • 最前面的 "4" 代表了setuid位。
  • "7" 代表了所有者的权限,包括读(4) + 写(2) + 执行(1)。
  • "5" 代表了组的权限,包括读(4) + 执行(1)。
  • "5" 代表了其他用户的权限,包括读(4) + 执行(1)。

不过在我的Linux下,即使设置了chmod,依然读不了文件。我也不知道书上是怎么成功的,这个例子我只能以失败告终。

顺便了解

strerror 是一个 C 语言标准库函数,用于将错误码(通常由全局变量 errno 表示)转换为对应的错误消息字符串。函数原型通常定义在 <string.h> 头文件中,其一般形式如下:

#include <string.h> char *strerror(int errnum);

参数 errnum 是一个整数,通常是全局变量 errno 的值,表示发生的错误码。strerror 函数返回一个指向错误消息字符串的指针,该字符串描述了对应错误码的错误信息。

可以这样使用setuid函数:开始时某个程序需要root权限完成一些工作,但后续的工作不需要root权限。可以将该可执行程序文件设置set_uid位,并使得该文件的属主是root。这样普通用户执行这个程序时,进程就具有了root权限,当不再需要root权限时,调用setuid(getuid())恢复进程的实际用户ID和有效用户ID为执行该程序的普通用户的ID.对于一些提供网络服务的程序,这样做是非常有必要的,否则就可能被攻击者利用,使攻击者控制整个系统。

对于设置了set_uid 位的可执行程序也要注意,尤其是对那些属主是root 的更要注意。因为Linux 系统中 root用户拥有最高权力。黑客们往往喜欢寻找设置了set_uid位的可执行程序的漏洞,这样的程序如果存在缓冲区溢出漏洞,并且该程序是一个网络程序,那么黑客可以从远程的地方轻松地利用该漏洞获得运行该漏洞程序的主机的root权限。即使这样的程序不是网络程序,那么也可以使本机上的恶意普通用户提升为root用户。

改变进程优先级

nice函数

nice系统调用用来改变调用进程的优先级。

#include <unistd.h>
int nice (int increment);

在介绍nice系统调用的用法前,需要先了解两个重要的函数:getpriority和setpriority,它们声明如下:

#include <sys/resource.h>
int getpriority(int which, int who);
int setpriority(int which, int who,int prio);

getpriority函数:该函数返回一组进程的优先级。参数 which和 who组合确定返回哪一组进程的优先级。which的可能取值以及 who的意义如下。
PRIO_PROCESS:一个特定的进程,此时who的取值为进程ID。
PRIO_PGRP:一个进程组的所有进程,此时who的取值为进程组ID。
PRIO_USER:一个用户拥有的所有进程,此时参数who取值为实际用户ID。

getpriority函数如果调用成功返回指定进程的优先级,如果出错将返回-1,并设置errno的值。errno可能的取值如下。
 ESRCH: which和 who的组合与现存的所有进程均不匹配。

 EINVAL: which是个无效的值。

setpriority函数:该函数用来设置指定进程的优先级。进程指定的方法与getpriority 函数相同。如果调用成功,函数返回指定进程的优先级,出错则返回-1,并设置相应errno。除了产生与getpriority相同的两个错误外,还有可能产生以下错误。
EPERM:要设置优先级的进程与当前进程不属于同一个用户,并且当前进程没有CAP_SYS_NICE特许。
EACCES:该调用可能降低进程的优先级并且进程没有CAP_SYS_NICE特许。

nice是它们的组合形式,nice系统调用等于

int nice(int increment){int oldpro=getpriority(PRIO_PROCESS,getpid());return setpriority(PRIO_PROCESS,getpid(),oldpro+increment);
}

就相当于 原本的优先级加上increment参数,返回新的优先级 

示例程序3

#include<cstdlib>
#include<malloc.h>
#include<cstring>
#include <cstdio>
#include<ctime>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<sys/resource.h>
#include<fcntl.h>
#include<unistd.h>
#include<cerrno>
using namespace std;
int main(){pid_t pid;int stat_val=0;int oldpri,newpri;printf("nice study\n");pid=fork();switch (pid){case 0:printf("Child is running,CurPid is %d,ParentPid is %d\n",getpid(),getppid());oldpri=getpriority(PRIO_PROCESS,getpid());printf("Old priority=%d\n",oldpri);newpri=nice(2);//优先级提升2printf("New priority=%d\n",newpri);exit(0);case -1:perror("Process creation failed\n");break;default:printf("Parent is running,ChildPid is %d,ParentPid is %d\n",pid,getpid());break;}wait(&stat_val);exit(0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/233929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSM整合实战(Spring、SpringMVC、MyBatis)

五、SSM整合实战 目录 一、SSM整合理解 1. 什么是SSM整合&#xff1f;2. SSM整合核心理解五连问&#xff01; 2.1 SSM整合涉及几个IoC容器&#xff1f;2.2 每个IoC容器盛放哪些组件&#xff1f;2.3 IoC容器之间是什么关系&#xff1f;2.4 需要几个配置文件和对应IoC容器关系&…

2.vue学习(8-13)

文章目录 8.数据绑定9.el与data的2种写法10.理解mvvm11.object.defineProperty12. 理解数据代理13 vue中的数据代理 8.数据绑定 单向数据绑定就是我们学的v-bind的方式&#xff0c;vue对象变了&#xff0c;页面才变。但是页面变了&#xff0c;vue对象不会变。 双向数据绑定需要…

时序预测 | Python实现LSTM-Attention电力需求预测

时序预测 | Python实现LSTM-Attention电力需求预测 目录 时序预测 | Python实现LSTM-Attention电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从而可以将预期预测与当前最先进的行…

vue 学习笔记

生命周期 1&#xff09;定义&#xff1a;vue实例从创建到销毁的过程 2&#xff09;钩子函数 2.1&#xff09;beforeCreate&#xff1a;vue实例初始化之前调用&#xff0c;这个阶段vue实例刚刚在内存中创建&#xff0c;此时data和methods这些都没初始化好。 2.2&#xff09;Cre…

【算法】红黑树

一、红黑树介绍 红黑树是一种自平衡二叉查找树&#xff0c;是在计算机科学中用到的一种数据结构&#xff0c;典型的用途是实现关联数组。 红黑树是在1972年由Rudolf Bayer发明的&#xff0c;当时被称为平衡二叉B树&#xff08;symmetric binary B-trees&#xff09;。后来&am…

Educational Codeforces Round 160 (Rated for Div. 2)

Educational Codeforces Round 160 (Rated for Div. 2) Educational Codeforces Round 160 (Rated for Div. 2) A. Rating Increase 题意&#xff1a;给定一个由数字字符组成的字符串&#xff0c;且无前导零&#xff0c;将其分割成ab两部分&#xff0c;b不能有前导零&#x…

DETR 【目标检测里程碑的任务】

paper with code - DETR 标题 End-to-End Object Detection with Transformers end-to-end 意味着去掉了NMS的操作&#xff08;生成很多的预测框&#xff0c;nms 去掉冗余的预测框&#xff09;。因为有了NMS &#xff0c;所以调参&#xff0c;训练都会多了一道工序&#xff0c…

Gemini 1.0:Google推出的全新AI模型,改变生成式人工智能领域的游戏规则!

Gemini 1.0&#xff1a;Google推出的全新AI模型&#xff0c;将改变生成式人工智能领域的游戏规则&#xff01; &#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 …

Ubuntu18.04 上通过 jihu 镜像完成 ESP-IDF 编译环境搭建流程

为了解决国内开发者从 github 克隆 esp 相关仓库慢的问题&#xff0c;已将 esp-idf 和部分重要仓库及其关联的子模块镜像到了 jihu&#xff0c;这些仓库将自动从原始仓库进行同步。此篇博客用来阐述 Ubuntu18.04 上通过 jihu 镜像完成 ESP-IDF 编译环境搭建流程。 注&#xff1…

LeetCode Hot100 51.N皇后

题目&#xff1a; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的…

亚马逊鲲鹏系统:引领批量自动操作买家号先进技术

亚马逊&#xff0c;作为全球最大的电商平台之一&#xff0c;其独特的自动化批量操作一直是众多我追逐的焦点。深入了解其主要使用方法&#xff0c;通过批量导入无数个买家账户&#xff0c;借助最新的反指纹技术和国外代理IP的绑定&#xff0c;可以成功规遍亚马逊市场&#xff0…

TortoiseGit通过SSH连接配置,生成SSH密钥方法

生成SSH密钥&#xff1a; Win环境下命令(git ssh key是可以自定义命名的)&#xff1a; ssh-keygen -t ed25519 -C "git ssh key" && start "" "C:\Windows\notepad.exe" "C:\Users\%username%\.ssh\id_ed25519.pub" 打开cm…

三相异步电机动态数学模型推导及矢量控制仿真

文章目录 **原文链接&#xff0c;点击跳转**三相异步电机动态数学模型及矢量控制仿真1、异步电机三相方程2、坐标变换3、磁链3/2变换推导4、两相静止坐标系下的方程5、两相旋转坐标系下的方程6、以 ω-is-Ψr 为状态变量的状态方程7、矢量控制及 matlab 仿真 原文链接&#xff…

Linux中使用HTTP协议进行API交互的示例

在Linux中&#xff0c;HTTP协议就像一个神奇的传送门&#xff0c;让我们可以通过网络进行各种交互。这不&#xff0c;今天我们就来探讨一下如何使用HTTP协议在Linux中进行API交互。 首先&#xff0c;我们需要一个API。为了方便演示&#xff0c;我们假设有一个天气预报API&…

spark介绍及简单使用

简介 Spark是由加州大学伯克利分校AMPLab&#xff08;AMP实验室&#xff09;开发的开源大数据处理框架。起初&#xff0c;Hadoop MapReduce是大数据处理的主流框架&#xff0c;但其存在一些限制&#xff0c;如不适合迭代算法、高延迟等。为了解决这些问题&#xff0c;Spark在20…

Re解析(正则表达式解析)

正则表达式基础 元字符 B站教学视频&#xff1a; 正则表达式元字符基本使用 量词 贪婪匹配和惰性匹配 惰性匹配如下两张图&#xff0c;而 .* 就表示贪婪匹配&#xff0c;即尽可能多的匹配到符合的字符串&#xff0c;如果使用贪婪匹配&#xff0c;那么结果就是图中的情况三 p…

【Unity】运行时创建曲线(贝塞尔的运用)

[Unity]运行时创建线&#xff08;贝塞尔的运用&#xff09; 1. 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线。 2. 原理介绍 2.1 曲线的创建 unity建立网格曲线可以参考Unity程序化网格体的实现方法。主要分为顶点&#xff0c;三角面&#xff0c…

浪潮信息KOS服务器操作系统:经过周密考虑后的智慧之选

文章目录 一、引言二、服务器操作系统概述三、选择服务器操作系统的关键因素四、评估服务器操作系统的标准五、选择服务器操作系统的实践经验六、浪潮信息KOS服务器操作系统一、稳定可靠二、高效协同三、全天候运维四、广泛兼容 七、总结与展望 浪潮信息信息KOS是浪潮信息信息基…

linux: ip route 与 route 用法详解与对比

文章目录 1. 引言2. ip route2.1 描述2.2 语法2.3 参数2.4 例子 3. route3.1 描述3.2 语法3.3 参数3.4 例子 4. 对比5. 参考 1. 引言 本文主要介绍 ip route 以及 route 的用法和区别。 2. ip route 2.1 描述 用于管理静态路由表。linux 系统中&#xff0c;可以自定义从 1&…

【docker】数据管理

Docker容器会随时关闭和开启,Docker 容器的数据放哪里呢&#xff1f; 答案就是&#xff1a;数据卷和数据卷容器 官网文档 Manage data in Docker | Docker Docs 数据卷(Data Volume) 数据卷就是将宿主机的某个目录&#xff0c;映射到容器中&#xff0c;作为数据存储的目录&…