博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程&信号&管道实践学习记录
阅读量:5921 次
发布时间:2019-06-19

本文共 21785 字,大约阅读时间需要 72 分钟。

程序分析

exec1.c & exect2.c & exect3.c

程序代码 (以exect1.c为例,其他两个结构类似)

#include 
#include
int main(){ char *arglist[3]; arglist[0] = "ls"; arglist[1] = "-l"; arglist[2] = 0 ;//NULL printf("* * * About to exec ls -l\n"); execvp( "ls" , arglist ); printf("* * * ls is done. bye"); return 0;}

运行结果:

745844-20151127153303718-227666310.png
结果显示代码“* * * ls is done. bye”没有打印出来。

原因:因为调用execvp,execlp,execv时,内核将新程序载入到当前进程,替代当前进程的代码和数据。

forkdemo1.c

程序代码:

#include    
#include
#include
int main(){ int ret_from_fork, mypid; mypid = getpid(); printf("Before: my pid is %d\n", mypid); ret_from_fork = fork(); sleep(1); printf("After: my pid is %d, fork() said %d\n", getpid(), ret_from_fork); return 0;}

运行结果:

745844-20151127194806124-620731673.png

分析:fork()在父进程中返回子进程的pid,在子进程中返回0。

forkdemo2.c

程序代码:

#include 
#include
int main(){ printf("before:my pid is %d\n", getpid() ); fork(); fork(); printf("aftre:my pid is %d\n", getpid() ); return 0;}

运行结果:

745844-20151127195002202-380479599.png

分析:两次fork()共产生3个子进程,加上父进程总共有4个进程。

forkdemo3.c

程序代码:

#include    
#include
#include
int main(){ int fork_rv; printf("Before: my pid is %d\n", getpid()); fork_rv = fork(); /* create new process */ if ( fork_rv == -1 ) /* check for error */ perror("fork"); else if ( fork_rv == 0 ){ printf("I am the child. my pid=%d\n", getpid()); exit(0); } else{ printf("I am the parent. my child is %d\n", fork_rv); exit(0); } return 0;}

运行效果:

745844-20151127195107468-736657186.png

forkdemo4.c

程序代码:

#include    
#include
#include
int main(){ int fork_rv; printf("Before: my pid is %d\n", getpid()); fork_rv = fork(); /* create new process */ if ( fork_rv == -1 ) /* check for error */ perror("fork"); else if ( fork_rv == 0 ){ printf("I am the child. my pid=%d\n", getpid()); printf("parent pid= %d, my pid=%d\n", getppid(), getpid()); exit(0); } else{ printf("I am the parent. my child is %d\n", fork_rv); sleep(10); exit(0); } return 0;}

运行结果:

745844-20151127195221577-339783291.png

forkgdb.c

程序代码:

#include 
#include
#include
int gi=0;int main(){ int li=0; static int si=0; int i=0; pid_t pid = fork(); if(pid == -1){ exit(-1); } else if(pid == 0){ for(i=0; i<5; i++){ printf("child li:%d\n", li++); sleep(1); printf("child gi:%d\n", gi++); printf("child si:%d\n", si++); } exit(0); } else{ for(i=0; i<5; i++){ printf("parent li:%d\n", li++); printf("parent gi:%d\n", gi++); sleep(1); printf("parent si:%d\n", si++); } exit(0); } return 0;}

运行效果:

745844-20151127195354952-718176510.png

分析:运行结果说明了子进程与父进程并发运行。

psh1.c

#include    
#include
#include
#include
#define MAXARGS 20 #define ARGLEN 100 //将字符串内容当做命令来执行。int execute( char *arglist[] ){ execvp(arglist[0], arglist); perror("execvp failed"); exit(1);}char * makestring( char *buf ){ char *cp; buf[strlen(buf)-1] = '\0'; cp = malloc( strlen(buf)+1 ); if ( cp == NULL ){ fprintf(stderr,"no memory\n"); exit(1); } strcpy(cp, buf); return cp; }int main(){ char *arglist[MAXARGS+1]; int numargs; char argbuf[ARGLEN]; numargs = 0; while ( numargs < MAXARGS ) { printf("Arg[%d]? ", numargs); if ( fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n' ) arglist[numargs++] = makestring(argbuf); else { if ( numargs > 0 ){ arglist[numargs]=NULL; execute( arglist ); //将arglist中的字符串当做命令来执行。 numargs = 0; } } } return 0;}

运行结果:

745844-20151128095413343-1844463668.png

程序功能:输入字符串并将其当做命令执行。

psh2.c

程序代码:

#include    
#include
#include
#include
#include
#include
#include
#define MAXARGS 20 #define ARGLEN 100 char *makestring( char *buf ){ char *cp; buf[strlen(buf)-1] = '\0'; cp = malloc( strlen(buf)+1 ); if ( cp == NULL ){ fprintf(stderr,"no memory\n"); exit(1); } strcpy(cp, buf); return cp; }void execute( char *arglist[] ){ int pid,exitstatus; pid = fork(); switch( pid ){ case -1: perror("fork failed"); exit(1); case 0: execvp(arglist[0], arglist); perror("execvp failed"); exit(1); default: while( wait(&exitstatus) != pid ) ; printf("child exited with status %d,%d\n", exitstatus>>8, exitstatus&0377); }}int main(){ char *arglist[MAXARGS+1]; int numargs; char argbuf[ARGLEN]; numargs = 0; while ( numargs < MAXARGS ) { printf("Arg[%d]? ", numargs); if ( fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n' ) arglist[numargs++] = makestring(argbuf); else { if ( numargs > 0 ){ arglist[numargs]=NULL; execute( arglist ); numargs = 0; } } } return 0;}

运行结果:

745844-20151128101327562-1467319093.png

程序功能:不断产生新的子进程输入字符串命令。

testbuf1

程序代码:

#include 
#include
int main(){ printf("hello"); fflush(stdout); while(1);}

运行效果:

745844-20151128102505577-27214552.png

testbuf2

程序代码:

#include 
int main(){ printf("hello\n"); while(1);}

运行效果:

745844-20151128102455765-1396989428.png

testbuf3

程序代码:

#include 
int main(){ fprintf(stdout, "1234", 5); fprintf(stderr, "abcd", 4);}

运行效果:

745844-20151128103508452-1466321224.png

分析:在默认情况下,stdout是行缓冲的,他的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。而stderr是无缓冲的,会直接输出。所以输出结果为:abcd1234

testpid.c

程序代码:

#include 
#include
#include
int main(){ printf("my pid: %d \n", getpid());//获取当前进程pid printf("my parent's pid: %d \n", getppid());//获取当前进程父进程pid return 0;}

运行效果:

745844-20151128104057671-461329665.png

testpp.c

程序代码:

#include 
#include
int main(){ char **pp; pp[0] = malloc(20); return 0;}

运行效果:

745844-20151128203105266-1076405401.png

testsystem.c

程序代码:

#include    
int main ( int argc, char *argv[] ){ system(argv[1]); system(argv[2]); return EXIT_SUCCESS;}
  • system函数:

system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。 返回值 =-1:出现错误 =0:调用成功但是没有出现子进程 >0:成功退出的子进程的id 如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值>。如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。

运行效果:

745844-20151128204045688-899722657.png

waitdemo1.c

程序代码:

#include    
#include
#include
#include
#include
#define DELAY 4void child_code(int delay){ printf("child %d here. will sleep for %d seconds\n", getpid(), delay); sleep(delay); printf("child done. about to exit\n"); exit(17);}void parent_code(int childpid){ int wait_rv=0; /* return value from wait() */ wait_rv = wait(NULL);//子进程成功结束返回子进程PID,没有子进程则返回-1。 printf("done waiting for %d. Wait returned: %d\n", childpid, wait_rv);}int main(){ int newpid; printf("before: mypid is %d\n", getpid()); if ( (newpid = fork()) == -1 ) perror("fork"); else if ( newpid == 0 ) child_code(DELAY); else parent_code(newpid); return 0;}

运行效果:

745844-20151128205051172-574816244.png

waitdemo2.c

程序代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define DELAY   10void child_code(int delay){    printf("child %d here. will sleep for %d seconds\n", getpid(), delay);    sleep(delay);    printf("child done. about to exit\n");    exit(27);}void parent_code(int childpid){    int wait_rv;        int child_status;    int high_8, low_7, bit_7;    wait_rv = wait(&child_status);    printf("done waiting for %d. Wait returned: %d\n", childpid, wait_rv);    high_8 = child_status >> 8;     /* 1111 1111 0000 0000 */    low_7  = child_status & 0x7F;   /* 0000 0000 0111 1111 */    bit_7  = child_status & 0x80;   /* 0000 0000 1000 0000 */    printf("status: exit=%d, sig=%d, core=%d\n", high_8, low_7, bit_7);}int main(){    int  newpid;    printf("before: mypid is %d\n", getpid());    if ( (newpid = fork()) == -1 )        perror("fork");    else if ( newpid == 0 )        child_code(DELAY);    else        parent_code(newpid);}

运行结果:

745844-20151128205739844-538731402.png

argtest.c

程序代码:

#include 
#include
#include "argv.h"int main(int argc, char *argv[]) {char delim[] = " \t";int i;char **myargv; int numtokens; if (argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); return 1;} if ((numtokens = makeargv(argv[1], delim, &myargv)) == -1) { fprintf(stderr, "Failed to construct an argument array for %s\n", argv[1]); return 1;} printf("The argument array contains:\n");for (i = 0; i < numtokens; i++) printf("%d:%s\n", i, myargv[i]); execvp(myargv[0], myargv); return 0;}

功能:将输入字符串当做系统命令执行。

运行结果:

745844-20151128210413047-69598019.png

environ.c

程序代码:

#include 
#include
int main(void){ printf("PATH=%s\n", getenv("PATH")); setenv("PATH", "hello", 1); printf("PATH=%s\n", getenv("PATH"));#if 0 printf("PATH=%s\n", getenv("PATH")); setenv("PATH", "hellohello", 0); printf("PATH=%s\n", getenv("PATH")); printf("MY_VER=%s\n", getenv("MY_VER")); setenv("MY_VER", "1.1", 0); printf("MY_VER=%s\n", getenv("MY_VER")); #endif return 0;}

运行效果:

745844-20151128211330547-1569434906.png

environvar.c

运行代码:

#include 
int main(void){ extern char **environ; int i; for(i = 0; environ[i] != NULL; i++) printf("%s\n", environ[i]); return 0;}

功能:打印环境变量。

运行效果:

745844-20151128211910953-516606592.png

sigactdemo.c

程序代码:

#include    
#include
#include
#define INPUTLEN 100void inthandler(); int main(){ struct sigaction newhandler; sigset_t blocked; char x[INPUTLEN]; newhandler.sa_handler = inthandler;//新的信号处理函数效果与signal()类似 newhandler.sa_flags = SA_RESTART|SA_NODEFER |SA_RESETHAND;//设置信号处理相关操作 sigemptyset(&blocked); //将blocked信号集初始化,并清空。 sigaddset(&blocked, SIGQUIT);//将SIGQUIT信号加入参数blocked信号集。 newhandler.sa_mask = blocked;//暂时将block信号阻塞 if (sigaction(SIGINT, &newhandler, NULL) == -1) perror("sigaction"); else while (1) { fgets(x, INPUTLEN, stdin); printf("input: %s", x); } return 0;}void inthandler(int s){ printf("Called with signal %d\n", s); sleep(s * 4); printf("done handling signal %d\n", s);}

sigation结构体:

struct sigaction {void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *,  void *);sigset_t sa_mask;int sa_flags;void (*sa_restorer)(void);}
  • sa_handler此参数和signal()的参数handler相同,代表新的信号处理函数,其他意义请参考signal()。
  • sa_mask 指定在信号处理程序执行过程中,哪些信号应当被阻塞。默认当前信号本身被阻塞。
  • sa_restorer 已过时,POSIX不支持它,不应再使用。
  • sa_flags 用来设置信号处理的其他相关操作,下列的数值可用。
  • sa_flags还可以设置其他标志:
    • SA_RESETHAND:当调用信号处理函数时,将信号的处理函数重置为缺省值SIG_DFL
    • SA_RESTART:如果信号中断了进程的某个系统调用,则系统自动启动该系统调用
    • SA_NODEFER :一般情况下, 当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号

运行效果:

745844-20151129102010782-1040850181.png

sigactdemo2.c

#include 
#include
#include
void sig_alrm( int signo ){ /*do nothing*/}unsigned int mysleep(unsigned int nsecs){ struct sigaction newact, oldact; unsigned int unslept; newact.sa_handler = sig_alrm;//设置处理函数 sigemptyset( &newact.sa_mask );//清空newact的阻塞信号集 newact.sa_flags = 0;//设置信号处理的其它操作为空 sigaction( SIGALRM, &newact, &oldact );//显式取消阻塞信号 alarm( nsecs );//设置闹钟 pause(); unslept = alarm ( 0 );//取消闹钟,并返回剩余时间 sigaction( SIGALRM, &oldact, NULL ); return unslept;}int main( void ){ while( 1 ) { mysleep( 2 ); printf( "Two seconds passed\n" ); } return 0;}

运行效果:

745844-20151129104516797-1915056884.png

sigdemo1.c

#include    
#include
void f(int); int main(){ int i; signal( SIGINT, f );//改变键盘ctril+C处理函数 for(i=0; i<5; i++ ){ printf("hello\n"); sleep(2); } return 0;}void f(int signum) { printf("OUCH!\n");}

运行效果:

745844-20151129104955047-1216409064.png

sigdemo2.c

#include    
#include
main(){ signal( SIGINT, SIG_IGN );//设置忽略Ctrl+C中断信号。 printf("you can't stop me!\n"); while( 1 ) { sleep(1); printf("haha\n"); }}

运行效果:

745844-20151129201225782-1794176140.png

sigdemo3.c

程序代码:

#include    
#include
#include
#include
#define INPUTLEN 100int main(int argc, char *argv[]){ void inthandler(int); void quithandler(int); char input[INPUTLEN]; int nchars; signal(SIGINT, inthandler);//^C signal(SIGQUIT, quithandler);//^\ do { printf("\nType a message\n"); nchars = read(0, input, (INPUTLEN - 1)); if (nchars == -1) perror("read returned an error"); else { input[nchars] = '\0'; printf("You typed: %s", input); } } while (strncmp(input, "quit", 4) != 0); return 0;}void inthandler(int s){ printf(" Received signal %d .. waiting\n", s); sleep(2); printf(" Leaving inthandler \n");}void quithandler(int s){ printf(" Received signal %d .. waiting\n", s); sleep(3); printf(" Leaving quithandler \n");}

运行效果:

745844-20151129202158391-1583747850.png

listargs.c

程序代码

#include    
main( int ac, char *av[] ){ int i; printf("Number of args: %d, Args are:\n", ac);//ac为传入参数的个数。 for(i=0;i

运行效果:

745844-20151129210733907-1075397495.png
745844-20151201142811468-1476715150.png

pipe.c

#include    
#include
#include
#define oops(m,x) { perror(m); exit(x); }int main(int ac, char **av){ int thepipe[2], newfd, pid; //判断管道输入格式是否正确 if ( ac != 3 ){ fprintf(stderr, "usage: pipe cmd1 cmd2\n"); exit(1); } //管道建立失败,输出错误信息 if ( pipe( thepipe ) == -1 ) oops("Cannot get a pipe", 1); //子进程创建失败,输出错误信息 if ( (pid = fork()) == -1 ) oops("Cannot fork", 2); if ( pid > 0 ){ close(thepipe[1]); if ( dup2(thepipe[0], 0) == -1 )//将thepipe[0]重定向到标准输入 oops("could not redirect stdin",3); close(thepipe[0]); execlp( av[2], av[2], NULL);//试着执行av[2]中的命令 oops(av[2], 4); } close(thepipe[0]); if ( dup2(thepipe[1], 1) == -1 )//将thepipe[1]重定向到标准输出 oops("could not redirect stdout", 4); close(thepipe[1]); execlp( av[1], av[1], NULL);//试着执行av[1]中的命令 oops(av[1], 5);}
  • pipe():

    1) 头文件 #include<unistd.h>

    2) 定义函数: int pipe(int filedes[2]);

    3) 函数说明: pipe()会建立管道,并将文件描述词由参数filedes数组返回。

    filedes[0]为管道里的读取端
    filedes[1]则为管道的写入端。

    4) 返回值: 若成功则返回零,否则返回-1,错误原因存于errno中。

execlp():

从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针,则必须将它强制转换为一个字符指针,否则将它解释为整形参数,如果一个整形数的长度与char * 的长度不同,那么exec函数的实际参数就将出错。如果函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了。

返回值:

如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。

运行效果:

745844-20151129211220188-1540456681.png

pipedemo2.c

#include    
#include
#include
#include
#define CHILD_MESS "I want a cookie\n"#define PAR_MESS "testing..\n"#define oops(m,x) { perror(m); exit(x); }main(){ int pipefd[2]; int len; char buf[BUFSIZ]; int read_len; if ( pipe( pipefd ) == -1 ) oops("cannot get a pipe", 1); switch( fork() ){ case -1: oops("cannot fork", 2); case 0: len = strlen(CHILD_MESS); while ( 1 ){ if (write( pipefd[1], CHILD_MESS, len) != len ) oops("write", 3); sleep(5); } default: len = strlen( PAR_MESS ); while ( 1 ){ if ( write( pipefd[1], PAR_MESS, len)!=len ) oops("write", 4); sleep(1); read_len = read( pipefd[0], buf, BUFSIZ ); if ( read_len <= 0 ) break; write( 1 , buf, read_len ); } }}

运行结果:

745844-20151129212811266-310459137.png

pipedemo.c

#include    
#include
#include
#include
int main(){ int len, i, apipe[2]; char buf[BUFSIZ]; if ( pipe ( apipe ) == -1 ){ perror("could not make pipe"); exit(1); } printf("Got a pipe! It is file descriptors: { %d %d }\n", apipe[0], apipe[1]); while ( fgets(buf, BUFSIZ, stdin) ){ len = strlen( buf ); if ( write( apipe[1], buf, len) != len ){ perror("writing to pipe"); break; } for ( i = 0 ; i

运行结果:

745844-20151201155424452-475356513.png

stdinerdir1.c

程序代码:

#include    
#include
int main(){ int fd ; char line[100]; fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); close(0); fd = open("/etc/passwd", O_RDONLY);//读取passwd文件到stdin if ( fd != 0 ){ fprintf(stderr,"Could not open data as fd 0\n"); exit(1); } fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line );}

745844-20151201153212358-2012384718.png

stdinredir2.c

#include        
#include
#include
//#define CLOSE_DUP //#define USE_DUP2 main(){ int fd ; int newfd; char line[100]; fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fd = open("data", O_RDONLY); #ifdef CLOSE_DUP close(0); newfd = dup(fd); #else newfd = dup2(fd,0); //将fd重定向到标准输入 #endif if ( newfd != 0 ){ fprintf(stderr,"Could not duplicate fd to 0\n"); exit(1); } close(fd); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line );}

运行效果:(没有data文件,无法获取文件描述符,重定向失败)

745844-20151201153845312-1294095476.png

testtty.c

#include 
int main(){ char *buf = "abcde\n"; write(0, buf, 6);//将字符串写到标准输入}

运行效果:

745844-20151201155010421-1867420015.png

whotofile.c

#include    
#include
#include
int main(){ int pid ; int fd; printf("About to run who into a file\n"); if( (pid = fork() ) == -1 ){ perror("fork"); exit(1); } if ( pid == 0 ){ close(1); /* close, */ fd = creat( "userlist", 0644 ); /* then open *///以写的方式创建一个文件,因为前面关闭了文件描述符1,所以fd=1,为标准输出。 execlp( "who", "who", NULL ); /* and run *///执行who命令,输出到文件表描述符1中。 perror("execlp"); exit(1); } if ( pid != 0 ){ wait(NULL); printf("Done running who. results in userlist\n"); } return 0;}

运行结果:

745844-20151201160937718-500579669.png

consumer.c

#include 
#include
#include
#include
#include
#include
#include
#define FIFO_NAME "/tmp/myfifo"#define BUFFER_SIZE PIPE_BUFint main(){ int pipe_fd; int res; int open_mode = O_RDONLY; char buffer[BUFFER_SIZE + 1]; int bytes = 0; memset(buffer, 0, sizeof(buffer));//数组置零 printf("Process %d opeining FIFO O_RDONLY \n", getpid()); pipe_fd = open(FIFO_NAME, open_mode); printf("Process %d result %d\n", getpid(), pipe_fd); if (pipe_fd != -1) { do { res = read(pipe_fd, buffer, BUFFER_SIZE); bytes += res; } while (res > 0); close(pipe_fd); } else { exit(EXIT_FAILURE); } printf("Process %d finished, %d bytes read\n", getpid(), bytes); exit(EXIT_SUCCESS);}

运行效果:

文件不存在,打开失败。

745844-20151201162131608-573644807.png

文件存在读取成功。

745844-20151201185616562-221302385.png

producer.c

程序代码:

#include 
#include
#include
#include
#include
#include
#include
#define FIFO_NAME "/tmp/myfifo"#define BUFFER_SIZE PIPE_BUF#define TEN_MEG (1024 * 1024 * 10)int main(){ int pipe_fd; int res; int open_mode = O_WRONLY; int bytes = 0; char buffer[BUFFER_SIZE + 1]; //判断文件是否存在。 if (access(FIFO_NAME, F_OK) == -1) { res = mkfifo(FIFO_NAME, 0777);//创建一个FIFO文件 if (res != 0) { fprintf(stderr, "Could not create fifo %s \n", FIFO_NAME); exit(EXIT_FAILURE); } } printf("Process %d opening FIFO O_WRONLY\n", getpid()); pipe_fd = open(FIFO_NAME, open_mode); printf("Process %d result %d\n", getpid(), pipe_fd); if (pipe_fd != -1) { while (bytes < TEN_MEG) { res = write(pipe_fd, buffer, BUFFER_SIZE); if (res == -1) { fprintf(stderr, "Write error on pipe\n"); exit(EXIT_FAILURE); } bytes += res; } close(pipe_fd); } else { exit(EXIT_FAILURE); } printf("Process %d finish\n", getpid()); exit(EXIT_SUCCESS);}

access():

判断是否具有存取文件的权限

相关函数
stat,open,chmod,chown,setuid,setgid
表头文件
#include<unistd.h>
定义函数
int access(const char * pathname, int mode);
函数说明
access()会检查是否可以读/写某一已存在的文件。参数mode有几种情况组合:
R_OK,W_OK,X_OK 和F_OK。
R_OK,W_OK与X_OK用来检查文件是否具有读取、写入和执行的权限。
F_OK则是用来判断该文件是否存在。由于access()只作权限的核查,并不理会文件形态或文件内容,因此,如果一目录表示为“可写入”,表示可以在该目录中建立新文件等操作,而非意味此目录可以被当做文件处理。例如,你会发现DOS的文件都具有“可执行”权限,但用execve()执行时则会失败。
返回值
若所有欲查核的权限都通过了检查则返回0值,表示成功,只要有一权限被禁止则返回-1。

mkfifo()

mkfifo函数的作用是在文件系统中创建一个文件(该文件之前必须不存在),该文件用于提供FIFO功能,即命名管道。前边讲的那些管道都没有名字,因此它们被称为匿名管道,或简称管道。

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo( const char *pathname, mode_t mode );
mkfifo函数需要两个参数,第一个参数(pathname)是将要在文件系统中创建的一个专用文件。第二个参数(mode)用来规定FIFO的读写权限。Mkfifo函数如果调用成功的话,返回值为0;如果调用失败返回值为-1。

运行结果:

745844-20151201193746968-996722488.png

遇到的问题及解决

1.sigactdemo.c中的inthandler中的参数int s是怎么传进去的?

745844-20151129101523407-567694060.png

解决方法:在博客园提问。

inthandler被当做函数指针传给了newhandler.sa_handler

后面调用int sigaction(int signum,const struct sigaction act ,struct sigaction oldact);
它的第一个参数signum指定的信号编号就是用来设置这个信号的处理函数的。信号SIGINT序号为2。

命令kill -l可以查看各信号的序号。

2.运行testpp时遇到段错误(核心已转储)。

745844-20151128105620234-2106060315.png

解决方法:在博客园提问。

二维数组越界申请空间。

将代码改为

pp=malloc(20);

即可编译成功。

参考资料

《深入理解计算机系统》第8章异常控制流

转载于:https://www.cnblogs.com/Ntime/p/5005432.html

你可能感兴趣的文章
Toad for MySQL 7.7 Freeware设置
查看>>
高性能的数据库一体机:Oracle Exadata
查看>>
exchange 2010 OAB的设置
查看>>
Spring自动绑定@Repsity@Service@Controller
查看>>
使用GRE使组播穿越非组播网络
查看>>
CloudStack(一)简介及相关理论介绍
查看>>
我的友情链接
查看>>
编程题:指向变量的指针变量
查看>>
国内首家免费企业级私有镜像库 有容云AppHouse震撼来袭
查看>>
xampp下新增virtualhost出现access denied
查看>>
查看端口号是否占用
查看>>
软件外包中国发展服务外包独具优势
查看>>
四川移动官网被黑 网友担忧他人被骗
查看>>
windows8企业版应用商店 窗口拖动靠边
查看>>
精品软件 推荐 免费的PDF 阅读 软件 福昕阅读器
查看>>
How To Use Linux epoll with Python
查看>>
win下安装AnyProxy
查看>>
油猴【QQ音乐付费音乐流畅版本下载】
查看>>
IE 支持 margin: 0 auto;
查看>>
Linux命令之kill
查看>>