⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myapp.c

📁 Linux嵌入式设计配套光盘,学习嵌入式设计可参考
💻 C
字号:
/* A trivial application to demonstrate the RTA package.  *//* We define a structure with a user-editable string and  *//* two integers.  One of the integers, zalarm, is set by  *//* the user.  The other integer, zcount, is incremented   *//* on each transition of zalarm from one-to-zero or from  *//* zero-to-one.  We print a message to the console each   *//* time a transition occurs.  The string, zname,  is      *//* considered a configuration value and is saved in a     *//* disk file whenever it is updated.  This code is        *//* limited in that only one user can connect at a time.   *//* Build with 'gcc myapp.c  -lrtadb' */#include <stdio.h>#include <stdlib.h>#include <stddef.h>             /* for 'offsetof' */#include <unistd.h>             /* for 'read/write/close' */#include <string.h>             /* for 'memset' */#include <sys/socket.h>#include <netinet/in.h>#include "../src/rta.h"/* You may need to change the above line to match where   *//* you are building this program.                         *//* We detect transitions of zalarm in a write callback.   *//* Here is the forward reference for it.                  *//* Forward references */int zedgedetect(char *tbl, char *col, char *sql, void *pr,                int rowid, void *poldrow);/* We need to allocate buffers for the text of the SQL    *//* command from the client and for the response returned  *//* to the client.  Here we are using 500 and 50000 bytes  *//* repectively. */#define INSZ       500#define OUTSZ     5000#define Z_NAME_LEN   20struct ZData {    char   zname[Z_NAME_LEN];    int    zalarm;    int    zcount;};#define ROW_COUNT  5struct ZData zdata[ROW_COUNT];/* Here is the array of COLDEFs that describe the columns *//* in our table.  The information in these structures is  *//* derived from the data structure itself and from our    *//* problem statement.  Note that you can have columns     *//* (members) in your data structure that are not          *//* described by a COLDEF.  Such hidden columns might be   *//* useful for information that you do not want visible to *//* the user interfaces. */COLDEF zcols[] = {  {    "ztable",           /* the table name */    "zname",            /* the column name */    RTA_STR,            /* it is a string */    Z_NAME_LEN,         /* number of bytes */    offsetof(struct ZData, zname), /* location in struct */    RTA_DISKSAVE,       /* flags: configuration data */    (int (*)()) 0,      /* called before read */    (int (*)()) 0,      /* called after write */    "User assigned name for this row.  The names are "    "saved to a disk file since they are part of the "    "configuration.  Note that the maximum name length "    "is 20 characters including the terminating NULL. "  },  {    "ztable",           /* the table name */    "zalarm",           /* the column name */    RTA_INT,            /* it is an integer */    sizeof(int),        /* number of bytes */    offsetof(struct ZData, zalarm), /* location in struct */    0,                  /* no flags */    (int (*)()) 0,      /* called before read */    zedgedetect,        /* called after write */    "A user read/write value.  Print a message on all transitions "    "from high-to-low or from low-to-high.  Do not display anything "    "if a write does not cause a transition.  A write callback "    "translates all non-zero values to a value of one."  },  {    "ztable",           /* the table name */    "zcount",           /* the column name */    RTA_INT,            /* it is an integer */    sizeof(int),        /* number of bytes */    offsetof(struct ZData, zcount), /* location in struct */    RTA_READONLY,       /* flags: a statistic */    (int (*)()) 0,      /* called before read */    (int (*)()) 0,      /* called after write */    "The number of transitions of zalarm.  This is "    "a read-only statistic."  },};TBLDEF ztbl = {    "ztable",            /* table name */    zdata,               /* address of table */    sizeof(struct ZData), /* length of each row */    ROW_COUNT,           /* number of rows */    (void *) NULL,       /* linear array; no need for an iterator */    (void *) NULL,       /* no iterator callback data either */    zcols,               /* array of column defs */    sizeof(zcols) / sizeof(COLDEF),                         /* the number of columns */    "/tmp/zsave.sql",    /* Save config in /tmp directory */    "A sample table showing column flags and write callbacks"};/* In the TBLDEF we give the name of the table, its start *//* address, the size of each row, the number of rows, a   *//* pointer to the table of COLDEFS for this table, and    *//* the number of columns in the table.  Here we are       *//* specifying a save file.  This file will be used save   *//* all of the RTA_DISKSAVE columns, which, in our case,   *//* is just the name column. */int main(){    int   i;                   /* a loop counter */    int   srvfd;               /* File Descriptor for our server socket */    int   connfd;              /* File Descriptor for conn to client */    struct sockaddr_in srvskt; /* server listen socket */    struct sockaddr_in cliskt; /* socket to the UI/DB client */    socklen_t   adrlen;    char  inbuf[INSZ];         /* Buffer for incoming SQL commands */    char  outbuf[OUTSZ];       /* response back to the client */    int   incnt;               /* SQL command input count */    int   outcnt;              /* SQL command output count */    int   dbret;               /* return value from SQL command */    /* init zdata */    for (i=0; i<ROW_COUNT; i++) {        zdata[i].zname[0] = (char) 0;        zdata[i].zalarm   = 0;        zdata[i].zcount   = 0;    }    /* tell RTA it about zdata */    if (rta_add_table(&ztbl) != RTA_SUCCESS) {        fprintf(stderr, "Table definition error!\n");        exit(1);    }    /* By-the-way: the following code is pretty horrendous.     * It uses blocking IO, ignores error conditions, and     * makes wildly optimistic assumptions about socket IO.     * My goal is to make the code understandable by getting     * it into as few lines as possible.  DO NOT USE FOR     * PRODUCTION CODE!!! */    /* We now need to open a socket to listen for incoming     * client connections. */    adrlen = sizeof (struct sockaddr_in);    (void) memset ((void *) &srvskt, 0, (size_t) adrlen);    srvskt.sin_family = AF_INET;    srvskt.sin_addr.s_addr = INADDR_ANY;    srvskt.sin_port = htons (8888);    srvfd = socket(AF_INET, SOCK_STREAM, 0); /* no error checks! */    bind(srvfd, (struct sockaddr *) &srvskt, adrlen);    listen (srvfd, 1);    /* Loop forever accepting client connections */    while (1) {        connfd = accept(srvfd, (struct sockaddr *) &cliskt, &adrlen);        if (connfd < 0) {            fprintf(stderr, "Error on socket/bind/listen/accept\n");            exit(1);        }        incnt = 0;        while (connfd >= 0) {            incnt = read(connfd, &inbuf[incnt], INSZ-incnt);            if (incnt <= 0) {                close(connfd);                connfd = -1;            }            outcnt = OUTSZ;/* The read above uses blocking IO.  In a real            *//* application we would want to accept the connection and *//* use a select() or poll() to do the multiplexing for us.*//* We are trying keep the like count low in this sample.  *//* The real work of RTA occurs with the following call.   *//* We pass the string read from the client into the RTA   *//* library which parses it, verifies it, executes it, and *//* fills outbuf with the result.  We switch on the result *//* of the dbcommand() call to see if we should send the   *//* result back to the client or close the connections.    *//* Under normal circumstances, the PostgreSQL client will *//* do an orderly close and dbcommand() returns RTA_CLOSE. */            dbret = dbcommand(inbuf, &incnt, outbuf, &outcnt);            switch (dbret) {                case RTA_SUCCESS:                    write(connfd, outbuf, (OUTSZ - outcnt));                    incnt = 0;                    break;                case RTA_NOCMD:                    break;                case RTA_CLOSE:                    close(connfd);                    connfd = -1;                    break;                default:                    break;            }        }    }}/* zedgedetect(), a write callback to print a message when * the alarm structure member is set from zero-to-one or * from one-to-zero.  We also normalize zalarm to 0 or 1. */int zedgedetect(char *tbl, char *col, char *sql, void *pr,                int rowid, void *poldrow){    /* we detect an edge by seeing if the old value of     * zalarm is different from the new value. */    int oldalarm;    int newalarm;    /* normalize non-zero values to 1 */    if (((struct ZData *) pr)->zalarm != 0) {        ((struct ZData *) pr)->zalarm = 1;    }    oldalarm = ((struct ZData *) poldrow)->zalarm;    newalarm = ((struct ZData *) pr)->zalarm;    if (oldalarm != newalarm) {        zdata[rowid].zcount++;   /* increment counter */        printf("Transition from %d to %d in row %d\n",               oldalarm, newalarm, rowid);    }/* We always return success in this example.  As a        *//* reminder, if we return a non-zero value, the row       *//* affected is restored to its old value and the client   *//* programs gets an error result from the SQL command     *//* that it sent. */    return(0);  /* always succeeds */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -