GVKun编程网logo

Unix/Linux编程实践教程–chmod在Centos7.3的实现(chmod linux)

6

本文将分享Unix/Linux编程实践教程–chmod在Centos7.3的实现的详细内容,并且还将对chmodlinux进行详尽解释,此外,我们还将为大家带来关于centos是linux还是unix

本文将分享Unix/Linux编程实践教程–chmod在Centos7.3的实现的详细内容,并且还将对chmod linux进行详尽解释,此外,我们还将为大家带来关于centos是linux还是unix、I/O 重定向和管道 ——《Unix/Linux 编程实践教程》读书笔记(第 10 章)、I/O重定向和管道——《Unix/Linux编程实践教程》读书笔记(第10章)、Linux CentOS 7 & Tengine(Nginx)安装与配置 centos7下载 centos7官网 centos7桌的相关知识,希望对你有所帮助。

本文目录一览:

Unix/Linux编程实践教程–chmod在Centos7.3的实现(chmod linux)

Unix/Linux编程实践教程–chmod在Centos7.3的实现(chmod linux)

环境:centos 7.3 x86_64

如果搜一下man就会发现,里面有两个chmod,一个是chmod(1),一个是chmod(2)。根据牛顿-莱布尼兹公式,立即推,第一个是用户命令,第二个是系统调用。系统调用里,函数的原型是这样的:

int chmod(const char *pathname,mode_t mode);

所以要实现的chmod命令,无非就是把用户的输入解释成对应的mode_t类型,然后交给chmod系统调用进行处理即可。

目标,支持符号和八进制数两种表示法。符号表示法仅支持[ugoa...][+-=][rwxst...]。八进制表示法支持1-4位八制数,没有设置的位默认为0,同man 1 chmod一致。

Usage: chmod mode file...

程序流程大概是这样的:

  1. 解析mode
  2. 对于每个文件调用chmod进行设置或修改

代码大概是这样的,用了一些位操作去减少代码的长度:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

void oops(const char* str);
mode_t parse_mode(const char *mode);
void xc_chmod(const char *path,mode_t mode);
mode_t modify_mode(mode_t mode);

#define USAGE "Usage: chmod mode file...\n"

enum{
    CW_ADD,CW_REMOVE,CW_SET,CW_COVER
}chmod_way;
enum{
    MOD_READ = 0444,MOD_WRITE = 0222,MOD_EXEC = 0111,};
enum{
    ER_ALL = 0777,ER_USR = 0700,ER_GRP = 070,ER_OTH = 07
}effect_range = 0;

int mode_read = 0;
int mode_write = 0; 
int mode_exec = 0;
int mode_sgid = 0;
int mode_sticky = 0;

