2012-07-15 65 views
0

我得到了兩個文件sendfdsock.c, accessories.c。在accessories.c中,我定義了各種常用函數(如logp - 打印日誌)幷包含各種常用函數庫(如sys/socket.h,string.h,stdio.h ....)。現在,我沒有在sendfdsock.c中包含accessories.c或先製作acceessories.h,然後將它包含在sendfdsock.c中,我計劃先製作sendfdsock.c and accessories.c的目標文件,然後將它們鏈接在一起發送。該命令來做到這一點(我沒有做任何accessories.h文件,我直接連接accessories.c):如何編譯在gcc中完成

gcc -c sendfdsock.c 
gcc -c accessories.c 
gcc -o send sendfdsock.o accessories.o 

但第一個命令gcc -c sendfdsock.c後,我得到了一些錯誤和警告。造成這些錯誤的原因是sendfdsock.c需要一些函數和變量,這些函數和變量在accessories.h中包含的.h文件中定義。這意味着gcc在製作目標文件時會檢查各種函數和變量的定義。 令人毛骨悚然的功能logp()沒有錯誤或警告,我已在accessories.c中定義並在第一行main() of sendfdsock.c中使用。
對於用戶定義的函數,沒有錯誤/警告,但是對於標準庫,沒有錯誤/警告。 爲什麼?
這個編譯如何在gcc中完成?有沒有什麼好的資料可以簡單地告訴我這個編譯和鏈接的東西。
我也分享這兩個文件的代碼(如果有的人想看到):

accessories.c

#include <malloc.h> 
#include <time.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 
#include <error.h> 
#include <signal.h> 

#define PORT "4444" //port we are listening on 

int sendall(int fd, char *buf, int *len) 
{ 
    int total = 0;  // how many bytes we've sent 
    int bytesleft = *len; // how many we have left to send 
    int n; 

    while(total < *len) { 
     n = send(fd, buf+total, bytesleft, 0); 
     if (n == -1) { break; } 
     total += n; 
     bytesleft -= n; 
    } 

    *len = total; // return number actually sent here 

    return n==-1?-1:0; // return -1 on failure, 0 on success 
} 

int recvall(int fd, char *buf, int *len) 
{ 
    int total = 0;  // how many bytes we've sent 
    int bytesleft = *len; // how many we have left to send 
    int n; 

    while(total < *len) { 
     n = recv(fd, buf+total, bytesleft, 0); 
     if (n == -1) { break; } 
     total += n; 
     bytesleft -= n; 
    } 

    *len = total; // return number actually sent here 

    return n==-1?-1:0; // return -1 on failure, 0 on success 
} 

void logp(int typ, char* msg) // typ --> type(category) of message [1-Normal Log, 2-Warning(any unexpected thing happened), 3-Error, 4-Debugging Log ] 
{ 
    int fd; 
    time_t now; 
    ssize_t wlength=0; 
    char * dat; 
    char * str; 
    int size = 45+strlen(msg);//14+24+5+sizeof msg+1 

    str= (char *) malloc(size); 

    time(&now);//system time in seconds 
    dat = ctime(&now); // converting seconds to date-time format 
    dat = strtok(dat,"\n"); 

    //Appending type of log 
    switch(typ) 
    { 
    case 1: 
     strcpy(str,"__LOG__ | "); 
     strcat(str,dat); 
     break; 
    case 2: 
     strcpy(str,"__WARN__ | "); 
     strcat(str,dat); 
     break; 
    case 3: 
     strcpy(str,"__ERR__ | "); 
     strcat(str,dat); 
     break; 
    case 4: 
     strcpy(str,"__DEBUG__ | "); 
     strcat(str,dat); 
     break; 
    default: 
     strcpy(str,"__UNDEF__ | "); 
     strcat(str,dat); 
     break; 
    } 


    strcat(str," | "); 
    strcat(str,msg);//appending message 
    strcat(str,"\n"); 

    fd = open("log", O_WRONLY | O_CREAT | O_APPEND, 0644); // should be opened somewhere else 
    if (fd == -1) 
     printf("Could not open log - %s\n",strerror(errno)); 
    else 
    {//need to add lock to the file and printing error message 
     while (wlength < strlen(str)) 
     { 
      wlength = write(fd, str,strlen(str)); 
      if (wlength == -1) 
      { 
       printf("Error : writing log\n"); 
       break; 
      } 
     } 


    } 
} 
void errorp(char *where, int boolean, int errn,char *what) 
{ 
    char errmsg[21+strlen(where)]; 
    strcpy(errmsg,"Where - "); 
    strcat(errmsg,where); 
    strcat(errmsg," | Error - "); 

    if(boolean == 1)//we got error number 
    { 
     strcat(errmsg,strerror(errn)); 
     //fprintf(stderr,"ERROR - In %s and error is %s\n",where ,strerror(errn)); 
     logp(3,errmsg); 
    } 
    else if(boolean == 0)//we got a message 
    { 
     strcat(errmsg,what); 
     //fprintf(stderr,"ERROR - In %s and error is %s\n",where ,what); 
     logp(3,errmsg); 
    } 
    else//we got nothing 
    { 
     strcat(errmsg,"No Message"); 
     //fprintf(stderr,"ERROR - In %s\n",where); 
     logp(3,errmsg); 
    } 
} 

