1. 用户登录:
(1)根据用户名确定身份 权限
(2)验证密码
(3)创建shell
(4)用户主目录
2. 了解自己的环境变量
[code]
#include<iostream>
using namespace std;
int main( int argc, char* argv[], char* env[] ){
cout<<" ---------------begin-------------- "<<endl;
while( env!=NULL && *env!=NULL ){
cout<<*env<<endl;
env++;
}
cout<<" ---------------end --------------- "<<endl;
return 0;
}
[/code]
3. 在程序中操作环境变量
#include<stdlib.h>
char* getenv( const char* name ) // 返回变量名的值
int putenv( const char* str ) // 修改/添加变量,但只在程序内有效,因为它改动的只是自己进程空间内的env列表,并不影响内核的env
例子:
[code]
#include<iostream>
#include<unistd.h>
using namespace std;
int main(){
//cout<<"ORACLE_SID="<<getenv( "ORACLE_SID" )<<endl;
putenv( "AAA=123456" );
cout<<"AAA="<<getenv("AAA")<<endl;
return 0;
}
[/code]
4. 进程空间
程序被装载到内存后展开成进程空间,先执行 _start 进行准备工作,如拷贝env 等,然后执行 main
| env 列表 ( 拷贝内核中的拥护env )
| 数据区: 全局,静态
进程 | 代码区(正文段):指令
空间 | 栈: 数据栈,代码栈
| 堆: 动态分配
| 表项(文件描述符表等)
5. 进程状态的切换
(1)Ctrl-Z, bg //先停下已经启动的进程然后放入后台
(2)Command & // 启动后自动进入后台
(3)fg // 回到前台
(4)stop pid
例子:
[code]
#include<iostream>
#include<unistd.h>
using namespace std;
void fn(){
pause();// 使调用进程停止
}
void fn1(){
fn();
}
void fn2(){
fn1();
}
int main(){
cout<<"hello, pid="<<getpid()<<endl;
fn2();
return 0;
}
//ctrl Z
//ps -al |grep pid
//bg
//ps -al |grep pid
//pstack pid //看进程栈 必须进程在pause状态
//fg
//ctrl C
[/code]
6. 用户信息操作函数
#include<pwd.h>
char* getlogin() // 得到用户登录名,不受su 影响
int getuid() // 得到当前登录用户的用户ID号,受su 影响
int geteuid() // 得到当前运行该进程的有效用户ID号,只有设置了用户标记位后结果才和getuid()不同,
// 设置了用户标记位后无论任何人执行该程序,用户身份都会变为所有者,如ping 命令
struct passwd * getpwuid( int userid ) // 得到一个指向passwd 结构的指针,该结构中包括用户相关信息记录,可用man查看该结构
例子:
[code]
#include<iostream>
#include<unistd.h>
#include<pwd.h>
using namespace std;
int main(){
int id=getuid();
struct passwd* p=NULL;
p=getpwuid( id );
if( p==NULL ){
cout<<"error"<<endl;
exit( -1 );
}
cout<<"name ="<<p->pw_name<<endl;
cout<<"uid ="<<p->pw_uid<<endl;
cout<<"gid ="<<p->pw_gid<<endl;
cout<<"dir ="<<p->pw_dir<<endl;
cout<<"shell ="<<p->pw_shell<<endl;
return 0;
}
[/code]
7. 组信息操作函数
意义同上
#include<grp.h>
int getgid();
int getegid();
struct group * getgrgid( int groupid );
例子:
[code]
#include<iostream>
#include<unistd.h>
#include<grp.h>
using namespace std;
int main(){
int gid=getgid();
struct group *p=NULL;
p=getgrgid( gid );
if( p==NULL ){
cout<<"error"<<endl;
exit( -1 );
}
cout<<"g_name ="<<p->gr_name<<endl;
cout<<"g_id ="<<p->gr_gid<<endl;
cout<<"--------------member------------"<<endl;
char** pm=p->gr_mem;
while( pm!=NULL && *pm!=NULL ){
cout<<*pm<<endl;;
pm++;
}
return 0;
}
[/code]
8. unix的目录
#include<unistd.h>
char* getcwd( char* buf, size_t size ); // size_t这个类型的在sys/types.h中,都可当做int型处理
例子:
[code]
#include<iostream>
#include<unistd.h>
#include<grp.h>
using namespace std;
int main(){
char buf[100];
memset( buf, 0x00, sizeof( buf ) );
cout<<"pwd=>"<<getcwd( buf, sizeof( buf ) )<<endl;
cout<< "buf=>"<<buf<<endl;
return 0;
}
[/code]
#include<sys/types.h>
#include<dirent.h>
DIR *opendir( const char *dirname ) // open directory
struct dirent * readdir( DIR * dirp ) // read direcotry
int closedir( DIR * dirp ) // close a direcotry
例子:
[code]
#include<iostream>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<dirent.h>
using namespace std;
int main(){
char name[ 100 ];
memset( name, 0x00, sizeof( name ) );
cout<<"enter a dir >";
cin>>name;
DIR * pd= opendir( name );
if( pd==NULL ){
cout<<strerror( errno )<<" ErrorCode["<<errno<<"]"<<endl;
exit( -1 );
}
struct dirent* pent=NULL;
while( 1 ){
pent= readdir( pd );
if( pent==NULL ){
break;
}
cout<<pent->d_name<<endl;
}
closedir( pd );
return 0;
}
[/code]
9. 文件与文件描述符
* 文件描述符( fd )是一个非负整数,一个fd对应一个打开的文件
* fd表在进程空间的内部,记录这个进程打开的所有文件, 一个fd指向一个文件表(包含:文件状态标记,当前位移量,V节点指针)
* 多次打开同一个文件会产生多个文件表,但V节点(包含:V节点信息,I节点信息,当前文件长度)只有一个
* fd 有系统内核产生,shell产生三个标准fd :0,1,2 对应于 cin,cout,cerr
* 打开一个文件
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int open( const char* pathname, int oflag, ... )
oflag为打开方式:
a. O_RDONLY | O_WRONLY | O_RDWR
b. O_APPAND
c. O_CREAT // 存在就打开,否则建一个
d. O_EXCL // 排它,有这个文件就报错,常与CREAT连用建一个新的
... 为可选,CREAT时必填,为权限
返回 fd
read/write 函数
size_t read( int fd, void *buf, size_t nbytes ) // 直接拷贝硬盘内容,返回实际读到的字节数,一般用于读二进制文件,文本的用c++的io
size_t write( int fd, void *buf, size_t nbytes )// 将buf中nbytes个字节写入fd,返回实际写入个数
例子:
[code]
#include<iostream>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
using namespace std;
int main(){
char name[100];
memset( name,0x00,sizeof( name ));
cout<<"enter a file name:";
cin>>name;
int fd=open( name, O_RDONLY );
int fd=open( "bg_test.cc", O_RDONLY );
if ( fd < 0 ){
cout<<"open file error "<<endl;
exit( -1 );
}
char buf[ 10 ];
int len=0;
while( 1 ){
memset( buf,0,sizeof( buf ) );
len=read( fd,buf,sizeof(buf) );
if( len<=0 ) break;
cout<<buf<<endl;
}
close( fd );
return 0;
}
#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
using namespace std;
int main(){
char name[100];
memset( name,0x00,sizeof( name ));
cout<<"enter a file name:";
cin>>name;
int fd=open(name,O_CREAT|O_WRONLY|O_APPEND,0755);
if( fd<0 ){
cout<<"error"<<endl;
exit( -1 );
}
char buf[100];
cin.ignore( 255,'\n' );
while( 1 ){
memset( buf, 0x00, sizeof( buf ) );
cout<<"enter a line>";
cin.getline( buf, sizeof( buf ) );
if( strcmp( buf,"bye" )==0 ) break;
write( fd, buf, strlen( buf ) );
}
close( fd );
}
[/code]
10. lseek 函数
#include<sys/types.h>
#include<unistd.h>
off_t lseek( int fd, off-t offset, int whence )
whence 为从哪开始:
a. SEEK_SET: 文件头
b. SEEK_CUR:当前位置
c. SEEK_END: 文件尾
例子:
[code]
#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
using namespace std;
int main(){
int fd=open("lseek_sample.txt", O_WRONLY | O_CREAT, 0777 );
if( fd<0 ){
cout<<"error"<<endl;
exit( -1 );
}
write( fd, "hello", strlen("hello") );
lseek( fd, 100, SEEK_CUR );
write( fd, "world", strlen("world") );
close( fd );
return 0;
}
[/code]
11. 复制 fd
int dup( int fd );
int dup2( int fd1, int fd2 );// 将 fd1 复制到 fd2 上
例子:
[code]
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/stat.h>
using namespace std;
int main(){
int fd=open( "dup.txt", O_RDWR | O_CREAT, 0777 );
if( fd< 0 ){
cout<<"error";
exit( -1 );
}
dup2( fd,1 );
cout<<"hello world "<<endl;
cout<<"have a nice day "<<endl;
return 0;
}
[/code]
12. 在程序中获得文件的属性
#include<sys/types.h>
#include<sys/stat.h>
int stat( const char * pathname, struct stat * buf ); // 用man 查看 struct stat 结构
int fstat( int fd, struct stat * buf );
int lstat( const char* pathname, struct stat * buf );
* 文件类型判别宏:
a. S_ISREG() // 普通文件
b. S_ISDIR() // 目录文件
c. S_ISCHR() // 字符特殊文件
d. S_ISBLK() // 块特殊文件
e. S_ISFIFO() // FIFO管道文件
f. S_ISLINK() // 连接文件
g. S_ISSOCK() // socket文件
* 文件属性与权限
stat.st_mode 和下面的 &
S_IRUSR | S_IWUSR | S_IXUSR // is read user
S_IRGRP | S_IWGRP | S_IXGRP // is read group
S_IROTH | S_IWOTH | S_IXOTH // is read other
例子:
[code]
#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
using namespace std;
int main(){
char name[100];
memset( name,0x00,sizeof( name ) );
cout<<"enter a file name >";
cin>>name;
struct stat s;
memset ( &s, 0x00, sizeof( s ) );
int ret=stat( name, &s );
if( ret ){
cout<<"error"<<endl;
}
cout<<"uid ="<<s.st_uid<<endl;
cout<<"group ="<<s.st_gid<<endl;
cout<<"size ="<<s.st_size<<endl;
cout<<"ctime ="<<s.st_ctime<<endl;
cout<<"mtime ="<<s.st_mtime<<endl;
cout<<"atime ="<<s.st_atime<<endl;
cout<<"mode ="<<s.st_mode<<endl;
if( S_ISREG( s.st_mode ) )
cout<<"regular file"<<endl;
else if( S_ISDIR( s.st_mode ) )
cout<<"directory file"<<endl;
else if( S_ISFIFO( s.st_mode ) )
cout<<"pipe file"<<endl;
else cout<<"other file"<<endl;
cout<<"----------------------- "<<endl;
if( s.st_mode & S_IRUSR )
cout<<"user can read"<<endl;
else
cout<<"user can not read"<<endl;
if( s.st_mode & S_IWUSR )
cout<<"user can write"<<endl;
else
cout<<"user can't write"<<endl;
if( s.st_mode & S_IXUSR )
cout<<"user can execute"<<endl;
else
cout<<"user can't execute"<<endl;
return 0;
}
[/code]