I'm using ØMQ in C, and I noticed that when calling zmq_unbind it returns -1. My ØMQ version is 4.2.2. Here is a simple code that fails:
#include <stdio.h>
#include <stdlib.h>
#include "zmq.h"
#define SERVER_ENDPOINT "tcp://*:5555"
int main(void)
{
void *context = zmq_ctx_new();
void *socket = zmq_socket(context, ZMQ_REP);
int rc = zmq_bind(socket, SERVER_ENDPOINT);
if (rc) {
fprintf(stderr, "Error: could not bind the socket.\n");
exit(1);
}
rc = zmq_unbind(socket, SERVER_ENDPOINT);
if (rc) {
fprintf(stderr, "Error: could not unbind the socket.\n");
exit(1);
}
rc = zmq_close(socket);
if (rc) {
fprintf(stderr, "Error: could not close the socket.\n");
exit(1);
}
zmq_ctx_destroy(context);
return 0;
}
tcp://*:5555 with the wildcard is not a valid option for zmq_unbind.
As suggested here: https://github.com/zeromq/pyzmq/issues/1025
The last_endpoint socket option can be used to retrieve the actual
endpoint when using wildcards
Related
I'm trying to replicate the behavior of a Windows app on Linux. Specifically, to control the backlighting on a keyboard.
Using Wireshark (on the linux host) to observer what the Windows tool does (when run on a Windows guest), I see a pair of URB_INTERRUPT out messages followed by a pair of URB_INTERRUPT in messages (one of each in each direction).
I've never used libusb before, but reading docs and examples, I've put together the code below. When run, libusb_interrupt_transfer() returns LIBUSB_ERROR_IO. Maybe I'm passing the wrong parameters, maybe I missed some initialization step, this is where my lack of experience with libusb really shines.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
int main(int argc, char *argv[]) {
unsigned int interface = 2;
int bSent = 0;
int retval = 0;
unsigned char msg[64];
unsigned char bytes[] = "\x51\x2c\x00\x00\xff\x64\x00\xff\xff\x72\x67\x62";
bzero(msg, sizeof(msg));
memcpy(msg, bytes, sizeof(bytes));
libusb_device_handle *devh;
libusb_init(NULL);
devh = libusb_open_device_with_vid_pid(NULL, 0x0b05, 0x1875);
if (devh) {
printf("Found device\n");
} else {
printf("ERROR: can't find device\n");
exit(1);
}
retval = libusb_set_auto_detach_kernel_driver(devh, interface);
if (!retval) {
printf("Set auto detach kernel driver\n");
} else {
printf("ERROR: failed to set auto detach kernel driver: %s\n", libusb_strerror(retval));
exit(1);
}
retval = libusb_claim_interface(devh, interface);
if (retval < 0) {
printf("ERROR: failed to claim interface %d: %s\n", interface, libusb_strerror(retval));
exit(1);
} else {
printf("Claimed interface %d\n", interface);
}
retval = libusb_interrupt_transfer(devh, interface, msg, sizeof(msg), &bSent, 1000);
if (retval < 0) {
printf("ERROR: libusb_interrupt_transfer() returned %d: %s\n", retval, libusb_strerror(retval));
} else {
printf("libusb_interrupt_transfer() sent %d bytes\n", bSent);
}
libusb_release_interface(devh, interface);
libusb_close(devh);
libusb_exit(NULL);
return(0);
}
Output:
Found device
Set auto detach kernel driver
Claimed interface 2
ERROR: libusb_interrupt_transfer() returned -1: Input/Output Error
I'm writing my very first C program and I was really doing well. The application talks to RESTful server. All was good until I decided to use an embedded database(libdb) for storage. I got this code below that was part of my entire program. My problem is it keeps on crashing on this line:
my_archive->db_home_dir = DEFAULT_HOMEDIR;
I thought I was running out of stack so I malloc'd all my lengthy variables but the problem was still occuring so I decided to separate this libdb part into a new code, but the problem still remains.
Any idea what has gone wrong here?
P.S. I'm doing all the coding in Xcode and stepping through each line after debug breakpoint right after main() doesn't help me a bit. Always ends up on the same error line. Or perhaps I just don't know what I'm doing.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include "db.h"
#define DEFAULT_HOMEDIR "/Users/mark/Documents/bdb/"
#define URLSDB "urls"
typedef struct archive_dbs {
DB *URLS_dbp;
char *db_home_dir;
char *URLS_db_name;
} ARCHIVE_DBS;
void initialize_archivedbs(ARCHIVE_DBS *my_archive)
{
my_archive->db_home_dir = DEFAULT_HOMEDIR; //CRASHES HERE: Thread 1: EXC_BAD_ACCESS (code=2, address=0x1000061da)
my_archive->URLS_dbp = NULL;
my_archive->URLS_db_name = NULL;
}
void set_db_filenames(ARCHIVE_DBS *my_archive)
{
size_t size;
size = strlen(my_archive->db_home_dir) + strlen(URLSDB) + 1;
my_archive->URLS_db_name = malloc(size);
snprintf(my_archive->URLS_db_name, size, "%s%s", my_archive->db_home_dir, URLSDB);
}
int open_database(DB **dbpp, const char *file_name, const char *program_name, FILE *error_file_pointer)
{
DB *dbp;
u_int32_t open_flags;
int ret;
ret = db_create(&dbp, NULL, 0);
if (ret != 0) {
fprintf(error_file_pointer, "%s: %s\n", program_name,
db_strerror(ret));
return(ret);
}
*dbpp = dbp;
dbp->set_errfile(dbp, error_file_pointer);
dbp->set_errpfx(dbp, program_name);
open_flags = DB_CREATE;
ret = dbp->open(dbp,
NULL,
file_name,
NULL,
DB_BTREE,
open_flags,
0);
if (ret != 0) {
dbp->err(dbp, ret, "Database '%s' open failed.", file_name);
return(ret);
}
return (0);
}
int databases_setup(ARCHIVE_DBS *my_archive, const char *program_name, FILE *error_file_pointer)
{
int ret;
ret = open_database(&(my_archive->URLS_dbp), my_archive->URLS_db_name, program_name, error_file_pointer);
if (ret != 0)
return (ret);
printf("databases opened successfully\n");
return (0);
}
int databases_close(ARCHIVE_DBS *my_archive)
{
int ret;
if (my_archive->URLS_dbp != NULL) {
ret = my_archive->URLS_dbp->close(my_archive->URLS_dbp, 0);
if (ret != 0)
fprintf(stderr, "URLS database close failed: %s\n",
db_strerror(ret));
}
printf("databases closed.\n");
return (0);
}
int main(void){
ARCHIVE_DBS *archivedbs;
initialize_archivedbs(archivedbs);
set_db_filenames(archivedbs);
databases_setup(archivedbs, "urlfetcher", NULL);
open_database(&archivedbs->URLS_dbp, "URLS.db", "urlfetcher",
NULL);
databases_close(archivedbs);
}
/* Edited */
my Cmakefile.txt file is:
cmake_minimum_required(VERSION 3.3)
project(WebServer)
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(SOURCE_FILES io.c server.c lock_fcntl.c sig_handler.c thread_job.c msg_parser.c)
set(LIB http-parser-master/http_parser.c)
set(CMAKE_USE_PTHREADS_INIT true)
set(CMAKE_USE_PTHREADS_INIT ON)
find_package(Threads REQUIRED)
add_executable(server ${SOURCE_FILES} ${LIB})
target_link_libraries(server Threads::Threads)
add_executable(client client.c io.c)
include_directories(header)
include_directories(http-parser-master)
In this way, I can compile and link my code. However pthread_create seems not work.
server.c:
void create_thread(int socket) {
data_t *data;
data = malloc(sizeof(data_t));
if (data == NULL) {
fprintf(stderr, "error in memory allocation");
exit(EXIT_FAILURE);
}
data->sock = socket;
/* debug */
fprintf(stdout, "[*] Creating thread\n");
fflush(stdout);
if (pthread_create(data->tid, NULL, job_t, data) != 0) {
fprintf(stderr, "Error returned by pthread_create()\n");
exit(EXIT_FAILURE);
}
/* debug */
fprintf(stdout, "[*] Thread created\n");
fflush(stdout);
}
thread_job.c:
void *job_t(void *arg) {
data_t *data = arg;
char *http_msg_h;
int nread;
/* debug */
fprintf(stdout, "start listening\n");
fflush(stdout);
/* read http header from connsd socket and store it in msg buffer */
nread = receive_msg_h(data->sock, (void **) &http_msg_h);
/* debug */
fprintf(stdout, "[+] parsing completed");
fflush(stdout);
}
Neither "start listening nor "Thread creation" is printed in output.
it is as if the function does not return but it doesn't work.
CMakeLists.txt is correct. My error was in code.
I change
pthread_create(data->tid, NULL, job_t, data) != 0
in pthread_create(&data->tid, NULL, job_t, data) != 0.
I am trying to write a c program to read data for morningstar sunsaver MPPT.
This is the simple program I found in net. But my program is unable to read data from register.
#include <stdlib.h>
#include <errno.h>
#include "src/modbus.h"
int main(void)
{
modbus_t *ctx;
uint16_t tab_reg[64];
int rc;
int i;
ctx = modbus_new_rtu("/dev/ttyS0", 115200, 'N',8,1);
if (ctx == NULL) {
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
rc = modbus_read_registers(ctx, 0, 10, tab_reg);
if (rc == -1) {
fprintf(stderr, "%s\n", modbus_strerror(errno));
return -1;
}
for (i=0; i < rc; i++) {
printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
}
modbus_close(ctx);
modbus_free(ctx);
}
It does not work for me. I get the following error message:
Bad file descriptor
By reading the documentation from LibModBus, I think you're missing a call to modbus_connect.
Try connecting before reading registers:
ctx = modbus_new_rtu("/dev/ttyS0", 115200, 'N',8,1);
if (ctx == NULL) {
fprintf(stderr, "Creation failed: %s\n", modbus_strerror(errno));
return -1;
}
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
Also, remember to modbus_close and modbus_free your context before exiting due to further error conditions. For example:
rc = modbus_read_registers(ctx, 0, 10, tab_reg);
if (rc == -1) {
fprintf(stderr, "%s\n", modbus_strerror(errno));
modbus_close(ctx);
modbus_free(ctx);
return -1;
}
It turned out to be trying to read from wrong Serial port.
Reading from /dev/ttyS3 worked.
I later realize that serial port are from /dev/ttyS0 .. /dev/ttyS9
I have assignment when I need to write simple time server and a client using Linux message queue. The server opens a message queue and the client sends a request with his PID (message with type 1) and the server reads that message and sends a message with type of PID (taken from the message read). I put all the code below because I don't know where I made the mistake. I'm not Linux programming expert. Don't even know if I written server correct.
File that is included by server and client (I need to write it in this way).
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#define QUEUE 100
#define PERM_ALL 0777
typedef struct my_msgbuf {
long mtype;
int pid;
} ClientMessage;
typedef struct my_msgbuf2 {
long mtype;
struct tm time;
} TimeMessage;
Server
int m_queue;
void cleanup(int signum) {
if (msgctl(m_queue, IPC_RMID, NULL) == -1) {
printf("Something happen on clean up\n");
exit(1);
}
exit(signum);
}
int main() {
ClientMessage pid_message;
TimeMessage t;
time_t clock;
struct tm *cur_time;
if ((m_queue = msgget(QUEUE, PERM_ALL | IPC_CREAT)) == -1) {
printf("Can't create and open message queue\n");
exit(1);
}
printf("created message queue = %d\n", m_queue);
fflush(stdout);
//t = malloc(sizeof(TimeMessage));
signal(SIGINT, cleanup);
while (1) {
if (msgrcv(m_queue, &pid_message, sizeof(pid_message.pid), 1, 0) == -1) {
break;
} else {
t.mtype = pid_message.pid;
clock = time(NULL);
cur_time = localtime(&clock);
memcpy(&t.time, cur_time, sizeof(struct tm));
msgsnd(m_queue, &t, sizeof(struct tm), 0);
}
}
cleanup(0);
}
Client
int main() {
int m_queue;
TimeMessage *t;
ClientMessage client;
if ((m_queue = msgget(QUEUE, PERM_ALL)) == -1) {
perror("Error in opening queue");
exit(1);
}
client.mtype = 1;
client.pid = getpid();
while (1) {
if (msgsnd(m_queue, &client, sizeof(client.pid), 0) == -1) {
perror("Error sending to queue");
exit(1);
} else {
if (msgrcv(m_queue, t, sizeof(struct tm), client.pid, 0) == -1) {
perror("Error reading from queue");
exit(1);
}
printf("time: %d:%d:%d\n", t->time.tm_hour, t->time.tm_min, t->time.tm_sec);
}
}
return 0;
}
Both program compile without errors but client return "Error reading from queue" msgrcv is returning -1.
After adding the perror it appears that you have got the error stating "Bad Address" (EFAULT) which means that "The address pointed to by msgp (buffer) isn't accessible". From the code it appears that there has been no memory allocated to TimeMessage *t so you can either allocate memory or just change it to TimeMessage t and pass &t instead of t to msgrcv. Also size should be sizeof t (assuming the change from *t to t, or sizeof(TimeMessage) for *t) instead of sizeof(struct tm) (& obviously you would change printf statement accordingly)
Hope this helps!