sendfdsock.c

#include <stropts.h> 
#include <fcntl.h> 
#include <sys/ioctl.h> 
#include <sys/un.h> 




#define CONTROLLEN CMSG_LEN(sizeof(int)) 
static struct cmsghdr *cmptr = NULL; /* malloc'ed first time */ 

int send_err(int fd, int errcode, const char *msg); 
int send_fd(int fd, int fd_to_send); 

int main(int argc, char const *argv[]) 
{ 
    logp(1,"started"); 
    int fd_to_send; 
    if((fd_to_send = open("vi",O_RDONLY)) < 0) 
     printf("vi open failed"); 

    struct sockaddr_un address; 
    int socket_fd, nbytes; 
    char buffer[256]; 

    socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); 
    if(socket_fd < 0) 
    { 
     printf("socket() failed\n"); 
     return 1; 
    } 

    /* start with a clean address structure */ 
    memset(&address, 0, sizeof(struct sockaddr_un)); 

    address.sun_family = AF_UNIX; 
    snprintf(address.sun_path, sizeof(address.sun_path)-1, "./demo_socket"); 

    if(connect(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) 
    { 
     printf("connect() failed\n"); 
     return 1; 
    } 

    nbytes = snprintf(buffer, 256, "hello from a client"); 
// write(socket_fd, buffer, nbytes); 

    // nbytes = read(socket_fd, buffer, 256); 
    buffer[nbytes] = 0; 

    //printf("MESSAGE FROM SERVER: %s\n", buffer); 

    //sending the file descriptor  
    printf("From send_fd %d \n",send_fd(socket_fd,fd_to_send)); 
    printf("Main end"); 
    close(socket_fd); 

    exit(0); 

} 

int send_err(int fd, int errcode, const char *msg) 
{ 
    int  n; 

    if ((n = strlen(msg)) > 0) 
     if (write(fd, msg, n) != n) /* send the error message */ 
      return(-1); 

    if (errcode >= 0) 
     errcode = -1; /* must be negative */ 

    if (send_fd(fd, errcode) < 0) 
     return(-1); 

    return(0); 
} 

int send_fd(int fd, int fd_to_send) 
{ 

    ssize_t temp; 
    struct iovec iov[1]; 
    struct msghdr msg; 
    char   buf[2]; /* send_fd()/recv_fd() 2-byte protocol */ 

    iov[0].iov_base = buf; 
    iov[0].iov_len = 2; 
    msg.msg_iov  = iov; 
    msg.msg_iovlen = 1; 
    msg.msg_name = NULL; 
    msg.msg_namelen = 0; 
    if (fd_to_send < 0) { 
     msg.msg_control = NULL; 
     msg.msg_controllen = 0; 
     buf[1] = -fd_to_send; /* nonzero status means error */ 
     if (buf[1] == 0) 
      buf[1] = 1; /* -256, etc. would screw up protocol */ 
    } else { 
     if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL) 
      return(-1); 
     cmptr->cmsg_level = SOL_SOCKET; 
     cmptr->cmsg_type = SCM_RIGHTS; 
     cmptr->cmsg_len = CONTROLLEN; 
     msg.msg_control = cmptr; 
     msg.msg_controllen = CONTROLLEN; 
     *(int *)CMSG_DATA(cmptr) = fd_to_send;  /* the fd to pass */ 
     buf[1] = 0;   /* z ero status means OK */ 
    } 
    buf[0] = 0;    /* null byte flag to recv_fd() */ 
    printf("before sendmsg \n"); 
    temp = sendmsg(fd, &msg, 0); 
    if (temp != 2) 
    { 
     printf("inside sendmsg condition %d\n",temp); 
     return(-1); 
    } 
    printf("after sendmsg %d\n",temp); 
    return(0); 

} 
+0

請向我們展示'accessories.h'中的內容。 – crazyscot 2012-07-15 08:38:12

+0

在'accessories.h'中聲明'logp'嗎? – Mat 2012-07-15 08:42:14

+0

其實我不是在製作accessories.h,我直接鏈接accessories.c。 – 2012-07-15 08:42:24

回答

-1

extern那些變量就是你正在尋找的東西。

哦.h文件聲明的東西,但沒有定義它。

+0

我沒有使用任何.h文件。我直接鏈接'accessories.c' – 2012-07-15 08:45:13

+0

你在描述中寫了'accessories.h'。 – dave 2012-07-15 08:55:50

+0

這只是一種方法。我也寫過,我沒有製作任何.h文件。 – 2012-07-15 09:02:58

4

編譯-Wall -pedantic並仔細檢查:您可能會收到一條警告,告訴您隱式定義了int logp這就是gcc沒有找到聲明時所做的。

詩篇。如果您不確定聲明和定義的區別,請開始閱讀關於此的內容;-)

+0

我可以證實它,只是試過。 – dave 2012-07-15 09:22:36

+0

然後爲什麼它顯示錯誤 - printf未定義 – 2012-07-15 09:32:54

+0

我得到所有這些警告... – steffen 2012-07-15 21:49:06