Why do I get errno 88 for recv() in the following code? I seem to be using the right socket and accept seems to work. The program runs fine, I can connect from a client, but as soon as I send a single byte of data, recv() fails. I am using the correct socket fd as far as I can understand and I have no idea what is causing this to fail.
#include <stdbool.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "log.h"
#include "server.h"
#include "protocol.h"
bool run_alarm_server ()
{
llog(LOG_INFO, "Starting alarm server.");
alarm_on = false;
unlink(SOCKET_PATH);
int success;
int sock;
int conn;
bool run;
char buf[1];
struct sockaddr_un srvaddr;
success = false;
memset(&srvaddr, 0, sizeof(srvaddr));
srvaddr.sun_family = AF_UNIX;
strcpy(srvaddr.sun_path, SOCKET_PATH);
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
llog(LOG_ERROR, "Failed to create socket.");
} else {
llog (LOG_DEBUG, "Created socket.");
}
if (bind(sock, (struct sockaddr *) &srvaddr, SUN_LEN(&srvaddr)) < 0) {
llog(LOG_ERROR, "Failed to bind to socket.");
} else {
llog(LOG_DEBUG, "Bound to socket.");
}
if (listen(sock, SERVER_QUEUE_LEN) < 0) {
llog(LOG_ERROR, "Failed to listen on socket.");
} else {
llog(LOG_INFO, "Listening on socket.");
}
run = true;
while (run) {
if ((conn = accept(sock, NULL, NULL) < 0)) {
llog(LOG_ERROR, "Failed to accept connection on socket.");
} else {
llog(LOG_INFO, "Accepted connection on socket.");
}
if (recv(conn, buf, sizeof(buf) / sizeof(buf[0]), 0) < 0) {
llog(LOG_ERROR, "Failed to receive data on socket.");
} else {
llog(LOG_DEBUG, "Received data on socket.");
}
switch (buf[0]) {
case ALARM_END:
alarm_on = false;
llog(LOG_ALARM, "The alarm has ended.");
break;
case ALARM_START:
alarm_on = true;
llog(LOG_ALARM, "The alarm has started.");
break;
case ALARM_ARM:
llog(LOG_ALARM, "The system has been armed.");
break;
case ALARM_DISARM:
alarm_on = false;
llog(LOG_ALARM, "The system has been disarmed.");
break;
case ALARM_STATUS:
llog(LOG_INFO, "The alarm status has been requested.");
char alarm_status[1];
if (alarm_on) {
alarm_status[0] = (char) 0x01;
} else {
alarm_status[0] = (char) 0x00;
}
if (send(conn, (const void *) alarm_status, 1, 0) < 0) {
llog(LOG_ERROR, "Failed to send alarm status.");
run = false;;
} else {
llog(LOG_DEBUG, "Alarm status sent.");
}
break;
case ALARM_QUIT:
llog(LOG_INFO, "Exiting.");
run = false;
success = true;
break;
}
}
if (socket >= 0) {
close(sock);
}
if (conn >= 0) {
close(conn);
}
unlink(SOCKET_PATH);
return success;
}
Your problem is here:
if ((conn = accept(sock, NULL, NULL) < 0)) {
This line is being interpreted as:
if (conn = (accept(sock, NULL, NULL) < 0)) {
... which means that conn
will be set to 1 (aka boolean true) if the accept() call returns a negative value, or to 0 (aka boolean false) otherwise.
I think what you intended was something like this:
if ((conn = accept(sock, NULL, NULL)) < 0) {