X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fextras%2Flibc.c;h=3389c57d07516824d043d0aa03b23c165d50b820;hb=9ff28119bcd7a610bd9859a8f49b4635443df784;hp=37d4e33fa3a08cfe6db7d4c2c9a6408a4b681866;hpb=7b3f9bc354eb7d7cb00c5a16a6eeef5d5658baee;p=vlc diff --git a/src/extras/libc.c b/src/extras/libc.c index 37d4e33fa3..3389c57d07 100644 --- a/src/extras/libc.c +++ b/src/extras/libc.c @@ -1,29 +1,23 @@ /***************************************************************************** * libc.c: Extra libc function for some systems. ***************************************************************************** - * Copyright (C) 2002-2006 the VideoLAN team - * $Id$ + * Copyright (C) 2002-2006 VLC authors and VideoLAN * - * Authors: Jon Lech Johansen - * Samuel Hocevar - * Gildas Bazin - * Derk-Jan Hartman - * Christophe Massiot - * Rémi Denis-Courmont + * Authors: Gildas Bazin * - * 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 + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 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. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" @@ -43,24 +37,15 @@ # include #endif -#ifdef HAVE_FORK -# include -# include -# include -# include -# include -# ifndef PF_LOCAL -# define PF_LOCAL PF_UNIX -# endif -#endif +#if defined(__OS2__) && defined(__INNOTEK_LIBC__) +# include -#if defined(WIN32) || defined(UNDER_CE) -# define WIN32_LEAN_AND_MEAN -# include +typedef struct os2_iconv_t +{ + UconvObject from; +} os2_iconv_t; #endif - - /***************************************************************************** * Local conversion routine from ISO_6937 to UTF-8 charset. Support for this * is still missing in libiconv, hence multiple operating systems lack it. @@ -350,7 +335,42 @@ vlc_iconv_t vlc_iconv_open( const char *tocode, const char *fromcode ) return (vlc_iconv_t)(-2); #endif #if defined(HAVE_ICONV) +# if defined(__OS2__) && defined(__INNOTEK_LIBC__) + char tocode_ucs2[] = "UCS-2LE"; + char fromcode_ucs2[] = "UCS-2LE"; + os2_iconv_t *p_os2_iconv; + + /* Workaround for UTF-16 because OS/2 supports UCS-2 only not UTF-16 */ + if( !strncmp( tocode, "UTF-16", 6 )) + { + strncpy( tocode_ucs2 + 5, tocode + 6, 2 ); + tocode = tocode_ucs2; + } + + if( !strncmp( fromcode, "UTF-16", 6 )) + { + strncpy( fromcode_ucs2 + 5, fromcode + 6, 2 ); + fromcode = fromcode_ucs2; + } + + p_os2_iconv = ( os2_iconv_t * )iconv_open( tocode, fromcode ); + + if( p_os2_iconv != ( iconv_t )(-1)) + { + /* Mimic a behavior of GNU libiconv */ + uconv_attribute_t attr; + + UniQueryUconvObject( p_os2_iconv->from, &attr, + sizeof( uconv_attribute_t ), + NULL, NULL, NULL ); + attr.converttype |= CVTTYPE_PATH; + UniSetUconvObject( p_os2_iconv->from, &attr ); + } + + return ( vlc_iconv_t )p_os2_iconv; +# else return iconv_open( tocode, fromcode ); +# endif #else return (vlc_iconv_t)(-1); #endif @@ -437,310 +457,3 @@ bool vlc_ureduce( unsigned *pi_dst_nom, unsigned *pi_dst_den, return b_exact; } - -#undef vlc_execve -/************************************************************************* - * vlc_execve: Execute an external program with a given environment, - * wait until it finishes and return its standard output - *************************************************************************/ -int vlc_execve( vlc_object_t *p_object, int i_argc, char *const *ppsz_argv, - char *const *ppsz_env, const char *psz_cwd, - const char *p_in, size_t i_in, - char **pp_data, size_t *pi_data ) -{ - (void)i_argc; // <-- hmph -#ifdef HAVE_FORK -# define BUFSIZE 1024 - int fds[2], i_status; - - if (socketpair (PF_LOCAL, SOCK_STREAM, 0, fds)) - return -1; - - pid_t pid = -1; - if ((fds[0] > 2) && (fds[1] > 2)) - pid = fork (); - - switch (pid) - { - case -1: - msg_Err (p_object, "unable to fork (%m)"); - close (fds[0]); - close (fds[1]); - return -1; - - case 0: - { - sigset_t set; - sigemptyset (&set); - pthread_sigmask (SIG_SETMASK, &set, NULL); - - /* NOTE: - * Like it or not, close can fail (and not only with EBADF) - */ - if ((dup2 (fds[1], 0) == 0) && (dup2 (fds[1], 1) == 1) - && ((psz_cwd == NULL) || (chdir (psz_cwd) == 0))) - execve (ppsz_argv[0], ppsz_argv, ppsz_env); - - _exit (EXIT_FAILURE); - } - } - - close (fds[1]); - - *pi_data = 0; - if (*pp_data) - free (*pp_data); - *pp_data = NULL; - - if (i_in == 0) - shutdown (fds[0], SHUT_WR); - - while (!p_object->b_die) - { - struct pollfd ufd[1]; - memset (ufd, 0, sizeof (ufd)); - ufd[0].fd = fds[0]; - ufd[0].events = POLLIN; - - if (i_in > 0) - ufd[0].events |= POLLOUT; - - if (poll (ufd, 1, 10) <= 0) - continue; - - if (ufd[0].revents & ~POLLOUT) - { - char *ptr = realloc (*pp_data, *pi_data + BUFSIZE + 1); - if (ptr == NULL) - break; /* safely abort */ - - *pp_data = ptr; - - ssize_t val = read (fds[0], ptr + *pi_data, BUFSIZE); - switch (val) - { - case -1: - case 0: - shutdown (fds[0], SHUT_RD); - break; - - default: - *pi_data += val; - } - } - - if (ufd[0].revents & POLLOUT) - { - ssize_t val = write (fds[0], p_in, i_in); - switch (val) - { - case -1: - case 0: - i_in = 0; - shutdown (fds[0], SHUT_WR); - break; - - default: - i_in -= val; - p_in += val; - } - } - } - - close (fds[0]); - - while (waitpid (pid, &i_status, 0) == -1); - - if (WIFEXITED (i_status)) - { - i_status = WEXITSTATUS (i_status); - if (i_status) - msg_Warn (p_object, "child %s (PID %d) exited with error code %d", - ppsz_argv[0], (int)pid, i_status); - } - else - if (WIFSIGNALED (i_status)) // <-- this should be redumdant a check - { - i_status = WTERMSIG (i_status); - msg_Warn (p_object, "child %s (PID %d) exited on signal %d (%s)", - ppsz_argv[0], (int)pid, i_status, strsignal (i_status)); - } - -#elif defined( WIN32 ) && !defined( UNDER_CE ) - SECURITY_ATTRIBUTES saAttr; - PROCESS_INFORMATION piProcInfo; - STARTUPINFO siStartInfo; - BOOL bFuncRetn = FALSE; - HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr; - DWORD i_status; - char *psz_cmd = NULL, *p_env = NULL, *p = NULL; - char *const *ppsz_parser; - int i_size; - - /* Set the bInheritHandle flag so pipe handles are inherited. */ - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = NULL; - - /* Create a pipe for the child process's STDOUT. */ - if ( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0 ) ) - { - msg_Err( p_object, "stdout pipe creation failed" ); - return -1; - } - - /* Ensure the read handle to the pipe for STDOUT is not inherited. */ - SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0 ); - - /* Create a pipe for the child process's STDIN. */ - if ( !CreatePipe( &hChildStdinRd, &hChildStdinWr, &saAttr, 0 ) ) - { - msg_Err( p_object, "stdin pipe creation failed" ); - return -1; - } - - /* Ensure the write handle to the pipe for STDIN is not inherited. */ - SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0 ); - - /* Set up members of the PROCESS_INFORMATION structure. */ - ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); - - /* Set up members of the STARTUPINFO structure. */ - ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); - siStartInfo.cb = sizeof(STARTUPINFO); - siStartInfo.hStdError = hChildStdoutWr; - siStartInfo.hStdOutput = hChildStdoutWr; - siStartInfo.hStdInput = hChildStdinRd; - siStartInfo.wShowWindow = SW_HIDE; - siStartInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - - /* Set up the command line. */ - psz_cmd = malloc(32768); - if( !psz_cmd ) - return -1; - psz_cmd[0] = '\0'; - i_size = 32768; - ppsz_parser = &ppsz_argv[0]; - while ( ppsz_parser[0] != NULL && i_size > 0 ) - { - /* Protect the last argument with quotes ; the other arguments - * are supposed to be already protected because they have been - * passed as a command-line option. */ - if ( ppsz_parser[1] == NULL ) - { - strncat( psz_cmd, "\"", i_size ); - i_size--; - } - strncat( psz_cmd, *ppsz_parser, i_size ); - i_size -= strlen( *ppsz_parser ); - if ( ppsz_parser[1] == NULL ) - { - strncat( psz_cmd, "\"", i_size ); - i_size--; - } - strncat( psz_cmd, " ", i_size ); - i_size--; - ppsz_parser++; - } - - /* Set up the environment. */ - p = p_env = malloc(32768); - if( !p ) - { - free( psz_cmd ); - return -1; - } - - i_size = 32768; - ppsz_parser = &ppsz_env[0]; - while ( *ppsz_parser != NULL && i_size > 0 ) - { - memcpy( p, *ppsz_parser, - __MIN((int)(strlen(*ppsz_parser) + 1), i_size) ); - p += strlen(*ppsz_parser) + 1; - i_size -= strlen(*ppsz_parser) + 1; - ppsz_parser++; - } - *p = '\0'; - - /* Create the child process. */ - bFuncRetn = CreateProcess( NULL, - psz_cmd, // command line - NULL, // process security attributes - NULL, // primary thread security attributes - TRUE, // handles are inherited - 0, // creation flags - p_env, - psz_cwd, - &siStartInfo, // STARTUPINFO pointer - &piProcInfo ); // receives PROCESS_INFORMATION - - free( psz_cmd ); - free( p_env ); - - if ( bFuncRetn == 0 ) - { - msg_Err( p_object, "child creation failed" ); - return -1; - } - - /* Read from a file and write its contents to a pipe. */ - while ( i_in > 0 && !p_object->b_die ) - { - DWORD i_written; - if ( !WriteFile( hChildStdinWr, p_in, i_in, &i_written, NULL ) ) - break; - i_in -= i_written; - p_in += i_written; - } - - /* Close the pipe handle so the child process stops reading. */ - CloseHandle(hChildStdinWr); - - /* Close the write end of the pipe before reading from the - * read end of the pipe. */ - CloseHandle(hChildStdoutWr); - - /* Read output from the child process. */ - *pi_data = 0; - if( *pp_data ) - free( pp_data ); - *pp_data = NULL; - *pp_data = malloc( 1025 ); /* +1 for \0 */ - - while ( !p_object->b_die ) - { - DWORD i_read; - if ( !ReadFile( hChildStdoutRd, &(*pp_data)[*pi_data], 1024, &i_read, - NULL ) - || i_read == 0 ) - break; - *pi_data += i_read; - *pp_data = xrealloc( *pp_data, *pi_data + 1025 ); - } - - while ( !p_object->b_die - && !GetExitCodeProcess( piProcInfo.hProcess, &i_status ) - && i_status != STILL_ACTIVE ) - msleep( 10000 ); - - CloseHandle(piProcInfo.hProcess); - CloseHandle(piProcInfo.hThread); - - if ( i_status ) - msg_Warn( p_object, - "child %s returned with error code %ld", - ppsz_argv[0], i_status ); - -#else - msg_Err( p_object, "vlc_execve called but no implementation is available" ); - return -1; - -#endif - - if (*pp_data == NULL) - return -1; - - (*pp_data)[*pi_data] = '\0'; - return 0; -}