int main(int ac,char *av[])
{
    mode_t mode;
    if(ac < 3){
        fprintf(stderr,USAGE);
        exit(1);
    }
    mode = parse_mode(*++av);
    ac -= 2;
    while(ac--)
        xc_chmod(*++av,mode);
    return 0;
}
void xc_chmod(const char *path,mode_t mode)
{
    struct stat info;
    if(chmod_way != CW_COVER){
        if(stat(path,&info) == -1)
            oops("chmod");
        mode = info.st_mode;
        mode = modify_mode(mode);   
    }
    if(chmod(path,mode) == -1)
            oops("chmod");
}
mode_t modify_mode(mode_t mode)
{
    mode_t amode = mode;
    int add_or_remove;
    if(chmod_way == CW_SET)
    {
        if(mode_read){
            // printf("MODE_READ: %o & effect_range: %o = %o\n",MOD_READ,effect_range,MOD_READ& effect_range);
            amode |= MOD_READ & effect_range;
        }
        if(mode_write)
            amode |= MOD_WRITE & effect_range;
        if(mode_exec)
            amode |= MOD_EXEC & effect_range;

        if(mode_sgid){
            if(effect_range & ER_USR)
                amode |= S_ISUID;
            if(effect_range & ER_GRP)
                amode |= S_IsgiD;
        }
        if(mode_sticky  && (effect_range & ER_OTH))
            amode |= S_ISVTX;
    }else{
        add_or_remove = chmod_way == CW_ADD;

        if(mode_read)
            if(add_or_remove)
                amode |= MOD_READ & effect_range;
            else
                amode &= ~(MOD_READ & effect_range);
        if(mode_write)
            if(add_or_remove)
                amode |= MOD_WRITE & effect_range;
            else
                amode &= ~(MOD_WRITE & effect_range);
        if(mode_exec)
            if(add_or_remove)
                amode |= MOD_EXEC & effect_range;
            else
                amode &= ~(MOD_EXEC & effect_range);

        if(mode_sgid){
            if(effect_range & ER_USR)
                if(add_or_remove)
                    amode |= S_ISUID;
                else
                    amode &= ~S_ISUID;

            if(effect_range & ER_GRP)
                if(add_or_remove)
                    amode |= S_IsgiD;
                else
                    amode &= ~S_IsgiD;

        }
        if(mode_sticky && (effect_range & ER_OTH))
            if(add_or_remove)
                amode |= S_ISVTX;
            else
                amode &= ~S_ISVTX;
    }
    return amode;
}
mode_t parse_mode(const char *mode)
{
    char *p;
    mode_t amode;
    if(mode[0] >= '0' && mode[0] <= '9'){
        /* parse use oct digits */
        int len = 0;
        int base = 1;
        int tmp = 0;
        int i;
        int legal = 1;
        p = mode;
        while(*p){
            if(!(*p >= '0' && *p <= '7'))
                legal = 0;
            p++;
            len++;
        }
        if(len > 4)
            legal = 0;
        if(!legal){
            fprintf(stderr,USAGE);
            exit(1);
        }
        sscanf(mode,"%o",&tmp);
        amode = tmp;
        chmod_way = CW_COVER;
    }else{
        /* parse use symbolic */
        p = mode;
        while(*p != '+' && *p != '-' && *p != '='){
            switch(*p){
                case 'a':
                    effect_range |= ER_ALL;
                    break;
                case 'g':
                    effect_range |= ER_GRP;
                    break;
                case 'o':
                    effect_range |= ER_OTH;
                    break;
                case 'u':
                    effect_range |= ER_USR;
                    break;
                default:
                    fprintf(stderr,USAGE);
                    exit(1);
                    break;
            }
            p++;
        }
        switch(*p){
            case '+':
                chmod_way = CW_ADD;
                break;
            case '-':
                chmod_way = CW_REMOVE;
                break;
            case '=':
                chmod_way = CW_SET;
                break;
            default:
                fprintf(stderr,USAGE);
                exit(1);
                break;
        }
        p++;
        while(*p){
            switch(*p){
                case 'r':
                    mode_read = 1;
                    break;
                case 'w':
                    mode_write = 1;
                    break;
                case 'x':
                    mode_exec = 1;
                    break;
                case 's':
                    mode_sgid = 1;
                    break;
                case 't':
                    mode_sticky = 1;
                    break;
                default:
                    fprintf(stderr,USAGE);
                    exit(1);
                    break;
            }
            ++p;
        }
    }
    return amode;
}
void oops(const char* str)
{
    perror(str);
    exit(1);
}

效果:

测试脚本:

gcc chmod.c

./a.out 7777 aaa
ls -l aaa > bbb
./a.out 644 aaa
ls -l aaa >> bbb
./a.out 0000 aaa
ls -l aaa >> bbb
./a.out u=rwxst aaa
ls -l aaa >> bbb
./a.out g=rwxst aaa
ls -l aaa >> bbb
./a.out o=rwxst aaa
ls -l aaa >> bbb
./a.out 0000 aaa
ls -l aaa >> bbb
./a.out a=rwxst aaa
ls -l aaa >> bbb
./a.out 0000 aaa
ls -l aaa >> bbb
./a.out a=rw aaa
ls -l aaa >> bbb
./a.out 0000 aaa
ls -l aaa >> bbb
./a.out ug=rw aaa
ls -l aaa >> bbb
./a.out o+rw aaa
ls -l aaa >> bbb
./a.out u+x aaa
ls -l aaa >> bbb
./a.out u+s aaa
ls -l aaa >> bbb
./a.out u-x aaa
ls -l aaa >> bbb
./a.out a-r aaa
ls -l aaa >> bbb
./a.out a+t aaa
ls -l aaa >> bbb

