fd: Revamp para_mkdir(). It has two callers which both pass the mode value 0777 and contain extra code to regard the EEXIST error case as a success. Move the common bits into the wrapper and improve the documentation.
Consolidate EOF error codes. Currently we have ~15 error codes which indicate an EOF condition. One should suffice, so drop all codes except the generic E_EOF and use that everywhere.
Fix memory leak in para_play(). We leak one filter parse result per audio file played. Valgrind reports: ==24559== 24 (12 direct, 12 indirect) bytes in 1 blocks are definitely lost in loss record 34 of 104 ==24559== at 0x4044B0B: calloc (vg_replace_malloc.c:1328) ==24559== by 0x453A997: lls_parse (lopsub.c:768) ==24559== by 0x8057612: filter_setup (filter_common.c:98) ==24559== by 0x80500A4: load_file (play.c:377) ==24559== by 0x80500A4: load_next_file (play.c:454) ==24559== by 0x80500A4: play_post_monitor (play.c:1154) ==24559== by 0x8051110: call_post_monitor (sched.c:80) ==24559== by 0x8051110: sched_post_monitor (sched.c:106) ==24559== by 0x8051110: schedule (sched.c:148) ==24559== by 0x804EB80: main (play.c:1217)
Para_play: Improve doxygen global description. Expand and reword this text a bit, and move it into the documentation of main() so that it appears in the generated html.
para_play: Compute the current time more accurately. Currently get_play_time() throws away the subsecond part of the timeval and returns a number in seconds. We can improve on that by letting the function return milliseconds instead. However, with milliseconds we must perform multiplications using 64 bit integers to avoid integer overflows. This also affects the pause and play commands, which should now reposition the stream more accurately. It still won't be perfect, though, because play.c has no way of knowing the number of the chunk which is currently being decoded.
Merge topic branch t/overflow into master This series implements a new memory allocation API which checks for overflows. The first part of the series just renames the main allocation functions. Later patches in the series implement allocators which take two size_t arguments (like calloc(3)) and check whether the multiplication overflows by employing the __builtin_mul_overflow() primitive supported by gcc and clang. This requires us to bump the lowest supported gcc and clang version. * refs/heads/t/overflow: build: Compile with -ftrapv. string: Introduce arr_zalloc(). string: Introduce arr_alloc(). string: Introduce arr_realloc() and check for integer overflow. string: Rename para_calloc() -> zalloc(). string: Rename para_malloc() -> alloc(). string: Overhaul para_strdup().
Switch from select(2) to poll(2). The select(2) API is kind of obsolete because it does not work for file descriptors greater or equal than 1024, The general advice is to switch to poll(2), which offers equivalent functionality and does not suffer from this restriction. This patch implements this switch. The fd sets of select(2) have one nice feature: One can determine in O(1) time whether the bit for a given fd is turned on in an fd set. For poll(2), the monitored file descriptors are organized in an array of struct pollfd. Without information about the given fd's index in the pollfd array, one can only perform a linear search which requires O(n) time, with n being the number of fds being watched. Since this would have to be done for each fd, the running time becomes quadratic in the number of monitored fds, which is bad. Keeping the pollfd array sorted would reduce that to n * log(n) at the cost of additional work at insert time. This patch implements a different approach. The scheduler now maintains an additional array of unsigned integers which map fds to indices into the pollfd array. This new index array is transparent to the individual tasks, which still simply pass one or more fds from their ->pre_monitor() method to the scheduler. The length of the index array equals the highest fd given. This might become prohibitive in theory, but should not be an issue for the time being. Care needs to be taken in order to deal with callers which ask for the readiness of an fd without having called sched_monitor_readfd() or sched_monitor_writefd() in the ->pre_monitor() step. Before the patch, thanks to the FD_ZERO() call at the beginning of each iteration of the scheduler's main loop, both sched_read_ok() and sched_write_ok() returned false for fds which were not asked to be watched. We need to keep it this way for a seamless transition. We achieve this by replacing the FD_ZERO() call by a memset(3) call which fills the index array with 0xff bytes. Both sched_read_ok() and sched_write_ok() call the new get_revents() helper, where we check the fd argument against the allocation sizes of the two arrays. If either function is called with an fd that was not asked to be monitored in the ->pre_monitor() step, the checks notice that the index of this fd, 0xffffffff, is larger than the highest open fd and we return "not ready for I/O". Another issue is the case where the same file descriptor is submitted twice in ->pre_monitor() to check for readiness with respect to both reading and writing. The code in client_comon.c currently does that. To keep it working, the scheduler needs to detect this case and re-use the existing slot in both arrays.
Rename ->{pre,post}_select methods to ->{pre,post}_monitor. The word "monitor" is neutral and continues to be correct after the switch from select(2) to poll(2). Pure rename, nothing to see here.
Hide implementation of para_fd_set(). This preparatory patch for replacing select() renames para_fd_set() to sched_fd_set(), moves it to sched.c and makes it static. All users are modified to call either of the two new public functions sched_monitor_{read,write}fd() which take a pointer to struct sched rather than an fd set pointer.
sched: Introduce sched_{read,write}_ok(). Two trivial wrappers for FD_ISSET() which hide the fact that we're still using the select(2) API.
sched: Use integer value for select timeout. This modifies the public struct sched so that users pass in the default timeout as an integer value in milliseconds rather than a struct timeval. This simplifies the code a little and eases the transition from select(2) to poll(2) because poll(2) also takes a plain integer for the timeout. Since para_select() of fd.c now calls ms2tv() to convert the timeout back to a struct timeval, all executables which link with fd.o must also link with time.o. This was not the case for para_mixer and para_audioc, so configure.ac needs to be adjusted accordingly.
para_play: Avoid invalid time display on pause. When para_play enters pause mode, playback is stopped by notifying the writer node, causing it to terminate in the next iteration of the main loop. Until then the play time is computed incorrectly because we add the running time of the moribund writer node to the start time computed from the *new* start chunk set in com_pause(). Fortunately, the fix is simple. We just need to enqueue a reposition request in the same way the ff and jmp commands do.
string: Introduce arr_zalloc(). Adjust all callers which pass a product of two integers to zalloc() to call the new function instead and reduce zalloc() to a one-line wrapper.
string: Introduce arr_alloc(). Change all callers of alloc() which pass a product of two integers as the allocation size to call the new function instead. This function aborts if the multiplication overflows. With arr_alloc() in place, alloc() reduces to a trivial wrapper which calls new arr_alloc() with the first argument equal to one.
string: Rename para_calloc() -> zalloc(). Reword the documentation a bit since the function has never been a wrapper for calloc(3). No code changes.
string: Rename para_malloc() -> alloc(). Just because it's shorter and matches the naming of the new allocators we are about to introduce. The bulk of this patch was created with sed -i 's/para_malloc/alloc/g' *.c *.h yy/mp.y
i9e: Fix typo: s/ie9/i9e. It's weird that this was not noticed for so long. Fixes: e541d7bea7febed8cb9f8a65ae4bd9bdd1b5c8a0 Fixes: 3e3d8e1b48bbd8dbf46adf517c311b5e78dc820f
play: Avoid gcc warning when compiling without readline. The EXPORT_PLAY_CMD_HANDLER() macro is only used when READLINE support is enabled, which leads to play.c:112: warning: macro "EXPORT_PLAY_CMD_HANDLER" is not used [-Wunused-macros] Define the macro only when HAVE_READLINE is defined by moving down the definition to the first user, com_quit().
play: Create ~/.paraslash. Currently para_play won't save its history if this directory does not exist. This patch makes it create the directory at startup.
Merge branch 'refs/heads/t/para_play' A single patch which adds --end-of-playlist to control the behaviour of para_play when the end of the playlist is reached. Cooking for three weeks. * refs/heads/t/para_play: play: New option: --end-of-playlist.