您的位置:首页 > 运维架构

Glusterfs的编译选项 #pragma GCC poison system popen

2013-12-15 22:42 1406 查看
最近一直在研究Glusterfs3.3.1,当因需在代码中加入system(cmd)调用时,编译器提示
error:attempt to use poisoned ”system",
即试图使用有毒的system调用,首先我检查了一遍代码,其实就是一个system调用。排除了代码编写错误。然后我突然想起了system调用需要慎用的,调用system的进程在调用system未返回时可能会阻塞而且会忽略某几种信号。我接下来在网上查了查资料,确实system调用时可能会有诸多问题。
我在Glusterfs的源码文件./libglusterfs/src/compat.h也找到了这句话:#pragma GCC poison system popen,所以,当我再代码中加入system,popen等调用时,编译器就会报错,禁止编译。

问题又来了.我是自己编码实现类system的功能还是Glusterfs另有解决的办法的?显然,Glusterfs的研发团队足够的聪明,我们想的他们都替我们想好了,哈哈。在libglusterfs/src/下有run.h,实现了类system调用的接口runcmd等,且 使用非常灵活。run.h接口声明如下:

[cpp]
view plain
copy
print
?






/*
Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
#ifndef __RUN_H__
#define __RUN_H__
#define RUN_PIPE -1
struct runner {
char **argv;
unsigned argvlen;
int runerr;
pid_t chpid;
int chfd[3];
FILE *chio[3];
};
typedef struct runner runner_t;
/**
* initialize runner_t instance.
*
* @param runner pointer to runner_t instance
*/
void runinit (runner_t *runner);
/**
* get FILE pointer to which child's stdio is redirected.
*
* @param runner pointer to runner_t instance
* @param fd specifies which standard file descriptor is
*        is asked for
*
* @see runner_redir()
*/
FILE *runner_chio (runner_t *runner, int fd);
/**
* add an argument.
*
* 'arg' is duplicated.
*
* Errors are deferred, no error handling is necessary.
*
* @param runner pointer to runner_t instance
* @param arg    command line argument
*/
void runner_add_arg (runner_t *runner, const char *arg);
/**
* add a sequence of arguments.
*
* Variadic function, calls runner_add_arg() on each vararg.
* Argument sequence MUST be NULL terminated.
*
* Errors are deferred, no error handling is necessary.
*
* @param runner pointer to runner_t instance
*
* @see runner_add_arg()
*/
void runner_add_args (runner_t *runner, ...);
/**
* add an argument with printf style formatting.
*
* Errors are deferred, no error handling is necessary.
*
* @param runner pointer to runner_t instance
* @param format printf style format specifier
*/
void runner_argprintf (runner_t *runner, const char *format, ...);
/**
* log a message about the command to be run.
*
* @param runner  pointer to runner_t instance
*
* @param dom  log domain
* @param lvl  log level
* @param msg  message with which the command is prefixed in log
*
* @see gf_log()
*/
void runner_log (runner_t *runner, const char *dom, gf_loglevel_t lvl,
const char *msg);
/**
* set up redirection for child.
*
* @param runner  pointer to runner_t instance
*
* @param fd      fd of child to redirect (0, 1, or 2)
* @param tgt_fd  fd on parent side to redirect to.
*                Note that runner_end() will close tgt_fd,
*                if user needs it in another context it should
*                be dup'd beforehand.
*                RUN_PIPE can be used for requiring a
*                pipe from child to parent. The FILE
*                created for this purpose will be
*                accessible via runner_chio() (after
*                runner_start() has been invoked).
*
* @see  runner_start(), dup(2), runner_chio(), runner_start()
*/
void
runner_redir (runner_t *runner, int fd, int tgt_fd);
/**
* spawn child with accumulated arg list.
*
* @param runner  pointer to runner_t instance
*
* @return  0 on succesful spawn
*          -1 on failure (either due to earlier errors or execve(2) failing)
*
* @see runner_cout()
*/
int runner_start (runner_t *runner);
/**
* complete operation and free resources.
*
* If child exists, waits for it. Redirections will be closed.
* Dynamically allocated memory shall be freed.
*
* @param runner  pointer to runner_t instance
*
* @return  0 if child terminated successfully
*          -1 if there is no running child
*          n > 0 if child failed; value to be interpreted as status
*                in waitpid(2)
*
* @see waitpid(2)
*/
int runner_end (runner_t *runner);
/**
* variant of runner_end() which does not free internal data
* so that the runner instance can be run again.
*
* @see runner_end()
*/
int runner_end_reuse (runner_t *runner);
/**
* spawn and child, take it to completion and free resources.
*
* Essentially it's a concatenation of runner_start() and runner_end()
* with simplified return semantics.
*
* @param runner  pointer to runner_t instance
*
* @return  0 on success
*          -1 on failuire
*
* @see runner_start(), runner_end()
*/
int runner_run (runner_t *runner);
/**
* variant of runner_run() which does not free internal data
* so that the runner instance can be run again.
*
* @see runner_run()
*/
int runner_run_reuse (runner_t *runner);
/**
* run a command with args.
*
* Variadic function, child process is spawned with
* the given sequence of args and waited for.
* Argument sequence MUST be NULL terminated.
*
* @return 0 on success
*         -1 on failure
*/
int runcmd (const char *arg, ...);
#endif


例如:我在代码中想这样用:system("echo hello world!");,用runcmd实现则这样用:runcmd("echo", "hello", "world!", NULL);在run.h中还有更灵活的接口,而且在同目录的run.c文件中对run.h的接口都有使用实例,在此不做赘述。

更多精彩内容,请关注 吖Sool社区论坛
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息