chmod 7777 aaa
ls -l aaa > ccc
chmod 644 aaa
ls -l aaa >> ccc
chmod 0000 aaa
ls -l aaa >> ccc
chmod u=rwxst aaa
ls -l aaa >> ccc
chmod g=rwxst aaa
ls -l aaa >> ccc
chmod o=rwxst aaa
ls -l aaa >> ccc
chmod 0000 aaa
ls -l aaa >> ccc
chmod a=rwxst aaa
ls -l aaa >> ccc
chmod 0000 aaa
ls -l aaa >> ccc
chmod a=rw aaa
ls -l aaa >> ccc
chmod 0000 aaa
ls -l aaa >> ccc
chmod ug=rw aaa
ls -l aaa >> ccc
chmod o+rw aaa
ls -l aaa >> ccc
chmod u+x aaa
ls -l aaa >> ccc
chmod u+s aaa
ls -l aaa >> ccc
chmod u-x aaa
ls -l aaa >> ccc
chmod a-r aaa
ls -l aaa >> ccc
chmod a+t aaa
ls -l aaa >> ccc

diff bbb ccc

centos是linux还是unix

centos是linux还是unix

centos是属于linux的。centos是一个基于red hat linux提供的可自由使用源代码的企业级linux发行版本;centos是rhel源代码再编译的产物,相对于其他的linux发行版有着更强的稳定性。

centos是linux还是unix

本文操作环境:centos 6.4系统、Dell G3电脑。

centos是linux还是unix

CentOS(Community ENTerprise Operating System)是Linux发行版之一,它是来自于Red Hat Enterprise Linux依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定性的服务器以CentOS替代商业版的Red Hat Enterprise Linux使用。

CentOS 是一个基于Red Hat Linux 提供的可自由使用源代码的企业级Linux发行版本。每个版本的 CentOS都会获得十年的支持(通过安全更新方式)。新版本的 CentOS 大约每两年发行一次,而每个版本的 CentOS 会定期(大概每六个月)更新一次,以便支持新的硬件。这样,建立一个安全、低维护、稳定、高预测性、高重复性的 Linux 环境。[1] CentOS是Community Enterprise Operating System的缩写。

CentOS 是RHEL(Red Hat Enterprise Linux)源代码再编译的产物,而且在RHEL的基础上修正了不少已知的 Bug ,相对于其他 Linux 发行版,其稳定性值得信赖。另外,由于 Fedora Core 计划也归根于 Red Hat 系,所以在绝大多数情况下,使用 Fedora Core 的朋友,也同样能够通过本站介绍的各种 CentOS 方面相关的技巧、方法来完成服务器的构建和维护工作。但相对于稳定性来说,Fedora Core 更侧重于最新技术,更面向于桌面应用以及开发测试,这也导致 Fedora Core 的稳定性被考虑在了次要的方面。

RHEL 一直都提供源代码的发行方式,CentOS 就是将 RHEL 发行的源代码从新编译一次,形成一个可使用的二进制版本。由于 LINUX 的源代码是 GNU,所以从获得 RHEL 的源代码到编译成新的二进制,都是合法。只是 REDHAT 是商标,所以必须在新的发行版里将 REDHAT 的商标去掉。

REDHAT 对这种发行版的态度是:“我们其实并不反对这种发行版,真正向我们付费的用户,他们重视的并不是系统本身,而是我们所提供的商业服务。”

所以,CentOS 可以得到 RHEL 的所有功能,甚至是更好的软件。但 CentOS 并不向用户提供商业支持,当然也不负上任何商业责任。

但如果单纯的业务型企业,建议选购 RHEL 软件并购买相应服务。这样可以节省你的 IT 管理费用,并可得到专业服务。

CentOS在2014初,宣布加入Red Hat。

CentOS是基于Linux建立的操作系统发行版本;

Linux属于内核系统,只有终端命令界面,无图形界面;

CentOS拥有终端命令界面和图形界面;

推荐教程:《centos教程》

以上就是centos是linux还是unix的详细内容,更多请关注php中文网其它相关文章!

I/O 重定向和管道 ——《Unix/Linux 编程实践教程》读书笔记(第 10 章)

I/O 重定向和管道 ——《Unix/Linux 编程实践教程》读书笔记(第 10 章)

1、I/O 重定向的概念与原因 及 标准输入、输出的标准错误的定义

