fd: Simplify and move for_each_file_in_dir(). With only one user it can be static in aft.c. Modify the function so that it no longer changes the current working directory, remove para_opendir() because it is unused now, dedox the documentation and streamline it a bit.
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.
fd: Improve read_pattern(), rename it to read_and_compare(). The old name was a poor choice because the pattern argument actually is neither a regular expression nor a filename pattern. More importantly, the function receives a buffer size and tries to read this many bytes but then compares only the first part of the received buffer to the expected string. This is a rather weird calling convention. The only two callers are the http sender and receiver which both call the function during the initial handshake where no other data is available. Thus we can change the function to read only the minimal amount of data (length of the expected string), and drop the bufsize parameter. Remove the unnecessary log message in the error case and streamline the documentation while at it.
fd: Open-code para_chdir(). Another public trivial wrapper that can go away because it has only a single caller. POSIX says Upon successful completion, 0 shall be returned. Otherwise, −1 shall be returned, the current working directory shall remain unchanged, and errno shall be set to indicate the error. So the new check against zero is equivalent to the old code which checked whether the return value is non-negative.
fd: Remove file_exists(). Open-coding this function actually improves code readability. The function name was a misnomer anyway because any error from the stat() call (such as EACCES) was reported as "file does not exist".
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.
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.
fd: Drop fd_set parameter from read_nonblock() and friends. This parameter is not necessary because its only purpose is to avoid the readv(2) system call in case it would likely return EAGAIN because we just called select(2) which reported that there is no data to read. Since the parameter is an obstacle for the conversion of the code base from select(2) to poll(2), get rid of it for the time being. If needed we can add back an equivalent optimization which checks for POLLIN after the conversion.
interactive: Avoid select(2) in input_available(). In analogy to write_ok(), introduce read_ok() which uses poll(2) rather than select(2). To avoid duplications, abstract out the common code to the new xpoll() helper. We could avoid the timeout parameter of xpoll() at this point because both callers call it with a zero timeout (causing poll() to return immediately), but later patches introduce other callers which specify non-zero timeouts.
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.
server: Move para_fgets() to user_list.c. It's only used there, so we can make it static and dedoxify its documentation.
fd.c: Simplify para_mmap(). Both callers pass in a zero offset, so we can get rid of this parameter.
fd.c: Change return value of file_exists() to bool. file_exists() is in fact a misnomer, since it simply calls stat(2), which may fail for many reasons besides ENOENT. But that's another issue for another patch..
Shorten copyright notice. The GPLv2 line does not add any additional information, so drop it. This leaves a single line of legalese text for most files, which is about the amount of screen real estate it deserves. This patch was created with the following script (plus some manual fixups): awk '{ if (NR <= 5) { gs = gensub(/.*Copyright.* ([0-9]+).*Andre Noll.*/, "\\1", "g") if (gs != $0) year = gs next } if (NR == 6 && year != "") printf("/* Copyright (C) %s Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */\n", year) print }'
The wma tagger. This adds infrastructure to support meta tag editing. If the new --modify option is given to para_afh, the arguments to --title, --artist, --album and --comment are used to alter the meta information of the audio file. Only the wma audio format handler is extended to support the new feature. Patches for other audio format handlers follow. As for the implementation, this commit adds the function pointer ->rewrite_tags to struct audio_format_handler. This function takes a file descriptor to a newly opened temporary file. The individual audio format handlers are supposed to write the altered contents to this file descriptor. On success, the temporary file is renamed on top of the original file unless --backup is given. Since meta tags in wma files are encoded in UTF-16 we need primitives to convert from UTF8 to UTF16 and vice versa. These are provided by libiconv, so we check for this library and deactivate the new features on systems that lack libiconv. Unfortunately the signatures of iconv() are different between Linux and FreeBSD. To deal with this incompatibility this patch adds a configure check to determine if the cast is necessary.
Update year in copyright headers. Done with files=$(git grep -l 'Copyright (C) [0-9]\{4\}\(-2014\)* Andre Noll') sed --in-place= -e 's/Copyright (C) \([0-9]\{4\}\)-2014 Andre Noll/Copyright (C) \1 Andre Noll/1' $files In previous years we ran a similar script to set the second year in the range to the current year. This is kind of silly, so let's get rid of this useless information. This commit replaces "Copyright (C) A-B" by "Copyright (C) A" in all file headers, i.e. only the first year (A) is left in. Accurate information including time stamps for each change can be obtained from the git history.
doc: Change email address to maan@tuebingen.mpg.de The mail server on systemlinux.org was down for more than a week lately, so let's use an alternative official address. This commit changes all maan@systemlinux.org addresses to maan@tuebingen.mpg.de. Most .c and .h files contain the email address in the copyright header, so they must all be patched. Three other files contain the address for a different reason: * README lists email and git, gitweb and home page URLs * configure.ac needs it for configure -h * version.c contains it for the -V option of all commands
Change copyright year to 2014. This year, we're really on time. The changes in this patch were created by the following silly script: files=$(git grep -l 'Copyright (C) [0-9]\{4\}\(-2013\)* Andre Noll') sed --in-place= -e 's/Copyright (C) \([0-9]\{4\}\)-2013 Andre Noll/Copyright (C) \1-2014 Andre Noll/1' $files sed --in-place= -e 's/Copyright (C) 2013 Andre Noll/Copyright (C) 2013-2014 Andre Noll/1' $files
Change copyright year to 2013. Better late than never.
Introduce xwritev(). For the sideband API we will need to write two buffers one after another. This patch adds the new public function xwritev() to fd.c which takes an arbitrary number of buffers and calls writev() to perform the write. With this function in place, xwrite() becomes a trivial wrapper for xwritev().