|
Packit |
cb6d3d |
/*
|
|
Packit |
cb6d3d |
Copyright (C) 2004, 2008, 2010-2011, 2017 Rocky Bernstein <rocky@gnu.org>
|
|
Packit |
cb6d3d |
Copyright (C) 2014 Robert Kausch <robert.kausch@freac.org>
|
|
Packit |
cb6d3d |
Copyright (C) 1998 Monty xiphmont@mit.edu
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
cb6d3d |
it under the terms of the GNU General Public License as published by
|
|
Packit |
cb6d3d |
the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
cb6d3d |
(at your option) any later version.
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
This program is distributed in the hope that it will be useful,
|
|
Packit |
cb6d3d |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
cb6d3d |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
cb6d3d |
GNU General Public License for more details.
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
You should have received a copy of the GNU General Public License
|
|
Packit |
cb6d3d |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
cb6d3d |
*/
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#ifdef HAVE_CONFIG_H
|
|
Packit |
cb6d3d |
# include "config.h"
|
|
Packit |
cb6d3d |
# define __CDIO_CONFIG_H__ 1
|
|
Packit |
cb6d3d |
#endif
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#ifdef HAVE_SYS_TIME_H
|
|
Packit |
cb6d3d |
# include <sys/time.h>
|
|
Packit |
cb6d3d |
#endif
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#include "common_interface.h"
|
|
Packit |
cb6d3d |
#include "utils.h"
|
|
Packit |
cb6d3d |
void
|
|
Packit |
cb6d3d |
cderror(cdrom_drive_t *d,const char *s)
|
|
Packit |
cb6d3d |
{
|
|
Packit |
cb6d3d |
ssize_t bytes_ret __attribute__((unused));
|
|
Packit |
cb6d3d |
if(s && d){
|
|
Packit |
cb6d3d |
switch(d->errordest){
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_PRINTIT:
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO, s, strlen(s));
|
|
Packit |
cb6d3d |
if (strlen(s) != bytes_ret)
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_LOGIT:
|
|
Packit |
cb6d3d |
d->errorbuf=catstring(d->errorbuf,s);
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_FORGETIT:
|
|
Packit |
cb6d3d |
default:
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
void
|
|
Packit |
cb6d3d |
cdmessage(cdrom_drive_t *d, const char *s)
|
|
Packit |
cb6d3d |
{
|
|
Packit |
cb6d3d |
ssize_t bytes_ret __attribute__((unused));
|
|
Packit |
cb6d3d |
if(s && d){
|
|
Packit |
cb6d3d |
switch(d->messagedest){
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_PRINTIT:
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO, s, strlen(s));
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_LOGIT:
|
|
Packit |
cb6d3d |
d->messagebuf=catstring(d->messagebuf,s);
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_FORGETIT:
|
|
Packit |
cb6d3d |
default:
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
void
|
|
Packit |
cb6d3d |
idperror(int messagedest,char **messages,const char *f,
|
|
Packit |
cb6d3d |
const char *s)
|
|
Packit |
cb6d3d |
{
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
char *buffer;
|
|
Packit |
cb6d3d |
int malloced=0;
|
|
Packit |
cb6d3d |
if(!f)
|
|
Packit |
cb6d3d |
buffer=(char *)s;
|
|
Packit |
cb6d3d |
else
|
|
Packit |
cb6d3d |
if(!s)
|
|
Packit |
cb6d3d |
buffer=(char *)f;
|
|
Packit |
cb6d3d |
else{
|
|
Packit |
cb6d3d |
buffer=malloc(strlen(f)+strlen(s)+9);
|
|
Packit |
cb6d3d |
sprintf(buffer,f,s);
|
|
Packit |
cb6d3d |
malloced=1;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
if(buffer){
|
|
Packit |
cb6d3d |
ssize_t bytes_ret __attribute__((unused));
|
|
Packit |
cb6d3d |
switch(messagedest){
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_PRINTIT:
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO,buffer,strlen(buffer));
|
|
Packit |
cb6d3d |
if(errno){
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO,": ",2);
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO,strerror(errno),strlen(strerror(errno)));
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO,"\n",1);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_LOGIT:
|
|
Packit |
cb6d3d |
if(messages){
|
|
Packit |
cb6d3d |
*messages=catstring(*messages,buffer);
|
|
Packit |
cb6d3d |
if(errno){
|
|
Packit |
cb6d3d |
*messages=catstring(*messages,": ");
|
|
Packit |
cb6d3d |
*messages=catstring(*messages,strerror(errno));
|
|
Packit |
cb6d3d |
*messages=catstring(*messages,"\n");
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_FORGETIT:
|
|
Packit |
cb6d3d |
default:
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
if(malloced)free(buffer);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
void
|
|
Packit |
cb6d3d |
idmessage(int messagedest,char **messages,const char *f,
|
|
Packit |
cb6d3d |
const char *s)
|
|
Packit |
cb6d3d |
{
|
|
Packit |
cb6d3d |
char *buffer;
|
|
Packit |
cb6d3d |
int malloced=0;
|
|
Packit |
cb6d3d |
ssize_t bytes_ret __attribute__((unused));
|
|
Packit |
cb6d3d |
if(!f)
|
|
Packit |
cb6d3d |
buffer=(char *)s;
|
|
Packit |
cb6d3d |
else
|
|
Packit |
cb6d3d |
if(!s)
|
|
Packit |
cb6d3d |
buffer=(char *)f;
|
|
Packit |
cb6d3d |
else{
|
|
Packit |
cb6d3d |
const unsigned int i_buffer=strlen(f)+strlen(s)+2;
|
|
Packit |
cb6d3d |
buffer=malloc(i_buffer);
|
|
Packit |
cb6d3d |
sprintf(buffer,f,s);
|
|
Packit |
cb6d3d |
strncat(buffer,"\n",1);
|
|
Packit |
cb6d3d |
malloced=1;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
if(buffer) {
|
|
Packit |
cb6d3d |
switch(messagedest){
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_PRINTIT:
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO,buffer,strlen(buffer));
|
|
Packit |
cb6d3d |
if(!malloced)
|
|
Packit |
cb6d3d |
bytes_ret = write(STDERR_FILENO,"\n",1);
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_LOGIT:
|
|
Packit |
cb6d3d |
if(messages){
|
|
Packit |
cb6d3d |
*messages=catstring(*messages,buffer);
|
|
Packit |
cb6d3d |
if(!malloced)*messages=catstring(*messages,"\n");
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
case CDDA_MESSAGE_FORGETIT:
|
|
Packit |
cb6d3d |
default:
|
|
Packit |
cb6d3d |
break;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
if(malloced)free(buffer);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
char *
|
|
Packit |
cb6d3d |
catstring(char *buff, const char *s) {
|
|
Packit |
cb6d3d |
if (s) {
|
|
Packit |
cb6d3d |
const unsigned int add_len = strlen(s) + 1;
|
|
Packit |
cb6d3d |
if(buff) {
|
|
Packit |
cb6d3d |
buff = realloc(buff, strlen(buff) + add_len);
|
|
Packit |
cb6d3d |
} else {
|
|
Packit |
cb6d3d |
buff=calloc(add_len, 1);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
strncat(buff, s, add_len - 1);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
return(buff);
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
int
|
|
Packit |
cb6d3d |
gettime(struct timespec *ts) {
|
|
Packit |
cb6d3d |
int ret = -1;
|
|
Packit |
cb6d3d |
if (!ts) return ret;
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
#if defined(HAVE_CLOCK_GETTIME)
|
|
Packit |
cb6d3d |
/* Use clock_gettime if available, preferably using the monotonic clock.
|
|
Packit |
cb6d3d |
*/
|
|
Packit |
cb6d3d |
static clockid_t clock = (clockid_t)-1;
|
|
Packit |
cb6d3d |
if ((int)clock == -1) clock = (clock_gettime(CLOCK_MONOTONIC, ts) < 0 ? CLOCK_REALTIME : CLOCK_MONOTONIC);
|
|
Packit |
cb6d3d |
ret = clock_gettime(clock, ts);
|
|
Packit |
cb6d3d |
#elif defined(WIN32)
|
|
Packit |
cb6d3d |
/* clock() returns wall time (not CPU time) on Windows, so we can use it here.
|
|
Packit |
cb6d3d |
*/
|
|
Packit |
cb6d3d |
clock_t time = clock();
|
|
Packit |
cb6d3d |
if ((int)time != -1) {
|
|
Packit |
cb6d3d |
ts->tv_sec = time/CLOCKS_PER_SEC;
|
|
Packit |
cb6d3d |
ts->tv_nsec = time%CLOCKS_PER_SEC*(1000000000/CLOCKS_PER_SEC);
|
|
Packit |
cb6d3d |
ret = 0;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
#else
|
|
Packit |
cb6d3d |
/* In other cases use gettimeofday.
|
|
Packit |
cb6d3d |
*/
|
|
Packit |
cb6d3d |
struct timeval tv;
|
|
Packit |
cb6d3d |
ret = gettimeofday(&tv, NULL);
|
|
Packit |
cb6d3d |
if (ret == 0) {
|
|
Packit |
cb6d3d |
ts->tv_sec = tv.tv_sec;
|
|
Packit |
cb6d3d |
ts->tv_nsec = tv.tv_usec*1000;
|
|
Packit |
cb6d3d |
}
|
|
Packit |
cb6d3d |
#endif
|
|
Packit |
cb6d3d |
|
|
Packit |
cb6d3d |
return ret;
|
|
Packit |
cb6d3d |
}
|