所以的 Unix I/O 重定向都基于标准数据流的原理。三个数据了分别如下:

    1)标准输入 —— 需要处理的数据流

    2)标准输出 —— 结果数据流

    3)标准错误输出 —— 错误消息流


概念:所以的 Unix 工具都使用文件描述符 0、1 和 2。标准输入文件的描述符是 0, 标准输出的文件描述符是 1,而标准错误输出的文件描述符则是 2。Unix 假设文件描述符 0、1、2 已经被打开,可以分别进行读写操作。

通常通过 shell 命令行运行 Unix 系统工具时,stdin、stdout、stderr 连接在终端上。因此,工具从键盘读取数据并且把输出和错误消息写到屏幕。

大部分的 Unix 工具处理从文件或标准输入读入的数据。如果在命令行上给出了文件名,工具将从文件读取数据。若无文件名,程序则从标准输入读取数据。从另一方面说,大多数程序并不接收输出文件名;它们总是将结果写到文件描述符 1, 并将错误消息写到文件描述符 2。如果希望将进程的输出写道文件或另一个进程的输入去,就必须重定向相应的文件描述符。

重定向 I/O 的是 shell 而不是程序

最低可用文件描述符(lowest-available-fd)原则:文件描述符是一个数组的索引号。每个进程都有其打开的一组文件。这些打开的文件被保持在一个数组中。文件描述符即为某文件在此数组中的索引。当打开文件时,为此文件安排的描述符总是此数组中最低可用位置的索引。

将文件描述符 0、1、2 的概念和最低可用文件描述符原则结合使用,即可理解 I/O 重定向的工作原理


2、重定向标准 I/O 到文件

(1)如何将 stdin 定向到文件

a、close-then-open 策略

close(0);
int fd = open(file, O_RDONLY);


b、open-close-dup-close 策略
int oldfd = open(file, O_RDONLY);
#ifndef DUP2
    close(0);
    int newfd = dup(oldfd);
#else
    int newfd = dup2(oldfd, 0);
#endif
close(oldfd);


man 2 dup
#include <unistd.h>

int dup(int oldfd);
int dup2(int oldfd, int newfd);

系统调用 dup 复制了文件描述符 oldfd。而 dup2 将 oldfd 文件描述符复制给 newfd。两个文件描述符都指向同一个打开的文件。这两个调用都返回新的文件描述符,若发生错误,则返回 - 1。


c、open-dup2-close 策略


(2)重定向到文件

共有 3 个基本的概念,利用它们是的 Unix 下的程序可以轻易地将标准输入、输出和错误信息输出连接到文件:

    a、标准输入、输出以及错误输出分别对应于文件描述符 0、1、2;

    b、内核总是使用最低可用文件描述符;

    c、文件描述符集合通过 exec 调用传递,且不会被改变。

例子:

/*
 * who_to_file.c
 * purpose: show how to redirect output for another program
 * idea: fork, then in the child, redirect output, then exec
 */

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

int main(void)
{
    pid_t   pid;
    int     fd;

    printf("about to run who into a file\n");

    /* create a new process or quit */
    if ((pid = fork()) == -1)
    {
        perror("fork");
        exit(1);
    }

    /* child does the work */
    if (pid == 0)
    {
        close(1);
        fd = creat("userlist", 0644);
        execlp("who", "who", NULL);
        perror("execlp");
        exit(1);
    }

    /* parent waits then reports */
    else
    {
        wait(NULL);
        printf("done running who. results in userlist\n");
    }

    return 0;
}


3、管道编程

(1)创建管道

man 2 pipe
#include <unistd.h>

int pipe(int pipefd[2]);

系统调用 pipe 创建管道并将两端连接到两个文件描述符。pipefd [0] 为读数据端的文件描述符,而 pipefd [1] 则为写数据端的文件描述符。


(2)技术细节:管道并非文件

a、从管道中读数据

    管道读取阻塞:当进程试图从管道中读数据时,进程被挂起直到数据被写进管道。

    管道的读取结束标志:当所以的写操作关闭了管道的写数据端时,试图从管道读取数据的调用返回 0,意味着文件的结束。

    多个读操作可能会引起麻烦:管道是一个队列。当进程从管道中读取数据之后,数据已经不存在了。

