📄 a2dpd_ipc.c
字号:
int poll_error(int sockfd, int timeout){ int result = 0; int ipoll = -1; struct pollfd pollfds[1]; memset(pollfds, 0, sizeof(pollfds)); // Poll pollfds[0].fd = sockfd; pollfds[0].events = POLLERR | POLLHUP; pollfds[0].revents = 0; //DBG("Polling %d", sockfd); ipoll = poll(pollfds, (nfds_t)ARRAY_SIZE(pollfds), timeout); // if(pollfds[0].revents) // DBG("Polled %d = %d %08X", sockfd, ipoll, pollfds[0].revents); if((ipoll>0) && (pollfds[0].revents & (POLLERR | POLLHUP))) { DBG("%s detected on socket %d", (pollfds[0].revents & POLLERR) ? "POLLERR" : (pollfds[0].revents & POLLHUP) ? "POLLHUP" : "Nothing", sockfd); result = 1; } else if(ipoll==0) { errno = EAGAIN; } return result;}int accept_socket(int sockfd){ int new_fd = -1; if(poll_accept(sockfd, -1)) { // Block until connections if(enable_internet_socket) { struct sockaddr_in peer_addr; size_t sin_size = sizeof(peer_addr); new_fd = accept(sockfd, (struct sockaddr *)&peer_addr, &sin_size); } else { struct sockaddr_un peer_addr; size_t sin_size = sizeof(peer_addr); new_fd = accept(sockfd, (struct sockaddr *)&peer_addr, &sin_size); } } return new_fd;}void setup_socket(int sockfd){ if(enable_internet_socket) { // Timeouts struct timeval t = { 1, 0 }; (void)setsockopt( sockfd, SOL_SOCKET, SO_SNDTIMEO, &t, (int)sizeof(t)); (void)setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &t, (int)sizeof(t)); } else { // Timeouts struct timeval t = { 1, 0 }; (void)setsockopt( sockfd, SOL_SOCKET, SO_SNDTIMEO, &t, (int)sizeof(t)); (void)setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &t, (int)sizeof(t)); }}ssize_t send_socket(int sockfd, void* buffer, size_t size){ ssize_t result = -1; ssize_t ioffset = 0; while(sockfd>0 && ioffset<(ssize_t)size) { result=send(sockfd, ((char*)buffer)+ioffset, size-ioffset, MSG_NOSIGNAL); if(result>0) { ioffset += result; } else { break; } } return result;}ssize_t recv_socket(int sockfd, void* buffer, size_t size){ ssize_t received = 0; while((buffer!=0) && (received<(ssize_t)size)) { ssize_t result = recv(sockfd, buffer+received, size-received, MSG_NOSIGNAL); if(result>0) { received += result; if(result != (ssize_t)size) DBG("split frame received (%d/%d)", (int)result, (int)size); } else { received=result; break; } } return received;}//// Utility fonctions//void async_run_process(char* cmd, int wait){ char command[256]; char* argv[2]; int i = 0, status = 0; strncpy(command, cmd, sizeof(command)); command[sizeof(command)-1]= '\0'; argv[0] = strchr(command, ' '); if(argv[0]) { *argv[0]='\0'; argv[0]++; } if((cmd!=NULL) && (cmd[0]!='\0')) { pid_t pid = fork(); switch(pid) { case 0: // Children process close_server_socket_on_fork(); // Replace children with new process i = execlp(command, command, argv[0], NULL); DBG("execlp failed %s=%d (errno=%d:%s)", cmd, i, errno, strerror(errno)); break; case -1: // failed DBG("Fork %s failed", cmd); break; default: DBG("Forked %s", cmd); // Parent wait for completion if asked if(wait) { DBG("Waiting pid=%d", pid); waitpid(pid, &status, 0); DBG("Wait returned %d", status); } break; } }}void startup_a2dpd_upon_request(){ int running = 0; pid_t pid = 0; // Read pid FILE* fp = fopen(PIDFILE, "r"); if ((fscanf(fp, "%d", &pid) != 1)) { // Check a2dpd runs if((pid!=0)&&kill(pid,SIGUSR1)==0){ // Already running DBG("A2DPD is already running"); running = 1; } } // Start a2dpd if not running if(!running) { DBG("A2DPD is not running"); async_run_process("a2dpd -d", 1); }}void get_config_filename(char* filename, size_t buffersize){ // This strange construction allows to pass splint char* home_path = "/"; if(getenv("HOME")) { home_path = getenv("HOME"); } if(home_path != NULL) { (void)snprintf(filename, buffersize, "%s/%s", home_path, ".a2dprc"); filename[buffersize-1] = '\0'; }}void read_config_string(char* filename, char* section, char* key, char* returnbuffer, size_t buffersize, char* defvalue){ int found=0, error=0; FILE* hFile = fopen(filename, "rt"); returnbuffer[0] = '\0'; //DBG("read_config_string: reading %s", filename); if(hFile) { // search section while(!error && !found && !feof(hFile)) { char buffer[256], szsection[256]; if(fgets(buffer, (int)sizeof(buffer), hFile) == NULL) { error=1; break; } //DBG("read_config_string: read section %s", buffer); if(sscanf(buffer, "[%s]", szsection)==1) { szsection[strlen(szsection)-1]='\0'; //DBG("read_config_string: scanned %s", szsection); // Found section if(!strcasecmp(section, szsection)) { // key search loop while(!error && !found && !feof(hFile)) { char szkey[256], szvalue[256]; if(fgets(buffer, (int)sizeof(buffer), hFile) == NULL) { error=1; break; } //DBG("read_config_string: read key %s", buffer); // Another section name will exit the key search loop if(sscanf(buffer, "[%s]", szsection)==1) { break; } // A key name if(sscanf(buffer, "%[^=]=%[^\n]", szkey, szvalue)>1) { //DBG("read_config_string: read %s '%s' '%s'", buffer, szkey, szvalue); // Found key if(!strcasecmp(key, szkey)) { //DBG("read_config_string: buffer=%s", buffer); strncpy(returnbuffer, szvalue, buffersize); returnbuffer[buffersize-1]='\0'; found = 1; } } } } } } (void)fclose(hFile); } // Put default value if(!found) { strncpy(returnbuffer, defvalue, buffersize); returnbuffer[buffersize-1]='\0'; } //DBG("%s [%s] '%s'='%s'", __FUNCTION__, section, key, returnbuffer);}int read_config_int(char* filename, char* section, char* key, int defvalue){ char def[32]=""; char result[512]=""; (void)snprintf(def, sizeof(def), "%d", defvalue); read_config_string(filename, section, key, result, sizeof(result), def); return (atoi(result));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -