我有一个自定义shell程序,其中包含signal.h
,unistd.h
和stdio.h
。我最初在RedHat Enterprise上工作(不知道究竟是什么版本,但不是太老)我能够在我的程序中使用gcc并且编译得很好并且运行正常。现在我把它移到了Ubuntu,gcc给了我一些错误,第一个是conflicting types for 'getline()'
。其他一些错误说incompatible implicit declaration of built-in function strlen
。我已经覆盖了有问题的函数,为什么它在RedHat中工作但在Ubuntu中没有? Linux不是我的事所以请说清楚。如果您需要更多错误详情,请与我们联系。
/* define a global input buffer */
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#define MAXARG 512
#define MAXBUF 512
#define BUFFER_SIZE 50
#define MAX_COMMANDS 10
char buffer [BUFFER_SIZE];
static char *prompt = "MYSHELL>";
static char inpbuf[MAXBUF];
static char *arg[MAXARG+1];
static char tokbuf[2*MAXBUF];
static char *tok = tokbuf;
char history[MAX_COMMANDS][MAXBUF];
int cmd_num;
void getline(void);
void getline() {
int length;
length = read(0, inpbuf, MAXBUF);
if (length == 0) {
printf("\n");
exit(0);
}
inpbuf[length] = '\0';
}
void processline() {
char *ptr = inpbuf;
int narg;
for (narg=0;;) {
arg[narg] = tok;
for (; *ptr == ' ' || *ptr == '\t'; ptr++)
;
while(*ptr != ' ' && *ptr != '\t' && *ptr != '\n' &&
*ptr != '\0' && *ptr != ';' && *ptr != '&')
*tok++ = *ptr++;
*tok++ = '\0';
if (narg < MAXARG)
narg++;
if (*ptr == '\n')
break;
}
// clear the input buffer
for (ptr = inpbuf; *ptr != '\n'; ptr++)
*ptr = ' ';
if (narg != 0) {
arg[narg] = NULL;
}
}
void handle_SIGINT()
{
write(STDOUT_FILENO, buffer, strlen(buffer));
}
int main()
{
int pid, exitstat, ret;
struct sigaction handler;
handler.sa_handler = handle_SIGINT;
handler.sa_flags = 0;
sigemptyset(&handler.sa_mask);
sigaction(SIGINT, &handler, NULL);
strcpy(buffer, "Caught Control C\n");
while (1) {
printf("%s ", prompt);
fflush(stdout);
getline();
processline();
if ((pid = fork()) < 0){
fprintf(stderr, "myshell: error\n");
return (-1);
}
if (pid == 0) {
execvp(*arg, arg);
fprintf(stderr, "%s\n", *arg);
exit(127);
}
waitpid(pid, &exitstat, 0);
}
return 0;
}
答案 0 :(得分:4)
incompatible implicit declaration of built-in function strlen
conflicting types for 'getline()
<stdio.h>
已包含getline声明,因此请确保您的代码中没有任何地方重新声明/重新定义getline()
[使用不同的原型]。
答案 1 :(得分:4)
最简单的解决方案是重命名您的getline()
功能,例如到my_getline()
答案 2 :(得分:0)
gcc -Wall typoknig.c
typoknig.c:19: error: conflicting types for ‘getline’
//usr/include/stdio.h:671: note: previous declaration of ‘getline’ was here
typoknig.c:21: error: conflicting types for ‘getline’
//usr/include/stdio.h:671: note: previous declaration of ‘getline’ was here
getline
的两个单独声明,Andy建议您使用my_getline()
,因为前者已经是stdio.h
的一部分。
typoknig.c:在函数'getline'中:
typoknig.c:27:警告:隐式声明函数'退出'
typoknig.c:27:警告:内置函数'exit'的不兼容隐式声明
这可能不太好,man exit
在右上方说:
#include <stdlib.h>
void exit(int status);
也许你需要加入stdlib.h
? gcc假设的是未声明函数的签名?
哎呀,typoknig.c:在函数'handle_SIGINT'中:
typoknig.c:59:警告:隐式声明函数'strlen'
typoknig.c:59:警告:内置函数'strlen'的不兼容隐式声明
man strlen
救援:
#include <string.h>
幸运的是,string.h
将帮助解决下一个问题,我们已经确定了exit
:
typoknig.c:在函数'main'中:
typoknig.c:70:警告:隐式声明函数'strcpy'
typoknig.c:70:警告:内置函数'strcpy'的不兼容隐式声明
typoknig.c:85:警告:内置函数'exit'的不兼容隐式声明
预处理器不是很漂亮吗?
typoknig.c:87: warning: implicit declaration of function ‘waitpid’
typoknig.c:64: warning: unused variable ‘ret’
Sayeth man waitpid
:
#include <sys/types.h>
#include <sys/wait.h>
第64行留给读者练习。
答案 3 :(得分:0)
Getline()
不属于C标准。它是GNU扩展。在c ++ Getline()
是标准的。
所以在你的#include
之前添加你的代码#define _GNU_SOURCE
应修正警告。另请参阅linux上的“man getline”。