int main(int argc, char *argv[]) { struct msghdr msgh; struct iovec iov; int data, sfd, opt, fd; ssize_t ns; Boolean useDatagramSocket; /* Allocate a char array of suitable size to hold the ancillary data. However, since this buffer is in reality a 'struct cmsghdr', use a union to ensure that it is aligned as required for that structure. */ union { struct cmsghdr cmh; char control[CMSG_SPACE(sizeof(int))]; /* Space large enough to hold an 'int' */ } control_un; struct cmsghdr *cmhp; /* Parse command-line arguments */ useDatagramSocket = FALSE; while ((opt = getopt(argc, argv, "d")) != -1) { switch (opt) { case 'd': useDatagramSocket = TRUE; break; default: usageErr("%s [-d] file\n" " -d use datagram socket\n", argv[0]); } } if (argc != optind + 1) usageErr("%s [-d] file\n", argv[0]); /* Open the file named on the command line */ fd = open(argv[optind], O_RDONLY); if (fd == -1) errExit("open"); /* On Linux, we must transmit at least 1 byte of real data in order to send ancillary data */ msgh.msg_iov = &iov; msgh.msg_iovlen = 1; iov.iov_base = &data; iov.iov_len = sizeof(int); data = 12345; /* We don't need to specify destination address, because we use connect() below */ msgh.msg_name = NULL; msgh.msg_namelen = 0; msgh.msg_control = control_un.control; msgh.msg_controllen = sizeof(control_un.control); fprintf(stderr, "Sending fd %d\n", fd); /* Set message header to describe ancillary data that we want to send */ cmhp = CMSG_FIRSTHDR(&msgh); cmhp->cmsg_len = CMSG_LEN(sizeof(int)); cmhp->cmsg_level = SOL_SOCKET; cmhp->cmsg_type = SCM_RIGHTS; *((int *) CMSG_DATA(cmhp)) = fd; /* We could rewrite the preceding lines as: control_un.cmh.cmsg_len = CMSG_LEN(sizeof(int)); control_un.cmh.cmsg_level = SOL_SOCKET; control_un.cmh.cmsg_type = SCM_RIGHTS; *((int *) CMSG_DATA(CMSG_FIRSTHDR(&msgh))) = fd; */ /* Do the actual send */ sfd = unixConnect(SOCK_PATH, useDatagramSocket ? SOCK_DGRAM : SOCK_STREAM); if (sfd == -1) errExit("unixConnect"); ns = sendmsg(sfd, &msgh, 0); if (ns == -1) errExit("sendmsg"); fprintf(stderr, "sendmsg() returned %ld\n", (long) ns); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int data, sfd, opt; ssize_t ns; Boolean useDatagramSocket, noExplicitCreds; struct msghdr msgh; struct iovec iov; /* Allocate a char array of suitable size to hold the ancillary data. However, since this buffer is in reality a 'struct cmsghdr', use a union to ensure that it is aligned as required for that structure. Alternatively, we could allocate the buffer using malloc(), which returns a buffer that satisfies the strictest alignment requirements of any type */ union { char buf[CMSG_SPACE(sizeof(struct ucred))]; /* Space large enough to hold a ucred structure */ struct cmsghdr align; } controlMsg; struct cmsghdr *cmsgp; /* Pointer used to iterate through headers in ancillary data */ /* Parse command-line options */ useDatagramSocket = FALSE; noExplicitCreds = FALSE; while ((opt = getopt(argc, argv, "dn")) != -1) { switch (opt) { case 'd': useDatagramSocket = TRUE; break; case 'n': noExplicitCreds = TRUE; break; default: usageErr("%s [-d] [-n] [data [PID [UID [GID]]]]\n" " -d use datagram socket\n" " -n don't construct explicit " "credentials structure\n", argv[0]); } } /* The 'msg_name' field can be used to specify the address of the destination socket when sending a datagram. However, we do not need to use this field because we use connect() below, which sets a default outgoing address for datagrams. */ msgh.msg_name = NULL; msgh.msg_namelen = 0; /* On Linux, we must transmit at least 1 byte of real data in order to send ancillary data */ msgh.msg_iov = &iov; msgh.msg_iovlen = 1; iov.iov_base = &data; iov.iov_len = sizeof(int); /* Data is optionally taken from command line */ data = (argc > optind) ? atoi(argv[optind]) : 12345; fprintf(stderr, "Sending data = %d\n", data); if (noExplicitCreds) { /* Don't construct an explicit credentials structure. (It is not necessary to do so, if we just want the receiver to receive our real credentials.) */ printf("Not explicitly sending a credentials structure\n"); msgh.msg_control = NULL; msgh.msg_controllen = 0; } else { struct ucred *ucredp; /* Set 'msgh' fields to describe the ancillary data buffer */ msgh.msg_control = controlMsg.buf; msgh.msg_controllen = sizeof(controlMsg.buf); /* The control message buffer must be zero-initialized in order for the CMSG_NXTHDR() macro to work correctly. Although we don't need to use CMSG_NXTHDR() in this example (because there is only one block of ancillary data), we show this step to demonstrate best practice */ memset(controlMsg.buf, 0, sizeof(controlMsg.buf)); /* Set message header to describe the ancillary data that we want to send */ cmsgp = CMSG_FIRSTHDR(&msgh); cmsgp->cmsg_len = CMSG_LEN(sizeof(struct ucred)); cmsgp->cmsg_level = SOL_SOCKET; cmsgp->cmsg_type = SCM_CREDENTIALS; /* Set 'ucredp' to point to the data area in the 'cmsghdr' */ ucredp = (struct ucred *) CMSG_DATA(cmsgp); /* Use sender's own PID, real UID, and real GID, unless alternate values were supplied on the command line */ ucredp->pid = getpid(); if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) ucredp->pid = atoi(argv[optind + 1]); ucredp->uid = getuid(); if (argc > optind + 2 && strcmp(argv[optind + 2], "-") != 0) ucredp->uid = atoi(argv[optind + 2]); ucredp->gid = getgid(); if (argc > optind + 3 && strcmp(argv[optind + 3], "-") != 0) ucredp->gid = atoi(argv[optind + 3]); printf("Send credentials pid=%ld, uid=%ld, gid=%ld\n", (long) ucredp->pid, (long) ucredp->uid, (long) ucredp->gid); } /* Connect to the peer socket */ sfd = unixConnect(SOCK_PATH, useDatagramSocket ? SOCK_DGRAM : SOCK_STREAM); if (sfd == -1) errExit("unixConnect"); /* Send real plus ancillary data */ ns = sendmsg(sfd, &msgh, 0); if (ns == -1) errExit("sendmsg"); printf("sendmsg() returned %ld\n", (long) ns); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int data, sfd, opt, fd; ssize_t ns; Boolean useDatagramSocket; struct msghdr msgh; struct iovec iov; /* Allocate a char array of suitable size to hold the ancillary data. However, since this buffer is in reality a 'struct cmsghdr', use a union to ensure that it is aligned as required for that structure. Alternatively, we could allocate the buffer using malloc(), which returns a buffer that satisfies the strictest alignment requirements of any type. */ union { char buf[CMSG_SPACE(sizeof(int))]; /* Space large enough to hold an 'int' */ struct cmsghdr align; } controlMsg; struct cmsghdr *cmsgp; /* Pointer used to iterate through headers in ancillary data */ /* Parse command-line options */ useDatagramSocket = FALSE; while ((opt = getopt(argc, argv, "d")) != -1) { switch (opt) { case 'd': useDatagramSocket = TRUE; break; default: usageErr("%s [-d] file\n" " -d use datagram socket\n", argv[0]); } } if (argc != optind + 1) usageErr("%s [-d] file\n", argv[0]); /* Open the file named on the command line */ fd = open(argv[optind], O_RDONLY); if (fd == -1) errExit("open"); /* The 'msg_name' field can be used to specify the address of the destination socket when sending a datagram. However, we do not need to use this field because we use connect() below, which sets a default outgoing address for datagrams. */ msgh.msg_name = NULL; msgh.msg_namelen = 0; /* On Linux, we must transmit at least 1 byte of real data in order to send ancillary data */ msgh.msg_iov = &iov; msgh.msg_iovlen = 1; iov.iov_base = &data; iov.iov_len = sizeof(int); data = 12345; fprintf(stderr, "Sending data = %d\n", data); /* Set 'msgh' fields to describe the ancillary data buffer */ msgh.msg_control = controlMsg.buf; msgh.msg_controllen = sizeof(controlMsg.buf); /* The control message buffer must be zero-initialized in order for the CMSG_NXTHDR() macro to work correctly. Although we don't need to use CMSG_NXTHDR() in this example (because there is only one block of ancillary data), we show this step to demonstrate best practice */ memset(controlMsg.buf, 0, sizeof(controlMsg.buf)); /* Set message header to describe the ancillary data that we want to send */ cmsgp = CMSG_FIRSTHDR(&msgh); cmsgp->cmsg_len = CMSG_LEN(sizeof(int)); cmsgp->cmsg_level = SOL_SOCKET; cmsgp->cmsg_type = SCM_RIGHTS; *((int *) CMSG_DATA(cmsgp)) = fd; /* Connect to the peer socket */ sfd = unixConnect(SOCK_PATH, useDatagramSocket ? SOCK_DGRAM : SOCK_STREAM); if (sfd == -1) errExit("unixConnect"); fprintf(stderr, "Sending FD %d\n", fd); /* Send real plus ancillary data */ ns = sendmsg(sfd, &msgh, 0); if (ns == -1) errExit("sendmsg"); fprintf(stderr, "sendmsg() returned %ld\n", (long) ns); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int opt; char *optstring="dhs:"; int sfd, fdmax, ret; fd_set readfds, rfds; struct timeval timeout; struct tm *gmp, *locp; int i, numRead; char buf[BUF_SIZE]; struct param_st theParams; struct gps_st gpsStat; int sampleRate = 4000; /* * command-line processing */ debug=opterr=0; while((opt=getopt(argc,argv,optstring)) != -1) { switch(opt) { case 's': sampleRate = atoi(optarg); break; case 'd': debug++; break; case '?': case 'h': default: fprintf(stderr, "Usage: %s\n", "gp_store TODO"); exit(-1); } } if(debug) printf("gp_qc: sampRate=%d\n", sampleRate); struct sigaction sa; // sigterm sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = sig_handler; if(sigaction(SIGTERM, &sa, NULL) == -1) errExit("sched: sigaction"); /* connect to the udp socket */ int ufd; // char udp_path[128]; // snprintf(udp_path, 128, "%s.%d", UDP_SOCK_PATH, (long) getpid()) // ufd = unixBind(udp_path, SOCK_DGRAM); ufd = unixConnect(UDP_SOCK_PATH, SOCK_DGRAM); if(ufd < 0) errMsg("gp_store: udp bind"); float dt_in = 1. / (float)sampleRate; int resampleRate = 500; float fpasshi, fstophi, apasshi, astophi; int npoleshi; float f3dbhi; fpasshi = (float) resampleRate / (float) sampleRate; fstophi = 1.2 * fpasshi; apasshi = 0.95; astophi = 0.05; if(debug) printf("f = %f %f a =%f %f\n", fpasshi, fstophi, apasshi, astophi); bfdesign(fpasshi, apasshi, fstophi, astophi, &npoleshi, &f3dbhi); if(debug) printf("npoles = %d f3db = %f\n", npoleshi, f3dbhi); int n=sampleRate / 10; // operate on 1 s at a time float *p, *q; if((p=(float *)malloc(n*sizeof(float))) == NULL) errExit("qc: malloc"); if((q=(float *)malloc(n*sizeof(float))) == NULL) errExit("qc: malloc"); int dec = sampleRate / resampleRate; int nDec = n / dec; float *r, *t, dt_out = dt_in * dec; if((r=(float *)malloc(nDec*sizeof(float))) == NULL) errExit("qc: malloc"); if((t=(float *)malloc(nDec*sizeof(float))) == NULL) errExit("qc: malloc"); for(i=0; i<nDec; i++) t[i] = i * dt_out; if(debug) printf("samp %d resamp %d dt %f dtout %f n %d nDec %d\n", sampleRate, resampleRate, dt_in, dt_out, n, nDec); /* allocate the space for the udppkt. The zero length array is allocated here */ struct udppkt_st *u; int nWrt, pktSize = sizeof(struct udppkt_st) + nDec * sizeof(float); if((u=malloc(pktSize)) == NULL) errExit("qc: malloc"); while(STOP == FALSE) { /* n samples are collected from DMA here... */ /* copy into p */ /* antialias filter */ if(dec > 1) { bflowpass(npoleshi, f3dbhi, n, p, q); ints8r(n, dt_in, 0., q, 0., 0., nDec, t, r); if(ufd>0) { // send the data to base station u->dt = dt_out; u->ns = nDec; // u.t0.tv_sec = ; u.t0.tv_usec = memcpy(u->d, r, nDec * sizeof(float)); if((nWrt = write(ufd, u, pktSize)) != pktSize) errMsg("qc: write"); } } } }