Я создаю простую оболочку в C, которая может выполнять команды, выполнять перенаправления и протоколы stdout. До сих пор я получил только часть перенаправления, но по какой-то причине, когда я пытаюсь скомпилировать collect2, выдает ошибку.Создание простой оболочки в C приводит к ошибке связывания
Файл util.c, что я в том числе:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<errno.h>
#include"util.h"
void setSigHandler(){
void (*oldHandler)();
oldHandler = signal(SIGINT, SIG_IGN);
signal(SIGTERM, oldHandler);
}
void prompt(){
char* user = getlogin();
printf("[%s]-->$", user);
}
void getNextCommand(){
errno = 0;
cmd = malloc(sizeof *cmd);
if(cmd == NULL){
char* error = strerror(errno);
printf("malloc:%s\n", error);
exit(EXIT_FAILURE);
}
fgets(cmd->payload, sizeof(cmd->payload), stdin);
if(cmd->payload[strlen(cmd->payload) - 1] == '\n'){
cmd->payload[strlen(cmd->payload) - 1] = '\0';
}
}
void parseCommandString(){
cmd->payloadArgc = 0;
char* buffer = strtok(cmd->payload, " ");
while(buffer != NULL){
cmd->payloadArgv[cmd->payloadArgc] = buffer;
if(!strcmp(cmd->payloadArgv[cmd->payloadArgc], ">")){
cmd->payloadArgv[cmd->payloadArgc] = NULL;
fileName = strtok(NULL, " ");
break;
}
if(!strcmp(cmd->payloadArgv[cmd->payloadArgc], "|")){
cmd->payloadArgv[cmd->payloadArgc] = NULL;
pCount++;
break;
}
buffer = strtok(NULL, " ");
cmd->payloadArgc++;
}
}
И мой главный файл:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<signal.h>
#include<sys/file.h>
#include<fcntl.h>
#include"util.h"
int execCommand();
int main(){
setSigHandler();
while(1){
prompt();
getNextCommand();
//pdsh exits on "close"
if(!strcmp(cmd->payloadArgv[0], "close")) break;
parseCommandString();
}
return 0;
}
int execCommand()
{
errno = 0;
int newFd;
// Fork process
pid_t pid = fork();
// Error
if (pid == -1) {
char* error = strerror(errno);
printf("fork: %s\n", error);
return -1;
}
// Child process
else if (pid == 0) {
if(fileName != NULL){
newFd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, 0755);
if(newFd == -1){
char* error = strerror(errno);
printf("open: %s\n", error);
return -2;
}
dup2(newFd, STDOUT_FILENO);
close(newFd);
}
// Execute command
execvp(cmd->payloadArgv[0], cmd->payloadArgv);
// Error occurred
char* error = strerror(errno);
printf("shell: %s: %s\n", cmd->payloadArgv[0], error);
return -2;
}
// Parent process
else {
close(newFd);
fileName = NULL;
// Wait for child process to finish
int childStatus;
waitpid(pid, &childStatus, 0);
return 0;
}
}
и ошибка из collect2:
/tmp/ccIXS72e.o:(.bss+0x0): multiple definition of `fileName'
/tmp/ccINCcwP.o:(.bss+0x0): first defined here
/tmp/ccIXS72e.o:(.data+0x0): multiple definition of `pCount'
/tmp/ccINCcwP.o:(.data+0x0): first defined here
/tmp/ccIXS72e.o:(.data+0x4): multiple definition of `newDescriptor'
/tmp/ccINCcwP.o:(.data+0x4): first defined here
collect2: error: ld returned 1 exit status
Что является причиной этого ?
Я знаю, что мой код main.c немного уродлив извините за это.
Edit: util.h по запросу:
#ifndef UTIL_H_
#define UTIL_H_
#define TRUE 1
#define FALSE !TRUE
#define STDOUT 0
#define STDIN 1
#define MAX_CMD_LENGHT 500
#define MAX_CMD_ARGS_LENGHT 50
char* fileName = NULL;
int pCount = -1;
int newDescriptor = -1;
Command cmd;
typedef struct commandR* Command;
struct commandR{
char payload[MAX_CMD_LENGHT];
char* payloadArgv[MAX_CMD_ARGS_LENGHT];
int payloadArgc;
};
void setSigHandler();
void prompt();
void getNextCommand();
void parseCommand();
#endif
Edit 2: После предложения я изменил мой код. Ошибка по-прежнему отключается.
util.h
#ifndef UTIL_H_
#define UTIL_H_
#define TRUE 1
#define FALSE !TRUE
#define STDOUT 0
#define STDIN 1
#define MAX_CMD_LENGHT 500
#define MAX_CMD_ARGS_LENGHT 50
extern int newDescriptor;
extern char* fileName;
extern int pCount;
typedef struct commandR* Command;
struct commandR{
char payload[MAX_CMD_LENGHT];
char* payloadArgv[MAX_CMD_ARGS_LENGHT];
int payloadArgc;
};
extern Command cmd;
void setSigHandler();
void prompt();
void getNextCommand();
void parseCommand();
#endif
util.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<errno.h>
#include"util.h"
char* fileName = NULL;
int pCount = -1;
int newDescriptor = -1;
Command cmd;
void setSigHandler(){
void (*oldHandler)();
oldHandler = signal(SIGINT, SIG_IGN);
signal(SIGTERM, oldHandler);
}
void prompt(){
char* user = getlogin();
printf("[%s]-->$", user);
}
void getNextCommand(){
errno = 0;
cmd = malloc(sizeof *cmd);
if(cmd == NULL){
char* error = strerror(errno);
printf("malloc:%s\n", error);
exit(EXIT_FAILURE);
}
fgets(cmd->payload, sizeof(cmd->payload), stdin);
if(cmd->payload[strlen(cmd->payload) - 1] == '\n'){
cmd->payload[strlen(cmd->payload) - 1] = '\0';
}
}
void parseCommandString(){
cmd->payloadArgc = 0;
char* buffer = strtok(cmd->payload, " ");
while(buffer != NULL){
cmd->payloadArgv[cmd->payloadArgc] = buffer;
if(!strcmp(cmd->payloadArgv[cmd->payloadArgc], ">")){
cmd->payloadArgv[cmd->payloadArgc] = NULL;
fileName = strtok(NULL, " ");
break;
}
if(!strcmp(cmd->payloadArgv[cmd->payloadArgc], "|")){
cmd->payloadArgv[cmd->payloadArgc] = NULL;
pCount++;
break;
}
buffer = strtok(NULL, " ");
cmd->payloadArgc++;
}
}
Показать ваш util.h. У меня есть подозрение. – SergeyA
Я подозреваю, что у вас есть глобальная переменная в util.h, которая должна быть в util.c и "extern var_type var_name" в.h отсутствует – Krapow
Да, те переменные, которые он сообщает, являются глобальными. Они должны быть в файле util.c? Не знал этого. – Akaitenshi