b、向管道中写数据

    写入数据阻塞直到管道有空间去容纳新的数据

    写入必须保证一个最小的块大小:POSIX 标准规定内涵不会拆分小于 512 字节的块。而 Linux 则保证管道中可以存在 4096 字节的连续缓存。如果两个进程向管道写数据,并且没一个进程都限制其消息不打由于 512 字节,那么这些消息都不会被内核拆分。

    若无读操作在读数据,则写操作执行失败:如果所以的读操作都已将管道的读取端关闭,那么对管道的写入调用将会执行失败。如果在这种情况下,数据还可以被接收的话,为了避免数据丢失,内核采用了两种方法来通知进程:“此时的写操作是无意义的”。首先,内核发送 SIGPIPE 消息给进程。若进程被终止,则无任何事情发生。否则 write 调用返回 - 1, 并且将 errno 置为 EPIPE。

例子:

/*
 * pipe.c -
 *      demonstrates how to create a pipeline from one process to another
 * takes two args, each a command, and connectes
 * argv[1]s output to input of argv[2]
 * usage: pipe command1 command2
 * effect: command1 | command2
 * limitations: commands do not take arguments
 * users execlp() since known number of args
 * note: exchange child and parent and watch fun
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define oops(m, x)  { perror(m); exit(x); }

int main(int argc, char **argv)
{
    int     thepipe[2],
            newfd,
            pid;

    if (argc != 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)
            oops("could not redirect stdin", 3);

        close(thepipe[0]);
        execlp(argv[2], argv[2], NULL);
        oops(argv[2], 4);
    }

    close(thepipe[0]);

    if (dup2(thepipe[1], 1) == -1)
        oops("could not redirect stdout", 4);

    close(thepipe[1]);
    execlp(argv[1], argv[1], NULL);
    oops(argv[1], 5);

    return 0;
}


I/O重定向和管道——《Unix/Linux编程实践教程》读书笔记(第10章)

I/O重定向和管道——《Unix/Linux编程实践教程》读书笔记(第10章)

1、I/O重定向的概念与原因 及 标准输入、输出的标准错误的定义

所以的Unix I/O重定向都基于标准数据流的原理。三个数据了分别如下:

    1)标准输入——需要处理的数据流

    2)标准输出——结果数据流

    3)标准错误输出——错误消息流


概念:所以的Unix工具都使用文件描述符0、1和2。标准输入文件的描述符是0,标准输出的文件描述符是1,而标准错误输出的文件描述符则是2。Unix假设文件描述符0、1、2已经被打开,可以分别进行读写操作。

通常通过shell命令行运行Unix系统工具时,stdin、stdout、stderr连接在终端上。因此,工具从键盘读取数据并且把输出和错误消息写到屏幕。

大部分的Unix工具处理从文件或标准输入读入的数据。如果在命令行上给出了文件名,工具将从文件读取数据。若无文件名,程序则从标准输入读取数据。从另一方面说,大多数程序并不接收输出文件名;它们总是将结果写到文件描述符1,并将错误消息写到文件描述符2。如果希望将进程的输出写道文件或另一个进程的输入去,就必须重定向相应的文件描述符。

重定向I/O的是shell而不是程序

最低可用文件描述符(lowest-available-fd)原则:文件描述符是一个数组的索引号。每个进程都有其打开的一组文件。这些打开的文件被保持在一个数组中。文件描述符即为某文件在此数组中的索引。当打开文件时,为此文件安排的描述符总是此数组中最低可用位置的索引。

将文件描述符0、1、2的概念和最低可用文件描述符原则结合使用,即可理解I/O重定向的工作原理


2、重定向标准I/O到文件

(1)如何将stdin定向到文件

a、close-then-open策略

close(0);
int fd = open(file, O_RDONLY);


b、open-close-dup-close策略
int oldfd = open(file, O_RDONLY);
#ifndef DUP2
    close(0);
    int newfd = dup(oldfd);
#else
    int newfd = dup2(oldfd, 0);
#endif
close(oldfd);


man 2 dup
#include <unistd.h>

int dup(int oldfd);
int dup2(int oldfd, int newfd);

系统调用dup复制了文件描述符oldfd。而dup2将oldfd文件描述符复制给newfd。两个文件描述符都指向同一个打开的文件。这两个调用都返回新的文件描述符,若发生错误,则返回-1。


c、open-dup2-close策略


(2)重定向到文件

共有3个基本的概念,利用它们是的Unix下的程序可以轻易地将标准输入、输出和错误信息输出连接到文件:

    a、标准输入、输出以及错误输出分别对应于文件描述符0、1、2;

    b、内核总是使用最低可用文件描述符;

    c、文件描述符集合通过exec调用传递,且不会被改变。

例子:

/*
 * who_to_file.c
 * purpose: show how to redirect output for another program
 * idea: fork, then in the child, redirect output, then exec
 */

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

