0

2 つのファイルを取得しsendfdsock.c, accessories.cました。accessories.c では、さまざまな一般的な関数 (logp - ログを出力するなど) を定義し、さまざまな一般的なライブラリ (sys/socket.h、string.h、stdio.h .... など) を含めました。accessories.c私が計画しているのは、最初にsendfdsock.cor を作成acceessories.hしてから に含めるのではなく、sendfdsock.cまず両方のオブジェクト ファイルを作成sendfdsock.c and accessories.cしてから、send でそれらをリンクすることです。これを行うコマンド (私accessories.hは直接リンクしているファイルを作成していませんaccessories.c):

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

しかし、最初のコマンドの後gcc -c sendfdsock.c、いくつかのエラーと警告が表示されます。これらのエラーの理由は、私が に含めたファイルでsendfdsock.c定義されているいくつかの関数と変数が必要であるためです。これは、gcc がオブジェクト ファイルの作成中にさまざまな関数や変数の定義をチェックすることを意味します。しかし、不気味なのは、 で定義して の最初の行で使用した関数にエラーや警告がないことです。 つまり、ユーザー定義関数にはエラー/警告はありませんが、標準ライブラリには反対です。なぜ? このコンパイルはgccでどのように行われますか? このコンパイルとリンクについて簡単に教えてくれる良い情報源はありますか。.haccessories.hlogp()accessories.cmain() of sendfdsock.c


また、2 つのファイルのコードも共有しています (見たい場合)。

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);

}
4

2 に答える 2

4

コンパイルし-Wall -pedanticて慎重にチェックしてください。おそらく、暗黙的に定義したことを示す警告が表示されますint logp。これは、宣言が見つからない場合に gcc が行うことです。

Ps。宣言と定義の違いがわからない場合は、それについて読み始めてください ;-)

于 2012-07-15T09:20:38.367 に答える
-1

externこれらの変数は、探しているものです。

ああ .h ファイルは物事を宣言しますが、それを定義しません。

于 2012-07-15T08:40:16.570 に答える