lib

morphux C utility library
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/lib

m_util.c (4465B)


      1 /*********************************** LICENSE **********************************\
      2  *                            Copyright 2017 Morphux                            *
      3  *                                                                              *
      4  *        Licensed under the Apache License, Version 2.0 (the "License");       *
      5  *        you may not use this file except in compliance with the License.      *
      6  *                  You may obtain a copy of the License at                     *
      7  *                                                                              *
      8  *                 http://www.apache.org/licenses/LICENSE-2.0                   *
      9  *                                                                              *
     10  *      Unless required by applicable law or agreed to in writing, software     *
     11  *       distributed under the License is distributed on an "AS IS" BASIS,      *
     12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
     13  *        See the License for the specific language governing permissions and   *
     14  *                       limitations under the License.                         *
     15  \******************************************************************************/
     16 
     17 #include <m_util.h>
     18 #include <fts.h>
     19 
     20 static u8_t g_compile_flags = COMP_FLAGS_NONE;
     21 
     22 void set_execute_flags(u8_t flags) {
     23     g_compile_flags = flags;
     24 }
     25 
     26 bool recursive_delete(const char *dir) {
     27     FTS         *ftsp = NULL;
     28     FTSENT      *curr = NULL;
     29     const char  *files[] = { (char *)dir, NULL };
     30 
     31     ftsp = fts_open((char * const *)files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
     32     assert(ftsp != NULL);
     33 
     34     while ((curr = fts_read(ftsp))) {
     35         switch (curr->fts_info) {
     36 #ifndef COMPILE_WITH_TEST
     37             case FTS_NS:
     38             /* FALLTROUGH */
     39             case FTS_DNR:
     40             /* FALLTROUGH */
     41             case FTS_ERR:
     42                 goto error;
     43 
     44             case FTS_DC:
     45             /* FALLTROUGH */
     46             case FTS_DOT:
     47             /* FALLTROUGH */
     48             case FTS_NSOK:
     49                 break ;
     50 #endif /* COMPILE_WITH_TEST */
     51 
     52             case FTS_DP:
     53             /* FALLTROUGH */
     54             case FTS_F:
     55             /* FALLTROUGH */
     56             case FTS_SL:
     57             /* FALLTROUGH */
     58             case FTS_SLNONE:
     59             /* FALLTROUGH */
     60             case FTS_DEFAULT:
     61                 if (remove(curr->fts_accpath) < 0)
     62                     goto error;
     63                 break;
     64         }
     65     }
     66 
     67     fts_close(ftsp);
     68     return true;
     69 
     70 error:
     71     fts_close(ftsp);
     72     return false;
     73 }
     74 
     75 MPX_STATIC char **str_list_to_array(mlist_t *list) {
     76     char    **arr = NULL, *ptr = NULL;
     77     mlist_t *tmp;
     78     size_t  i = 0;
     79 
     80     arr = malloc(sizeof(char *) * (list_size(list) + 1));
     81     if (arr == NULL)
     82         return NULL;
     83 
     84     list_for_each(list, tmp, ptr) {
     85         arr[i] = strdup(ptr);
     86         arr[i + 1] = NULL;
     87         if (arr[i] == NULL)
     88             goto end;
     89         i++;
     90     }
     91 
     92     return arr;
     93 
     94 end:
     95     for (i = 0; arr[i] != NULL; i++)
     96         free(arr[i]);
     97     free(arr);
     98     return NULL;
     99 }
    100 
    101 int exec_line(const char *str) {
    102     mlist_t     *list = NULL;
    103     char        *cmd;
    104     size_t      j, i, len;
    105     int         ret;
    106 
    107     if (str == NULL)
    108         return 1;
    109 
    110     cmd = strdup(str);
    111     if (cmd == NULL)
    112         return 1;
    113 
    114     len = strlen(cmd);
    115     for (i = 0, j = 0; i < len; i++)
    116     {
    117         if (cmd[i] == ' ')
    118         {
    119             while (i < len && cmd[i] == ' ')
    120                 i++;
    121 
    122             i--;
    123             cmd[i] = '\0';
    124             list_add(list, cmd + j, i - j + 1);
    125             cmd[i] = ' ';
    126             j = i + 1;
    127         }
    128     }
    129     list_add(list, cmd + j, i - j + 1);
    130 
    131     ret = exec_list(list);
    132     list_free(list, NULL);
    133     free(cmd);
    134     return ret;
    135 }
    136 
    137 int exec_list(mlist_t *list) {
    138     char    **tab = NULL;
    139     int     pid, status = 1;
    140     int     fds[2];
    141 
    142     tab = str_list_to_array(list);
    143 
    144     if (tab == NULL)
    145         goto end;
    146 
    147     pipe(fds);
    148     if ((pid = fork()) == -1)
    149         goto end;
    150 
    151     if (pid == 0)
    152     {
    153         if (g_compile_flags & COMP_FLAGS_NONE)
    154         {
    155             dup2(fds[1], 1);
    156             dup2(fds[1], 2);
    157         }
    158         close(fds[1]);
    159 
    160         execvp(tab[0], tab);
    161         exit(1);
    162     }
    163     else
    164     {
    165         waitpid(pid, &status, 0);
    166         close(fds[1]);
    167     }
    168 
    169 end:
    170     if (tab != NULL)
    171     {
    172         for (size_t i = 0; tab[i]; i++)
    173             free(tab[i]);
    174         free(tab);
    175     }
    176     return status;
    177 }