📄 gz_iface.c
字号:
/* * Gazebo - Outdoor Multi-Robot Simulator * Copyright (C) 2003 * Nate Koenig & Andrew Howard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *//* * Desc: Generic interface support * Author: Andrew Howard * Date: 21 Apr 2003 * CVS: $Id: gz_iface.c,v 1.19 2006/10/01 18:48:26 natepak Exp $ */#include <assert.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <sys/mman.h>#include <fcntl.h>#include <sys/file.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include "gazebo.h"#include "gz_error.h"// Work out the filenamestatic const char *gz_iface_filename(gz_iface_t *self, const char *type, const char *id);//////////////////////////////////////////////////////////////////////////////// Create an interfacegz_iface_t *gz_iface_alloc(){ gz_iface_t *self; self = calloc(1, sizeof(gz_iface_t)); return self;}//////////////////////////////////////////////////////////////////////////////// Destroy an interfacevoid gz_iface_free(gz_iface_t *self){ free(self->filename); free(self); return;}//////////////////////////////////////////////////////////////////////////////// Work out the filenameconst char *gz_iface_filename(gz_iface_t *self, const char *type, const char *id){ char filename[128]; if (self->server != NULL) { snprintf(filename, sizeof(filename), "%s/%s.%s", self->server->filename, type, id); } else if (self->client != NULL) { snprintf(filename, sizeof(filename), "%s/%s.%s", self->client->filename, type, id); } else assert(0); if (self->filename) free(self->filename); self->filename = strdup(filename); return self->filename;}//////////////////////////////////////////////////////////////////////////////// Create an interface (server)int gz_iface_create(gz_iface_t *self, gz_server_t *server, const char *type, const char *id, size_t size){ self->server = server; // Went cant have null id's if (id == NULL) { GZ_ERROR1("interface [%s] id is NULL", type); return -1; } // We cannot have id with '.' if (strchr(id, '.')) { GZ_ERROR1("invalid id [%s] (must not contain '.')", id); return -1; } // Work out the filename gz_iface_filename(self, type, id); // Create and open the file self->mmap_fd = open(self->filename, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); if (self->mmap_fd < 0) { GZ_ERROR1("error creating mmap file: %s", strerror(errno)); return -1; } // Set the file to the correct size if (ftruncate(self->mmap_fd, size) < 0) { GZ_ERROR1("error setting size of mmap file: %s", strerror(errno)); return -1; } // Map the file into memory self->mmap = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, self->mmap_fd, 0); if (self->mmap == MAP_FAILED) { GZ_ERROR1("error mapping mmap file: %s", strerror(errno)); return -1; } memset(self->mmap, 0, size); ((gz_data_t*) self->mmap)->version = LIBGAZEBO_VERSION; ((gz_data_t*) self->mmap)->size = size; // Print the name, version info GZ_MSG3(5, "creating %s %03X %d", self->filename, ((gz_data_t*) self->mmap)->version, ((gz_data_t*) self->mmap)->size); return 0;}//////////////////////////////////////////////////////////////////////////////// Destroy the interface (server)int gz_iface_destroy(gz_iface_t *self){ // Unmap the file munmap(self->mmap, sizeof(gz_iface_t)); self->mmap = NULL; // Close the file close(self->mmap_fd); // Delete the file GZ_MSG1(5, "deleting %s", self->filename); if (unlink(self->filename)) { GZ_ERROR1("error deleting mmap file: %s", strerror(errno)); return -1; } return 0;}//////////////////////////////////////////////////////////////////////////////// Open an existing interface (client)int gz_iface_open(gz_iface_t *self, gz_client_t *client, const char *type, const char *id, size_t size){ self->client = client; // Work out the filename gz_iface_filename(self, type, id); // Open the mmap file self->mmap_fd = open(self->filename, O_RDWR); if (self->mmap_fd <= 0) { GZ_ERROR2("error opening device file %s : %s", self->filename, strerror(errno)); return -1; } // Map the mmap file self->mmap = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, self->mmap_fd, 0); if (self->mmap == MAP_FAILED) { GZ_ERROR1("error mapping device file: %s", strerror(errno)); return -1; } // Make sure everything is consistent if (((gz_data_t*) self->mmap)->size < size) { GZ_ERROR2("expected file size: %d < %d", ((gz_data_t*) self->mmap)->size, size); return -1; } // Print the name, version info GZ_MSG3(5, "opening %s %03X %d", self->filename, ((gz_data_t*) self->mmap)->version, ((gz_data_t*) self->mmap)->size); return 0;} //////////////////////////////////////////////////////////////////////////////// Close the interface (client)int gz_iface_close(gz_iface_t *self){ // Unmap the file munmap(self->mmap, sizeof(gz_iface_t)); self->mmap = NULL; // Close the file GZ_MSG1(5, "closing %s", self->filename); close(self->mmap_fd); return 0;}//////////////////////////////////////////////////////////////////////////////// Lock the interface.int gz_iface_lock(gz_iface_t *self, int blocking){ // Some 2.4 kernels seem to screw up the lock count somehow; keep an eye out //printf(" lock %p %s\n", self, self->filename); // Lock the file if (flock(self->mmap_fd, LOCK_EX) != 0) { GZ_ERROR2("flock %s error: %s", self->filename, strerror(errno)); return -1; } return 0;}//////////////////////////////////////////////////////////////////////////////// Unlock the interfacevoid gz_iface_unlock(gz_iface_t *self){ //printf("unlock %p %s\n", self, self->filename); // Unlock the file if (flock(self->mmap_fd, LOCK_UN) != 0) { GZ_ERROR1("flock error: %s", strerror(errno)); return; } return;}//////////////////////////////////////////////////////////////////////////////// Tell clients that new data is availableint gz_iface_post(gz_iface_t *self){ assert(self->server); return gz_server_post(self->server);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -