/* open the file and mmap it, necessary to go to READY state */ static gboolean gst_file_src_start (GstBaseSrc * basesrc) { GstFileSrc *src = GST_FILE_SRC (basesrc); struct stat stat_results; if (src->filename == NULL || src->filename[0] == '\0') goto no_filename; GST_INFO_OBJECT (src, "opening file %s", src->filename); /* open the file */ src->fd = gst_open (src->filename, O_RDONLY | O_BINARY, 0); if (src->fd < 0) goto open_failed; /* check if it is a regular file, otherwise bail out */ if (fstat (src->fd, &stat_results) < 0) goto no_stat; if (S_ISDIR (stat_results.st_mode)) goto was_directory; if (S_ISSOCK (stat_results.st_mode)) goto was_socket; src->using_mmap = FALSE; src->read_position = 0; /* record if it's a regular (hence seekable and lengthable) file */ if (S_ISREG (stat_results.st_mode)) src->is_regular = TRUE; #ifdef HAVE_MMAP if (src->use_mmap) { /* FIXME: maybe we should only try to mmap if it's a regular file */ /* allocate the first mmap'd region if it's a regular file ? */ src->mapbuf = gst_file_src_map_region (src, 0, src->mapsize, TRUE); if (src->mapbuf != NULL) { GST_DEBUG_OBJECT (src, "using mmap for file"); src->using_mmap = TRUE; src->seekable = TRUE; } } if (src->mapbuf == NULL) #endif { /* If not in mmap mode, we need to check if the underlying file is * seekable. */ off_t res = lseek (src->fd, 0, SEEK_END); if (res < 0) { GST_LOG_OBJECT (src, "disabling seeking, not in mmap mode and lseek " "failed: %s", g_strerror (errno)); src->seekable = FALSE; } else { src->seekable = TRUE; } lseek (src->fd, 0, SEEK_SET); } /* We can only really do seeking on regular files - for other file types, we * don't know their length, so seeking isn't useful/meaningful */ src->seekable = src->seekable && src->is_regular; return TRUE; /* ERROR */ no_filename: { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (_("No file name specified for reading.")), (NULL)); return FALSE; } open_failed: { switch (errno) { case ENOENT: GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("No such file \"%s\"", src->filename)); break; default: GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open file \"%s\" for reading."), src->filename), GST_ERROR_SYSTEM); break; } return FALSE; } no_stat: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not get info on \"%s\"."), src->filename), (NULL)); close (src->fd); return FALSE; } was_directory: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("\"%s\" is a directory."), src->filename), (NULL)); close (src->fd); return FALSE; } was_socket: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("File \"%s\" is a socket."), src->filename), (NULL)); close (src->fd); return FALSE; } }
/* open the flite, necessary to go to READY state */ static gboolean gst_flite_src_start (GstBaseSrc * basesrc) { GstFliteSrc *src = GST_FLITE_SRC (basesrc); struct stat stat_results; if (src->filename == NULL || src->filename[0] == '\0') goto no_filename; GST_INFO_OBJECT (src, "opening file %s", src->filename); /* open the file */ src->fd = gst_open (src->filename, O_RDONLY | O_BINARY, 0); if (src->fd < 0) goto open_failed; /* check if it is a regular file, otherwise bail out */ if (fstat (src->fd, &stat_results) < 0) goto no_stat; if (S_ISDIR (stat_results.st_mode)) goto was_directory; if (S_ISSOCK (stat_results.st_mode)) goto was_socket; src->read_position = 0; /* record if it's a regular (hence seekable and lengthable) file */ if (S_ISREG (stat_results.st_mode)) src->is_regular = TRUE; /* We need to check if the underlying file is seekable. */ { off_t res = lseek (src->fd, 0, SEEK_END); if (res < 0) { GST_LOG_OBJECT (src, "disabling seeking, lseek failed: %s", g_strerror (errno)); src->seekable = FALSE; } else { res = lseek (src->fd, 0, SEEK_SET); if (res < 0) { /* We really don't like not being able to go back to 0 */ src->seekable = FALSE; goto lseek_wonky; } src->seekable = TRUE; } } /* We can only really do seeking on regular files - for other file types, we * don't know their length, so seeking isn't useful/meaningful */ src->seekable = src->seekable && src->is_regular; gst_base_src_set_dynamic_size (basesrc, src->seekable); return TRUE; /* ERROR */ no_filename: { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (_("No file name specified for reading.")), (NULL)); goto error_exit; } open_failed: { switch (errno) { case ENOENT: GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("No such file \"%s\"", src->filename)); break; default: GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open file \"%s\" for reading."), src->filename), GST_ERROR_SYSTEM); break; } goto error_exit; } no_stat: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not get info on \"%s\"."), src->filename), (NULL)); goto error_close; } was_directory: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("\"%s\" is a directory."), src->filename), (NULL)); goto error_close; } was_socket: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("File \"%s\" is a socket."), src->filename), (NULL)); goto error_close; } lseek_wonky: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Could not seek back to zero after seek test in file \"%s\"", src->filename)); goto error_close; } error_close: close (src->fd); error_exit: return FALSE; }