int main(void)
{
    pid_t   pid;
    int     fd;

    printf("about to run who into a file\n");

    /* create a new process or quit */
    if ((pid = fork()) == -1)
    {
        perror("fork");
        exit(1);
    }

    /* child does the work */
    if (pid == 0)
    {
        close(1);
        fd = creat("userlist", 0644);
        execlp("who", "who", NULL);
        perror("execlp");
        exit(1);
    }

    /* parent waits then reports */
    else
    {
        wait(NULL);
        printf("done running who. results in userlist\n");
    }

    return 0;
}


3、管道编程

(1)创建管道

man 2 pipe
#include <unistd.h>

int pipe(int pipefd[2]);

系统调用pipe创建管道并将两端连接到两个文件描述符。pipefd[0]为读数据端的文件描述符,而pipefd[1]则为写数据端的文件描述符。


(2)技术细节:管道并非文件

a、从管道中读数据

    管道读取阻塞:当进程试图从管道中读数据时,进程被挂起直到数据被写进管道。

    管道的读取结束标志:当所以的写操作关闭了管道的写数据端时,试图从管道读取数据的调用返回0,意味着文件的结束。

    多个读操作可能会引起麻烦:管道是一个队列。当进程从管道中读取数据之后,数据已经不存在了。

b、向管道中写数据

    写入数据阻塞直到管道有空间去容纳新的数据

    写入必须保证一个最小的块大小:POSIX标准规定内涵不会拆分小于512字节的块。而Linux则保证管道中可以存在4096字节的连续缓存。如果两个进程向管道写数据,并且没一个进程都限制其消息不打由于512字节,那么这些消息都不会被内核拆分。

    若无读操作在读数据,则写操作执行失败:如果所以的读操作都已将管道的读取端关闭,那么对管道的写入调用将会执行失败。如果在这种情况下,数据还可以被接收的话,为了避免数据丢失,内核采用了两种方法来通知进程:“此时的写操作是无意义的”。首先,内核发送SIGPIPE消息给进程。若进程被终止,则无任何事情发生。否则write调用返回-1,并且将errno置为EPIPE。

例子:

/*
 * pipe.c -
 *      demonstrates how to create a pipeline from one process to another
 * takes two args, each a command, and connectes
 * argv[1]s output to input of argv[2]
 * usage: pipe command1 command2
 * effect: command1 | command2
 * limitations: commands do not take arguments
 * users execlp() since known number of args
 * note: exchange child and parent and watch fun
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define oops(m, x)  { perror(m); exit(x); }

int main(int argc, char **argv)
{
    int     thepipe[2],
            newfd,
            pid;

    if (argc != 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)
            oops("could not redirect stdin", 3);

        close(thepipe[0]);
        execlp(argv[2], argv[2], NULL);
        oops(argv[2], 4);
    }

    close(thepipe[0]);

    if (dup2(thepipe[1], 1) == -1)
        oops("could not redirect stdout", 4);

    close(thepipe[1]);
    execlp(argv[1], argv[1], NULL);
    oops(argv[1], 5);

    return 0;
}


Linux CentOS 7 & Tengine(Nginx)安装与配置 centos7下载 centos7官网 centos7桌

Linux CentOS 7 & Tengine(Nginx)安装与配置 centos7下载 centos7官网 centos7桌

今天关于Unix/Linux编程实践教程–chmod在Centos7.3的实现chmod linux的介绍到此结束,谢谢您的阅读,有关centos是linux还是unix、I/O 重定向和管道 ——《Unix/Linux 编程实践教程》读书笔记(第 10 章)、I/O重定向和管道——《Unix/Linux编程实践教程》读书笔记(第10章)、Linux CentOS 7 & Tengine(Nginx)安装与配置 centos7下载 centos7官网 centos7桌等更多相关知识的信息可以在本站进行查询。

本文标签: